167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===-- CodeEmitter.h - CodeEmitter Class -----------------------*- C++ -*-===// 267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// 367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// The LLVM Compiler Infrastructure 467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// 567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// This file is distributed under the University of Illinois Open Source 667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// License. See external/llvm/LICENSE.TXT for details. 767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// 867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===----------------------------------------------------------------------===// 967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// 1067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// This file defines the CodeEmitter class. 1167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// 1267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===----------------------------------------------------------------------===// 1367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 1467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#ifndef BCC_CODEEMITTER_H 1567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#define BCC_CODEEMITTER_H 1667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 1767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <bcc/bcc.h> 18bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines#include <bcc/bcc_assert.h> 1967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <bcc/bcc_cache.h> 208d3b5e184b776dbf0b4af8a1c95f027d8653ca66Logan Chien#include "ExecutionEngine/bcc_internal.h" 2167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 2267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "Config.h" 2367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 2467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/DenseMap.h" 2567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/SmallVector.h" 2667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/StringRef.h" 27bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines#include "llvm/CodeGen/MachineConstantPool.h" 2867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/CodeGen/MachineRelocation.h" 2967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/CodeGen/JITCodeEmitter.h" 3067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/Support/ValueHandle.h" 3167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 3267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <map> 3367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <vector> 3467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <set> 3567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 3667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <stdint.h> 3767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 3867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liaonamespace llvm { 3967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class Constant; 4067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class GenericValue; 4167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class GlobalVariable; 4267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class GlobalValue; 4367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class Function; 4467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class MachineBasicBlock; 4567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class MachineFunction; 4667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class MachineJumpTableInfo; 4767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class MachineModuleInfo; 4867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class MCSymbol; 4967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class Target; 5067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class TargetData; 5167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class TargetJITInfo; 5267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class TargetMachine; 5367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class Type; 5467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao} 5567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 5667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liaonamespace bcc { 5767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class CodeMemoryManager; 5867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class ScriptCompiled; 5967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 6067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao class CodeEmitter : public llvm::JITCodeEmitter { 6167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao private: 6267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao typedef llvm::DenseMap<const llvm::GlobalValue *, void *> 6367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao GlobalAddressMapTy; 6467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 6567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao typedef llvm::DenseMap<const llvm::Function *, void*> 6667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao FunctionToLazyStubMapTy; 6767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 6867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void *> 6967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao GlobalToIndirectSymMapTy; 7067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 7167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao public: 7267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator; 7367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 7467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 7567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao private: 7667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao ScriptCompiled *mpResult; 7767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 7867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao CodeMemoryManager *mpMemMgr; 7967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 80cfd23fde40cf0cb600dd8a09563ff8fe3e5f9c0aShih-wei Liao llvm::TargetMachine *mpTargetMachine; 81cfd23fde40cf0cb600dd8a09563ff8fe3e5f9c0aShih-wei Liao 8267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // The JITInfo for the target we are compiling to 8367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao const llvm::Target *mpTarget; 8467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 8567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::TargetJITInfo *mpTJI; 8667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 8767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao const llvm::TargetData *mpTD; 8867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 8967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 9067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao FuncInfo *mpCurEmitFunction; 9167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 9267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao GlobalAddressMapTy mGlobalAddressMap; 9367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 9467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This vector is a mapping from MBB ID's to their address. It is filled in 9567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // by the StartMachineBasicBlock callback and queried by the 9667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // getMachineBasicBlockAddress callback. 9767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::vector<uintptr_t> mMBBLocations; 9867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 9967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // The constant pool for the current function. 10067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::MachineConstantPool *mpConstantPool; 10167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 10267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // A pointer to the first entry in the constant pool. 10367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *mpConstantPoolBase; 10467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 10567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Addresses of individual constant pool entries. 10667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses; 10767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 10867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // The jump tables for the current function. 10967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::MachineJumpTableInfo *mpJumpTable; 11067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 11167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // A pointer to the first entry in the jump table. 11267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *mpJumpTableBase; 11367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 11467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // When outputting a function stub in the context of some other function, we 11567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // save BufferBegin/BufferEnd/CurBufferPtr here. 11667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr; 11767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 11867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // These are the relocations that the function needs, as emitted. 11967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::vector<llvm::MachineRelocation> mRelocations; 12067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 12167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#if 0 12267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::vector<oBCCRelocEntry> mCachingRelocations; 12367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif 12467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 12567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This vector is a mapping from Label ID's to their address. 12667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations; 12767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 12867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Machine module info for exception informations 12967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::MachineModuleInfo *mpMMI; 13067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 13167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 13267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao FunctionToLazyStubMapTy mFunctionToLazyStubMap; 13367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 13467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::set<const llvm::Function*> PendingFunctions; 13567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 13667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao GlobalToIndirectSymMapTy GlobalToIndirectSymMap; 13767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 13867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::map<void*, void*> ExternalFnToStubMap; 13967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 14067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao public: 14167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Resolver to undefined symbol in CodeEmitter 14267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao BCCSymbolLookupFn mpSymbolLookupFn; 14367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *mpSymbolLookupContext; 14467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 14567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Will take the ownership of @MemMgr 14667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao explicit CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr); 14767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 14867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual ~CodeEmitter(); 14967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 15067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao global_addresses_const_iterator global_address_begin() const { 15167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mGlobalAddressMap.begin(); 15267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 15367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 15467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao global_addresses_const_iterator global_address_end() const { 15567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mGlobalAddressMap.end(); 15667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 15767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 15867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#if 0 15967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao std::vector<oBCCRelocEntry> const &getCachingRelocations() const { 16067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mCachingRelocations; 16167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 16267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif 16367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 16467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) { 16567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao mpSymbolLookupFn = pFn; 16667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao mpSymbolLookupContext = pContext; 16767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 16867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 16967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void setTargetMachine(llvm::TargetMachine &TM); 17067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 17167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This callback is invoked when the specified function is about to be code 17267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // generated. This initializes the BufferBegin/End/Ptr fields. 17367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void startFunction(llvm::MachineFunction &F); 17467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 17567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This callback is invoked when the specified function has finished code 17667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // generation. If a buffer overflow has occurred, this method returns true 17767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // (the callee is required to try again). 17867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual bool finishFunction(llvm::MachineFunction &F); 17967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 18067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Allocates and fills storage for an indirect GlobalValue, and returns the 18167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // address. 18267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void *allocIndirectGV(const llvm::GlobalValue *GV, 18367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao const uint8_t *Buffer, size_t Size, 18467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao unsigned Alignment); 18567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 18667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Emits a label 18767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void emitLabel(llvm::MCSymbol *Label) { 18867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao mLabelLocations[Label] = getCurrentPCValue(); 18967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 19067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 19167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Allocate memory for a global. Unlike allocateSpace, this method does not 19267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // allocate memory in the current output buffer, because a global may live 19367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // longer than the current function. 19467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); 19567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 19667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This should be called by the target when a new basic block is about to be 19767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // emitted. This way the MCE knows where the start of the block is, and can 19867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // implement getMachineBasicBlockAddress. 19967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB); 20067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 20167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Whenever a relocatable address is needed, it should be noted with this 20267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // interface. 20367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void addRelocation(const llvm::MachineRelocation &MR) { 20467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao mRelocations.push_back(MR); 20567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 20667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 20767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return the address of the @Index entry in the constant pool that was 20867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // last emitted with the emitConstantPool method. 20967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { 210bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines bccAssert(Index < mpConstantPool->getConstants().size() && 211bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines "Invalid constant pool index!"); 21267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mConstPoolAddresses[Index]; 21367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 21467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 21567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return the address of the jump table with index @Index in the function 21667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // that last called initJumpTableInfo. 21767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const; 21867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 21967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return the address of the specified MachineBasicBlock, only usable after 22067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // the label for the MBB has been emitted. 22167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual uintptr_t getMachineBasicBlockAddress( 22267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao llvm::MachineBasicBlock *MBB) const; 22367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 22467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return the address of the specified LabelID, only usable after the 22567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // LabelID has been emitted. 22667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual uintptr_t getLabelAddress(llvm::MCSymbol *Label) const { 227bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines bccAssert(mLabelLocations.count(Label) && "Label not emitted!"); 22867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mLabelLocations.find(Label)->second; 22967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 23067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 23167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Specifies the MachineModuleInfo object. This is used for exception 23267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // handling purposes. 23367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao virtual void setModuleInfo(llvm::MachineModuleInfo *Info) { 23467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao mpMMI = Info; 23567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 23667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 23767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void releaseUnnecessary(); 23867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 23967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void reset(); 24067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 24167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao private: 24267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize, 24367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao unsigned Alignment); 24467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 24567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void startGVStub(void *Buffer, unsigned StubSize); 24667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 24767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void finishGVStub(); 24867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 24967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Replace an existing mapping for GV with a new address. This updates both 25067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // maps as required. If Addr is null, the entry for the global is removed 25167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // from the mappings. 25267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr); 25367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 25467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Tell the execution engine that the specified global is at the specified 25567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // location. This is used internally as functions are JIT'd and as global 25667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // variables are laid out in memory. 25767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) { 25867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *&CurVal = mGlobalAddressMap[GV]; 25967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); 26067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao CurVal = Addr; 26167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 26267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 26367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This returns the address of the specified global value if it is has 26467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // already been codegen'd, otherwise it returns null. 26567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) { 26667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV); 26767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return ((I != mGlobalAddressMap.end()) ? I->second : NULL); 26867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 26967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 27067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP); 27167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 27267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This function converts a Constant* into a GenericValue. The interesting 27367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // part is if C is a ConstantExpr. 27467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result); 27567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 27667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Stores the data in @Val of type @Ty at address @Addr. 27767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr, 278d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien llvm::Type *Ty); 27967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 28067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Recursive function to apply a @Constant value into the specified memory 28167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // location @Addr. 28267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void InitializeConstantToMemory(const llvm::Constant *C, void *Addr); 28367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 28467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void emitConstantPool(llvm::MachineConstantPool *MCP); 28567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 28667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI); 28767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 28867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI); 28967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 29067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToGlobal(llvm::GlobalValue *V, 29167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *Reference, 29267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao bool MayNeedFarStub); 29367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 29467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // If the specified function has been code-gen'd, return a pointer to the 29567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // function. If not, compile it, or use a stub to implement lazy compilation 29667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // if available. 29767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToFunctionOrStub(llvm::Function *F); 29867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 29967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetLazyFunctionStubIfAvailable(llvm::Function *F) { 30067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao return mFunctionToLazyStubMap.lookup(F); 30167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao } 30267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 30367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetLazyFunctionStub(llvm::Function *F); 30467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 30567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void updateFunctionStub(const llvm::Function *F); 30667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 30767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure); 30867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 30967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToNamedSymbol(const std::string &Name, 31067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao bool AbortOnFailure); 31167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 31267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return the address of the specified global variable, possibly emitting it 31367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // to memory if needed. This is used by the Emitter. 314d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien void *GetOrEmitGlobalVariable(llvm::GlobalVariable *GV); 31567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 31667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This method abstracts memory allocation of global variable so that the 31767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // JIT can allocate thread local variables depending on the target. 318d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien void *GetMemoryForGV(llvm::GlobalVariable *GV); 31967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 320d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien void EmitGlobalVariable(llvm::GlobalVariable *GV); 32167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 32267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference); 32367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 32467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // This is the equivalent of FunctionToLazyStubMap for external functions. 32567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // 32667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // TODO(llvm.org): Of course, external functions don't need a lazy stub. 32767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // It's actually here to make it more likely that far calls 32867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // succeed, but no single stub can guarantee that. I'll 32967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // remove this in a subsequent checkin when I actually fix 33067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // far calls. 33167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 33267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao // Return a stub for the function at the specified address. 33367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao void *GetExternalFunctionStub(void *FnAddr); 33467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 33567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao }; 33667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 33767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao} // namespace bcc 33867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao 33967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif // BCC_CODEEMITTER_H 340