1009b1c42SEd Schouten //===-- ExecutionEngine.cpp - Common Implementation shared by EEs ---------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file defines the common interface used by the various execution engine
10009b1c42SEd Schouten // subclasses.
11009b1c42SEd Schouten //
12cfca06d7SDimitry Andric // FIXME: This file needs to be updated to support scalable vectors
13cfca06d7SDimitry Andric //
14009b1c42SEd Schouten //===----------------------------------------------------------------------===//
15009b1c42SEd Schouten
1659850d08SRoman Divacky #include "llvm/ExecutionEngine/ExecutionEngine.h"
175a5ac124SDimitry Andric #include "llvm/ADT/STLExtras.h"
18cf099d11SDimitry Andric #include "llvm/ADT/SmallString.h"
1959850d08SRoman Divacky #include "llvm/ADT/Statistic.h"
204a16efa3SDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h"
2167c32a98SDimitry Andric #include "llvm/ExecutionEngine/JITEventListener.h"
22b915e9e0SDimitry Andric #include "llvm/ExecutionEngine/ObjectCache.h"
235a5ac124SDimitry Andric #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
244a16efa3SDimitry Andric #include "llvm/IR/Constants.h"
254a16efa3SDimitry Andric #include "llvm/IR/DataLayout.h"
264a16efa3SDimitry Andric #include "llvm/IR/DerivedTypes.h"
275a5ac124SDimitry Andric #include "llvm/IR/Mangler.h"
284a16efa3SDimitry Andric #include "llvm/IR/Module.h"
294a16efa3SDimitry Andric #include "llvm/IR/Operator.h"
305ca98fd9SDimitry Andric #include "llvm/IR/ValueHandle.h"
31c0981da4SDimitry Andric #include "llvm/MC/TargetRegistry.h"
3267c32a98SDimitry Andric #include "llvm/Object/Archive.h"
335ca98fd9SDimitry Andric #include "llvm/Object/ObjectFile.h"
34009b1c42SEd Schouten #include "llvm/Support/Debug.h"
354a16efa3SDimitry Andric #include "llvm/Support/DynamicLibrary.h"
3659850d08SRoman Divacky #include "llvm/Support/ErrorHandling.h"
3759850d08SRoman Divacky #include "llvm/Support/raw_ostream.h"
3856fe8f14SDimitry Andric #include "llvm/Target/TargetMachine.h"
397fa27ce4SDimitry Andric #include "llvm/TargetParser/Host.h"
40009b1c42SEd Schouten #include <cmath>
41009b1c42SEd Schouten #include <cstring>
421d5ae102SDimitry Andric #include <mutex>
43009b1c42SEd Schouten using namespace llvm;
44009b1c42SEd Schouten
455ca98fd9SDimitry Andric #define DEBUG_TYPE "jit"
465ca98fd9SDimitry Andric
47009b1c42SEd Schouten STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
48009b1c42SEd Schouten STATISTIC(NumGlobals , "Number of global vars initialized");
49009b1c42SEd Schouten
50cf099d11SDimitry Andric ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
5167c32a98SDimitry Andric std::unique_ptr<Module> M, std::string *ErrorStr,
525a5ac124SDimitry Andric std::shared_ptr<MCJITMemoryManager> MemMgr,
53eb11fae6SDimitry Andric std::shared_ptr<LegacyJITSymbolResolver> Resolver,
5467c32a98SDimitry Andric std::unique_ptr<TargetMachine> TM) = nullptr;
555a5ac124SDimitry Andric
5667c32a98SDimitry Andric ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
575ca98fd9SDimitry Andric std::string *ErrorStr) =nullptr;
58009b1c42SEd Schouten
anchor()5967c32a98SDimitry Andric void JITEventListener::anchor() {}
6067c32a98SDimitry Andric
anchor()61b915e9e0SDimitry Andric void ObjectCache::anchor() {}
62b915e9e0SDimitry Andric
Init(std::unique_ptr<Module> M)63dd58ef01SDimitry Andric void ExecutionEngine::Init(std::unique_ptr<Module> M) {
6436bf506aSRoman Divacky CompilingLazily = false;
65009b1c42SEd Schouten GVCompilationDisabled = false;
66009b1c42SEd Schouten SymbolSearchingDisabled = false;
675ca98fd9SDimitry Andric
685ca98fd9SDimitry Andric // IR module verification is enabled by default in debug builds, and disabled
695ca98fd9SDimitry Andric // by default in release builds.
705ca98fd9SDimitry Andric #ifndef NDEBUG
715ca98fd9SDimitry Andric VerifyModules = true;
725ca98fd9SDimitry Andric #else
735ca98fd9SDimitry Andric VerifyModules = false;
745ca98fd9SDimitry Andric #endif
755ca98fd9SDimitry Andric
766fe5c7aaSRoman Divacky assert(M && "Module is null?");
7767c32a98SDimitry Andric Modules.push_back(std::move(M));
78009b1c42SEd Schouten }
79009b1c42SEd Schouten
ExecutionEngine(std::unique_ptr<Module> M)80dd58ef01SDimitry Andric ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
81dd58ef01SDimitry Andric : DL(M->getDataLayout()), LazyFunctionCreator(nullptr) {
82dd58ef01SDimitry Andric Init(std::move(M));
83dd58ef01SDimitry Andric }
84dd58ef01SDimitry Andric
ExecutionEngine(DataLayout DL,std::unique_ptr<Module> M)85dd58ef01SDimitry Andric ExecutionEngine::ExecutionEngine(DataLayout DL, std::unique_ptr<Module> M)
86dd58ef01SDimitry Andric : DL(std::move(DL)), LazyFunctionCreator(nullptr) {
87dd58ef01SDimitry Andric Init(std::move(M));
88dd58ef01SDimitry Andric }
89dd58ef01SDimitry Andric
~ExecutionEngine()90009b1c42SEd Schouten ExecutionEngine::~ExecutionEngine() {
91009b1c42SEd Schouten clearAllGlobalMappings();
92009b1c42SEd Schouten }
93009b1c42SEd Schouten
94104bd817SRoman Divacky namespace {
95eb11fae6SDimitry Andric /// Helper class which uses a value handler to automatically deletes the
96cf099d11SDimitry Andric /// memory block when the GlobalVariable is destroyed.
97dd58ef01SDimitry Andric class GVMemoryBlock final : public CallbackVH {
GVMemoryBlock(const GlobalVariable * GV)98104bd817SRoman Divacky GVMemoryBlock(const GlobalVariable *GV)
99104bd817SRoman Divacky : CallbackVH(const_cast<GlobalVariable*>(GV)) {}
100104bd817SRoman Divacky
101104bd817SRoman Divacky public:
102eb11fae6SDimitry Andric /// Returns the address the GlobalVariable should be written into. The
103cf099d11SDimitry Andric /// GVMemoryBlock object prefixes that.
Create(const GlobalVariable * GV,const DataLayout & TD)104522600a2SDimitry Andric static char *Create(const GlobalVariable *GV, const DataLayout& TD) {
10501095a5dSDimitry Andric Type *ElTy = GV->getValueType();
106104bd817SRoman Divacky size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy);
107104bd817SRoman Divacky void *RawMemory = ::operator new(
108cfca06d7SDimitry Andric alignTo(sizeof(GVMemoryBlock), TD.getPreferredAlign(GV)) + GVSize);
109104bd817SRoman Divacky new(RawMemory) GVMemoryBlock(GV);
110104bd817SRoman Divacky return static_cast<char*>(RawMemory) + sizeof(GVMemoryBlock);
111104bd817SRoman Divacky }
112104bd817SRoman Divacky
deleted()1135ca98fd9SDimitry Andric void deleted() override {
114104bd817SRoman Divacky // We allocated with operator new and with some extra memory hanging off the
115104bd817SRoman Divacky // end, so don't just delete this. I'm not sure if this is actually
116104bd817SRoman Divacky // required.
117104bd817SRoman Divacky this->~GVMemoryBlock();
118104bd817SRoman Divacky ::operator delete(this);
119104bd817SRoman Divacky }
120104bd817SRoman Divacky };
121104bd817SRoman Divacky } // anonymous namespace
122104bd817SRoman Divacky
getMemoryForGV(const GlobalVariable * GV)123104bd817SRoman Divacky char *ExecutionEngine::getMemoryForGV(const GlobalVariable *GV) {
124dd58ef01SDimitry Andric return GVMemoryBlock::Create(GV, getDataLayout());
125009b1c42SEd Schouten }
126009b1c42SEd Schouten
addObjectFile(std::unique_ptr<object::ObjectFile> O)1275ca98fd9SDimitry Andric void ExecutionEngine::addObjectFile(std::unique_ptr<object::ObjectFile> O) {
1285ca98fd9SDimitry Andric llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");
1295ca98fd9SDimitry Andric }
1305ca98fd9SDimitry Andric
13167c32a98SDimitry Andric void
addObjectFile(object::OwningBinary<object::ObjectFile> O)13267c32a98SDimitry Andric ExecutionEngine::addObjectFile(object::OwningBinary<object::ObjectFile> O) {
13367c32a98SDimitry Andric llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");
13467c32a98SDimitry Andric }
13567c32a98SDimitry Andric
addArchive(object::OwningBinary<object::Archive> A)13667c32a98SDimitry Andric void ExecutionEngine::addArchive(object::OwningBinary<object::Archive> A) {
13767c32a98SDimitry Andric llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive.");
13867c32a98SDimitry Andric }
13967c32a98SDimitry Andric
removeModule(Module * M)1406fe5c7aaSRoman Divacky bool ExecutionEngine::removeModule(Module *M) {
14167c32a98SDimitry Andric for (auto I = Modules.begin(), E = Modules.end(); I != E; ++I) {
14267c32a98SDimitry Andric Module *Found = I->get();
1436fe5c7aaSRoman Divacky if (Found == M) {
14467c32a98SDimitry Andric I->release();
145009b1c42SEd Schouten Modules.erase(I);
1466fe5c7aaSRoman Divacky clearGlobalMappingsFromModule(M);
1476fe5c7aaSRoman Divacky return true;
148009b1c42SEd Schouten }
149009b1c42SEd Schouten }
1506fe5c7aaSRoman Divacky return false;
151009b1c42SEd Schouten }
152009b1c42SEd Schouten
FindFunctionNamed(StringRef FnName)153b915e9e0SDimitry Andric Function *ExecutionEngine::FindFunctionNamed(StringRef FnName) {
154ac9a064cSDimitry Andric for (const auto &M : Modules) {
155ac9a064cSDimitry Andric Function *F = M->getFunction(FnName);
1565a5ac124SDimitry Andric if (F && !F->isDeclaration())
157009b1c42SEd Schouten return F;
158009b1c42SEd Schouten }
1595ca98fd9SDimitry Andric return nullptr;
160009b1c42SEd Schouten }
161009b1c42SEd Schouten
FindGlobalVariableNamed(StringRef Name,bool AllowInternal)162b915e9e0SDimitry Andric GlobalVariable *ExecutionEngine::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) {
163ac9a064cSDimitry Andric for (const auto &M : Modules) {
164ac9a064cSDimitry Andric GlobalVariable *GV = M->getGlobalVariable(Name, AllowInternal);
1653a0822f0SDimitry Andric if (GV && !GV->isDeclaration())
1663a0822f0SDimitry Andric return GV;
1673a0822f0SDimitry Andric }
1683a0822f0SDimitry Andric return nullptr;
1693a0822f0SDimitry Andric }
170009b1c42SEd Schouten
RemoveMapping(StringRef Name)1715a5ac124SDimitry Andric uint64_t ExecutionEngineState::RemoveMapping(StringRef Name) {
1725a5ac124SDimitry Andric GlobalAddressMapTy::iterator I = GlobalAddressMap.find(Name);
1735a5ac124SDimitry Andric uint64_t OldVal;
174cf099d11SDimitry Andric
175cf099d11SDimitry Andric // FIXME: This is silly, we shouldn't end up with a mapping -> 0 in the
176cf099d11SDimitry Andric // GlobalAddressMap.
17759850d08SRoman Divacky if (I == GlobalAddressMap.end())
1785a5ac124SDimitry Andric OldVal = 0;
17959850d08SRoman Divacky else {
1805a5ac124SDimitry Andric GlobalAddressReverseMap.erase(I->second);
18159850d08SRoman Divacky OldVal = I->second;
18259850d08SRoman Divacky GlobalAddressMap.erase(I);
18359850d08SRoman Divacky }
18459850d08SRoman Divacky
18559850d08SRoman Divacky return OldVal;
18659850d08SRoman Divacky }
18759850d08SRoman Divacky
getMangledName(const GlobalValue * GV)1885a5ac124SDimitry Andric std::string ExecutionEngine::getMangledName(const GlobalValue *GV) {
18969156b4cSDimitry Andric assert(GV->hasName() && "Global must have name.");
19069156b4cSDimitry Andric
1911d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
1925a5ac124SDimitry Andric SmallString<128> FullName;
19369156b4cSDimitry Andric
19469156b4cSDimitry Andric const DataLayout &DL =
195ac9a064cSDimitry Andric GV->getDataLayout().isDefault()
196dd58ef01SDimitry Andric ? getDataLayout()
197ac9a064cSDimitry Andric : GV->getDataLayout();
19869156b4cSDimitry Andric
19969156b4cSDimitry Andric Mangler::getNameWithPrefix(FullName, GV->getName(), DL);
2004df029ccSDimitry Andric return std::string(FullName);
2015a5ac124SDimitry Andric }
2025a5ac124SDimitry Andric
addGlobalMapping(const GlobalValue * GV,void * Addr)203009b1c42SEd Schouten void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
2041d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2055a5ac124SDimitry Andric addGlobalMapping(getMangledName(GV), (uint64_t) Addr);
2065a5ac124SDimitry Andric }
207009b1c42SEd Schouten
addGlobalMapping(StringRef Name,uint64_t Addr)2085a5ac124SDimitry Andric void ExecutionEngine::addGlobalMapping(StringRef Name, uint64_t Addr) {
2091d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2105a5ac124SDimitry Andric
2115a5ac124SDimitry Andric assert(!Name.empty() && "Empty GlobalMapping symbol name!");
2125a5ac124SDimitry Andric
213eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "JIT: Map \'" << Name << "\' to [" << Addr << "]\n";);
2145a5ac124SDimitry Andric uint64_t &CurVal = EEState.getGlobalAddressMap()[Name];
2155ca98fd9SDimitry Andric assert((!CurVal || !Addr) && "GlobalMapping already established!");
216009b1c42SEd Schouten CurVal = Addr;
217009b1c42SEd Schouten
218cf099d11SDimitry Andric // If we are using the reverse mapping, add it too.
2195ca98fd9SDimitry Andric if (!EEState.getGlobalAddressReverseMap().empty()) {
2205a5ac124SDimitry Andric std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];
2215a5ac124SDimitry Andric assert((!V.empty() || !Name.empty()) &&
2225a5ac124SDimitry Andric "GlobalMapping already established!");
223cfca06d7SDimitry Andric V = std::string(Name);
224009b1c42SEd Schouten }
225009b1c42SEd Schouten }
226009b1c42SEd Schouten
clearAllGlobalMappings()227009b1c42SEd Schouten void ExecutionEngine::clearAllGlobalMappings() {
2281d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
229009b1c42SEd Schouten
2305ca98fd9SDimitry Andric EEState.getGlobalAddressMap().clear();
2315ca98fd9SDimitry Andric EEState.getGlobalAddressReverseMap().clear();
232009b1c42SEd Schouten }
233009b1c42SEd Schouten
clearGlobalMappingsFromModule(Module * M)234009b1c42SEd Schouten void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
2351d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
236009b1c42SEd Schouten
23701095a5dSDimitry Andric for (GlobalObject &GO : M->global_objects())
23801095a5dSDimitry Andric EEState.RemoveMapping(getMangledName(&GO));
239009b1c42SEd Schouten }
240009b1c42SEd Schouten
updateGlobalMapping(const GlobalValue * GV,void * Addr)2415a5ac124SDimitry Andric uint64_t ExecutionEngine::updateGlobalMapping(const GlobalValue *GV,
2425a5ac124SDimitry Andric void *Addr) {
2431d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2445a5ac124SDimitry Andric return updateGlobalMapping(getMangledName(GV), (uint64_t) Addr);
2455a5ac124SDimitry Andric }
2465a5ac124SDimitry Andric
updateGlobalMapping(StringRef Name,uint64_t Addr)2475a5ac124SDimitry Andric uint64_t ExecutionEngine::updateGlobalMapping(StringRef Name, uint64_t Addr) {
2481d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
249009b1c42SEd Schouten
25036bf506aSRoman Divacky ExecutionEngineState::GlobalAddressMapTy &Map =
2515ca98fd9SDimitry Andric EEState.getGlobalAddressMap();
252009b1c42SEd Schouten
253009b1c42SEd Schouten // Deleting from the mapping?
2545ca98fd9SDimitry Andric if (!Addr)
2555a5ac124SDimitry Andric return EEState.RemoveMapping(Name);
256009b1c42SEd Schouten
2575a5ac124SDimitry Andric uint64_t &CurVal = Map[Name];
2585a5ac124SDimitry Andric uint64_t OldVal = CurVal;
259009b1c42SEd Schouten
2605ca98fd9SDimitry Andric if (CurVal && !EEState.getGlobalAddressReverseMap().empty())
2615ca98fd9SDimitry Andric EEState.getGlobalAddressReverseMap().erase(CurVal);
262009b1c42SEd Schouten CurVal = Addr;
263009b1c42SEd Schouten
264cf099d11SDimitry Andric // If we are using the reverse mapping, add it too.
2655ca98fd9SDimitry Andric if (!EEState.getGlobalAddressReverseMap().empty()) {
2665a5ac124SDimitry Andric std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];
2675a5ac124SDimitry Andric assert((!V.empty() || !Name.empty()) &&
2685a5ac124SDimitry Andric "GlobalMapping already established!");
269cfca06d7SDimitry Andric V = std::string(Name);
270009b1c42SEd Schouten }
271009b1c42SEd Schouten return OldVal;
272009b1c42SEd Schouten }
273009b1c42SEd Schouten
getAddressToGlobalIfAvailable(StringRef S)2745a5ac124SDimitry Andric uint64_t ExecutionEngine::getAddressToGlobalIfAvailable(StringRef S) {
2751d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2765a5ac124SDimitry Andric uint64_t Address = 0;
2775a5ac124SDimitry Andric ExecutionEngineState::GlobalAddressMapTy::iterator I =
2785a5ac124SDimitry Andric EEState.getGlobalAddressMap().find(S);
2795a5ac124SDimitry Andric if (I != EEState.getGlobalAddressMap().end())
2805a5ac124SDimitry Andric Address = I->second;
2815a5ac124SDimitry Andric return Address;
2825a5ac124SDimitry Andric }
2835a5ac124SDimitry Andric
2845a5ac124SDimitry Andric
getPointerToGlobalIfAvailable(StringRef S)2855a5ac124SDimitry Andric void *ExecutionEngine::getPointerToGlobalIfAvailable(StringRef S) {
2861d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2875a5ac124SDimitry Andric if (void* Address = (void *) getAddressToGlobalIfAvailable(S))
2885a5ac124SDimitry Andric return Address;
2895a5ac124SDimitry Andric return nullptr;
2905a5ac124SDimitry Andric }
2915a5ac124SDimitry Andric
getPointerToGlobalIfAvailable(const GlobalValue * GV)292009b1c42SEd Schouten void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
2931d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
2945a5ac124SDimitry Andric return getPointerToGlobalIfAvailable(getMangledName(GV));
295009b1c42SEd Schouten }
296009b1c42SEd Schouten
getGlobalValueAtAddress(void * Addr)297009b1c42SEd Schouten const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
2981d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
299009b1c42SEd Schouten
300009b1c42SEd Schouten // If we haven't computed the reverse mapping yet, do so first.
3015ca98fd9SDimitry Andric if (EEState.getGlobalAddressReverseMap().empty()) {
30236bf506aSRoman Divacky for (ExecutionEngineState::GlobalAddressMapTy::iterator
3035ca98fd9SDimitry Andric I = EEState.getGlobalAddressMap().begin(),
3045a5ac124SDimitry Andric E = EEState.getGlobalAddressMap().end(); I != E; ++I) {
3055a5ac124SDimitry Andric StringRef Name = I->first();
3065a5ac124SDimitry Andric uint64_t Addr = I->second;
307cfca06d7SDimitry Andric EEState.getGlobalAddressReverseMap().insert(
308cfca06d7SDimitry Andric std::make_pair(Addr, std::string(Name)));
3095a5ac124SDimitry Andric }
310009b1c42SEd Schouten }
311009b1c42SEd Schouten
3125a5ac124SDimitry Andric std::map<uint64_t, std::string>::iterator I =
3135a5ac124SDimitry Andric EEState.getGlobalAddressReverseMap().find((uint64_t) Addr);
3145a5ac124SDimitry Andric
3155a5ac124SDimitry Andric if (I != EEState.getGlobalAddressReverseMap().end()) {
3165a5ac124SDimitry Andric StringRef Name = I->second;
317ac9a064cSDimitry Andric for (const auto &M : Modules)
318ac9a064cSDimitry Andric if (GlobalValue *GV = M->getNamedValue(Name))
3195a5ac124SDimitry Andric return GV;
3205a5ac124SDimitry Andric }
3215a5ac124SDimitry Andric return nullptr;
322009b1c42SEd Schouten }
323009b1c42SEd Schouten
324104bd817SRoman Divacky namespace {
325104bd817SRoman Divacky class ArgvArray {
32667c32a98SDimitry Andric std::unique_ptr<char[]> Array;
32767c32a98SDimitry Andric std::vector<std::unique_ptr<char[]>> Values;
328104bd817SRoman Divacky public:
329104bd817SRoman Divacky /// Turn a vector of strings into a nice argv style array of pointers to null
330104bd817SRoman Divacky /// terminated strings.
331104bd817SRoman Divacky void *reset(LLVMContext &C, ExecutionEngine *EE,
332104bd817SRoman Divacky const std::vector<std::string> &InputArgv);
333104bd817SRoman Divacky };
334104bd817SRoman Divacky } // anonymous namespace
reset(LLVMContext & C,ExecutionEngine * EE,const std::vector<std::string> & InputArgv)335104bd817SRoman Divacky void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE,
336009b1c42SEd Schouten const std::vector<std::string> &InputArgv) {
33767c32a98SDimitry Andric Values.clear(); // Free the old contents.
33867c32a98SDimitry Andric Values.reserve(InputArgv.size());
339dd58ef01SDimitry Andric unsigned PtrSize = EE->getDataLayout().getPointerSize();
3401d5ae102SDimitry Andric Array = std::make_unique<char[]>((InputArgv.size()+1)*PtrSize);
341009b1c42SEd Schouten
342eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "JIT: ARGV = " << (void *)Array.get() << "\n");
343b1c73532SDimitry Andric Type *SBytePtr = PointerType::getUnqual(C);
344009b1c42SEd Schouten
345009b1c42SEd Schouten for (unsigned i = 0; i != InputArgv.size(); ++i) {
346009b1c42SEd Schouten unsigned Size = InputArgv[i].size()+1;
3471d5ae102SDimitry Andric auto Dest = std::make_unique<char[]>(Size);
348eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "JIT: ARGV[" << i << "] = " << (void *)Dest.get()
349eb11fae6SDimitry Andric << "\n");
350009b1c42SEd Schouten
35167c32a98SDimitry Andric std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest.get());
352009b1c42SEd Schouten Dest[Size-1] = 0;
353009b1c42SEd Schouten
354104bd817SRoman Divacky // Endian safe: Array[i] = (PointerTy)Dest;
35567c32a98SDimitry Andric EE->StoreValueToMemory(PTOGV(Dest.get()),
35667c32a98SDimitry Andric (GenericValue*)(&Array[i*PtrSize]), SBytePtr);
35767c32a98SDimitry Andric Values.push_back(std::move(Dest));
358009b1c42SEd Schouten }
359009b1c42SEd Schouten
360009b1c42SEd Schouten // Null terminate it
3615ca98fd9SDimitry Andric EE->StoreValueToMemory(PTOGV(nullptr),
36267c32a98SDimitry Andric (GenericValue*)(&Array[InputArgv.size()*PtrSize]),
363009b1c42SEd Schouten SBytePtr);
36467c32a98SDimitry Andric return Array.get();
365009b1c42SEd Schouten }
366009b1c42SEd Schouten
runStaticConstructorsDestructors(Module & module,bool isDtors)36767c32a98SDimitry Andric void ExecutionEngine::runStaticConstructorsDestructors(Module &module,
36859850d08SRoman Divacky bool isDtors) {
369b915e9e0SDimitry Andric StringRef Name(isDtors ? "llvm.global_dtors" : "llvm.global_ctors");
37067c32a98SDimitry Andric GlobalVariable *GV = module.getNamedGlobal(Name);
371009b1c42SEd Schouten
372009b1c42SEd Schouten // If this global has internal linkage, or if it has a use, then it must be
373009b1c42SEd Schouten // an old-style (llvmgcc3) static ctor with __main linked in and in use. If
374009b1c42SEd Schouten // this is the case, don't execute any of the global ctors, __main will do
375009b1c42SEd Schouten // it.
376009b1c42SEd Schouten if (!GV || GV->isDeclaration() || GV->hasLocalLinkage()) return;
377009b1c42SEd Schouten
3786b943ff3SDimitry Andric // Should be an array of '{ i32, void ()* }' structs. The first value is
379009b1c42SEd Schouten // the init priority, which we ignore.
38063faed5bSDimitry Andric ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
3815ca98fd9SDimitry Andric if (!InitList)
3826b943ff3SDimitry Andric return;
383cf099d11SDimitry Andric for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
38463faed5bSDimitry Andric ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i));
3855ca98fd9SDimitry Andric if (!CS) continue;
386009b1c42SEd Schouten
387009b1c42SEd Schouten Constant *FP = CS->getOperand(1);
388009b1c42SEd Schouten if (FP->isNullValue())
3894df029ccSDimitry Andric continue; // Found a sentinel value, ignore.
390009b1c42SEd Schouten
391cf099d11SDimitry Andric // Strip off constant expression casts.
392009b1c42SEd Schouten if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
393009b1c42SEd Schouten if (CE->isCast())
394009b1c42SEd Schouten FP = CE->getOperand(0);
395cf099d11SDimitry Andric
396009b1c42SEd Schouten // Execute the ctor/dtor function!
397cf099d11SDimitry Andric if (Function *F = dyn_cast<Function>(FP))
398e3b55780SDimitry Andric runFunction(F, std::nullopt);
399cf099d11SDimitry Andric
400cf099d11SDimitry Andric // FIXME: It is marginally lame that we just do nothing here if we see an
401cf099d11SDimitry Andric // entry we don't recognize. It might not be unreasonable for the verifier
402cf099d11SDimitry Andric // to not even allow this and just assert here.
403009b1c42SEd Schouten }
404009b1c42SEd Schouten }
405009b1c42SEd Schouten
runStaticConstructorsDestructors(bool isDtors)406009b1c42SEd Schouten void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
407009b1c42SEd Schouten // Execute global ctors/dtors for each module in the program.
40867c32a98SDimitry Andric for (std::unique_ptr<Module> &M : Modules)
40967c32a98SDimitry Andric runStaticConstructorsDestructors(*M, isDtors);
410009b1c42SEd Schouten }
411009b1c42SEd Schouten
412009b1c42SEd Schouten #ifndef NDEBUG
413009b1c42SEd Schouten /// isTargetNullPtr - Return whether the target pointer stored at Loc is null.
isTargetNullPtr(ExecutionEngine * EE,void * Loc)414009b1c42SEd Schouten static bool isTargetNullPtr(ExecutionEngine *EE, void *Loc) {
415dd58ef01SDimitry Andric unsigned PtrSize = EE->getDataLayout().getPointerSize();
416009b1c42SEd Schouten for (unsigned i = 0; i < PtrSize; ++i)
417009b1c42SEd Schouten if (*(i + (uint8_t*)Loc))
418009b1c42SEd Schouten return false;
419009b1c42SEd Schouten return true;
420009b1c42SEd Schouten }
421009b1c42SEd Schouten #endif
422009b1c42SEd Schouten
runFunctionAsMain(Function * Fn,const std::vector<std::string> & argv,const char * const * envp)423009b1c42SEd Schouten int ExecutionEngine::runFunctionAsMain(Function *Fn,
424009b1c42SEd Schouten const std::vector<std::string> &argv,
425009b1c42SEd Schouten const char * const * envp) {
426009b1c42SEd Schouten std::vector<GenericValue> GVArgs;
427009b1c42SEd Schouten GenericValue GVArgc;
428009b1c42SEd Schouten GVArgc.IntVal = APInt(32, argv.size());
429009b1c42SEd Schouten
430009b1c42SEd Schouten // Check main() type
431009b1c42SEd Schouten unsigned NumArgs = Fn->getFunctionType()->getNumParams();
43230815c53SDimitry Andric FunctionType *FTy = Fn->getFunctionType();
433b1c73532SDimitry Andric Type *PPInt8Ty = PointerType::get(Fn->getContext(), 0);
434cf099d11SDimitry Andric
435cf099d11SDimitry Andric // Check the argument types.
436cf099d11SDimitry Andric if (NumArgs > 3)
437d7f7719eSRoman Divacky report_fatal_error("Invalid number of arguments of main() supplied");
438cf099d11SDimitry Andric if (NumArgs >= 3 && FTy->getParamType(2) != PPInt8Ty)
439cf099d11SDimitry Andric report_fatal_error("Invalid type for third argument of main() supplied");
440cf099d11SDimitry Andric if (NumArgs >= 2 && FTy->getParamType(1) != PPInt8Ty)
441cf099d11SDimitry Andric report_fatal_error("Invalid type for second argument of main() supplied");
442cf099d11SDimitry Andric if (NumArgs >= 1 && !FTy->getParamType(0)->isIntegerTy(32))
443cf099d11SDimitry Andric report_fatal_error("Invalid type for first argument of main() supplied");
444cf099d11SDimitry Andric if (!FTy->getReturnType()->isIntegerTy() &&
445cf099d11SDimitry Andric !FTy->getReturnType()->isVoidTy())
446cf099d11SDimitry Andric report_fatal_error("Invalid return type of main() supplied");
447009b1c42SEd Schouten
448104bd817SRoman Divacky ArgvArray CArgv;
449104bd817SRoman Divacky ArgvArray CEnv;
450009b1c42SEd Schouten if (NumArgs) {
451009b1c42SEd Schouten GVArgs.push_back(GVArgc); // Arg #0 = argc.
452009b1c42SEd Schouten if (NumArgs > 1) {
45359850d08SRoman Divacky // Arg #1 = argv.
454104bd817SRoman Divacky GVArgs.push_back(PTOGV(CArgv.reset(Fn->getContext(), this, argv)));
455009b1c42SEd Schouten assert(!isTargetNullPtr(this, GVTOP(GVArgs[1])) &&
456009b1c42SEd Schouten "argv[0] was null after CreateArgv");
457009b1c42SEd Schouten if (NumArgs > 2) {
458009b1c42SEd Schouten std::vector<std::string> EnvVars;
459009b1c42SEd Schouten for (unsigned i = 0; envp[i]; ++i)
46085d8b2bbSDimitry Andric EnvVars.emplace_back(envp[i]);
46159850d08SRoman Divacky // Arg #2 = envp.
462104bd817SRoman Divacky GVArgs.push_back(PTOGV(CEnv.reset(Fn->getContext(), this, EnvVars)));
463009b1c42SEd Schouten }
464009b1c42SEd Schouten }
465009b1c42SEd Schouten }
466cf099d11SDimitry Andric
467009b1c42SEd Schouten return runFunction(Fn, GVArgs).IntVal.getZExtValue();
468009b1c42SEd Schouten }
469009b1c42SEd Schouten
EngineBuilder()4705a5ac124SDimitry Andric EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {}
4715a5ac124SDimitry Andric
EngineBuilder(std::unique_ptr<Module> M)47267c32a98SDimitry Andric EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
4735a5ac124SDimitry Andric : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),
474b1c73532SDimitry Andric OptLevel(CodeGenOptLevel::Default), MemMgr(nullptr), Resolver(nullptr) {
4755ca98fd9SDimitry Andric // IR module verification is enabled by default in debug builds, and disabled
4765ca98fd9SDimitry Andric // by default in release builds.
4775ca98fd9SDimitry Andric #ifndef NDEBUG
4785ca98fd9SDimitry Andric VerifyModules = true;
4795ca98fd9SDimitry Andric #else
4805ca98fd9SDimitry Andric VerifyModules = false;
4815ca98fd9SDimitry Andric #endif
4825ca98fd9SDimitry Andric }
4835ca98fd9SDimitry Andric
4845a5ac124SDimitry Andric EngineBuilder::~EngineBuilder() = default;
4855a5ac124SDimitry Andric
setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager> mcjmm)4865a5ac124SDimitry Andric EngineBuilder &EngineBuilder::setMCJITMemoryManager(
4875a5ac124SDimitry Andric std::unique_ptr<RTDyldMemoryManager> mcjmm) {
4885a5ac124SDimitry Andric auto SharedMM = std::shared_ptr<RTDyldMemoryManager>(std::move(mcjmm));
4895a5ac124SDimitry Andric MemMgr = SharedMM;
4905a5ac124SDimitry Andric Resolver = SharedMM;
4915a5ac124SDimitry Andric return *this;
4925a5ac124SDimitry Andric }
4935a5ac124SDimitry Andric
4945a5ac124SDimitry Andric EngineBuilder&
setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM)4955a5ac124SDimitry Andric EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) {
4965a5ac124SDimitry Andric MemMgr = std::shared_ptr<MCJITMemoryManager>(std::move(MM));
4975a5ac124SDimitry Andric return *this;
4985a5ac124SDimitry Andric }
4995a5ac124SDimitry Andric
5005a5ac124SDimitry Andric EngineBuilder &
setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR)501eb11fae6SDimitry Andric EngineBuilder::setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR) {
502eb11fae6SDimitry Andric Resolver = std::shared_ptr<LegacyJITSymbolResolver>(std::move(SR));
5035a5ac124SDimitry Andric return *this;
5045a5ac124SDimitry Andric }
5055a5ac124SDimitry Andric
create(TargetMachine * TM)50663faed5bSDimitry Andric ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
5075ca98fd9SDimitry Andric std::unique_ptr<TargetMachine> TheTM(TM); // Take ownership.
50863faed5bSDimitry Andric
509009b1c42SEd Schouten // Make sure we can resolve symbols in the program as well. The zero arg
510009b1c42SEd Schouten // to the function tells DynamicLibrary to load the program, not a library.
5115ca98fd9SDimitry Andric if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr))
5125ca98fd9SDimitry Andric return nullptr;
513009b1c42SEd Schouten
51459850d08SRoman Divacky // If the user specified a memory manager but didn't specify which engine to
51559850d08SRoman Divacky // create, we assume they only want the JIT, and we fail if they only want
51659850d08SRoman Divacky // the interpreter.
5175a5ac124SDimitry Andric if (MemMgr) {
51859850d08SRoman Divacky if (WhichEngine & EngineKind::JIT)
51959850d08SRoman Divacky WhichEngine = EngineKind::JIT;
52059850d08SRoman Divacky else {
52159850d08SRoman Divacky if (ErrorStr)
52259850d08SRoman Divacky *ErrorStr = "Cannot create an interpreter with a memory manager.";
5235ca98fd9SDimitry Andric return nullptr;
52459850d08SRoman Divacky }
525009b1c42SEd Schouten }
526009b1c42SEd Schouten
52759850d08SRoman Divacky // Unless the interpreter was explicitly selected or the JIT is not linked,
52859850d08SRoman Divacky // try making a JIT.
52963faed5bSDimitry Andric if ((WhichEngine & EngineKind::JIT) && TheTM) {
53063faed5bSDimitry Andric if (!TM->getTarget().hasJIT()) {
53163faed5bSDimitry Andric errs() << "WARNING: This target JIT is not designed for the host"
53263faed5bSDimitry Andric << " you are running. If bad things happen, please choose"
53363faed5bSDimitry Andric << " a different -march switch.\n";
53463faed5bSDimitry Andric }
53563faed5bSDimitry Andric
5365ca98fd9SDimitry Andric ExecutionEngine *EE = nullptr;
537b60736ecSDimitry Andric if (ExecutionEngine::MCJITCtor)
5385a5ac124SDimitry Andric EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MemMgr),
5395a5ac124SDimitry Andric std::move(Resolver), std::move(TheTM));
5405a5ac124SDimitry Andric
5415ca98fd9SDimitry Andric if (EE) {
5425ca98fd9SDimitry Andric EE->setVerifyModules(VerifyModules);
5435ca98fd9SDimitry Andric return EE;
54459850d08SRoman Divacky }
54559850d08SRoman Divacky }
54659850d08SRoman Divacky
54759850d08SRoman Divacky // If we can't make a JIT and we didn't request one specifically, try making
54859850d08SRoman Divacky // an interpreter instead.
54959850d08SRoman Divacky if (WhichEngine & EngineKind::Interpreter) {
55059850d08SRoman Divacky if (ExecutionEngine::InterpCtor)
55167c32a98SDimitry Andric return ExecutionEngine::InterpCtor(std::move(M), ErrorStr);
55259850d08SRoman Divacky if (ErrorStr)
55359850d08SRoman Divacky *ErrorStr = "Interpreter has not been linked in.";
5545ca98fd9SDimitry Andric return nullptr;
55559850d08SRoman Divacky }
55659850d08SRoman Divacky
55767c32a98SDimitry Andric if ((WhichEngine & EngineKind::JIT) && !ExecutionEngine::MCJITCtor) {
55859850d08SRoman Divacky if (ErrorStr)
55959850d08SRoman Divacky *ErrorStr = "JIT has not been linked in.";
56059850d08SRoman Divacky }
561cf099d11SDimitry Andric
5625ca98fd9SDimitry Andric return nullptr;
563009b1c42SEd Schouten }
564009b1c42SEd Schouten
getPointerToGlobal(const GlobalValue * GV)565009b1c42SEd Schouten void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
566009b1c42SEd Schouten if (Function *F = const_cast<Function*>(dyn_cast<Function>(GV)))
567009b1c42SEd Schouten return getPointerToFunction(F);
568009b1c42SEd Schouten
5691d5ae102SDimitry Andric std::lock_guard<sys::Mutex> locked(lock);
5705a5ac124SDimitry Andric if (void* P = getPointerToGlobalIfAvailable(GV))
571cf099d11SDimitry Andric return P;
572009b1c42SEd Schouten
573009b1c42SEd Schouten // Global variable might have been added since interpreter started.
574009b1c42SEd Schouten if (GlobalVariable *GVar =
575009b1c42SEd Schouten const_cast<GlobalVariable *>(dyn_cast<GlobalVariable>(GV)))
576cfca06d7SDimitry Andric emitGlobalVariable(GVar);
577009b1c42SEd Schouten else
57859850d08SRoman Divacky llvm_unreachable("Global hasn't had an address allocated yet!");
579cf099d11SDimitry Andric
5805a5ac124SDimitry Andric return getPointerToGlobalIfAvailable(GV);
581009b1c42SEd Schouten }
582009b1c42SEd Schouten
583eb11fae6SDimitry Andric /// Converts a Constant* into a GenericValue, including handling of
584cf099d11SDimitry Andric /// ConstantExpr values.
getConstantValue(const Constant * C)585009b1c42SEd Schouten GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
586009b1c42SEd Schouten // If its undefined, return the garbage.
587829000e0SRoman Divacky if (isa<UndefValue>(C)) {
588829000e0SRoman Divacky GenericValue Result;
589829000e0SRoman Divacky switch (C->getType()->getTypeID()) {
5904a16efa3SDimitry Andric default:
5914a16efa3SDimitry Andric break;
592829000e0SRoman Divacky case Type::IntegerTyID:
593829000e0SRoman Divacky case Type::X86_FP80TyID:
594829000e0SRoman Divacky case Type::FP128TyID:
595829000e0SRoman Divacky case Type::PPC_FP128TyID:
596829000e0SRoman Divacky // Although the value is undefined, we still have to construct an APInt
597829000e0SRoman Divacky // with the correct bit width.
598829000e0SRoman Divacky Result.IntVal = APInt(C->getType()->getPrimitiveSizeInBits(), 0);
599829000e0SRoman Divacky break;
600f8af5cf6SDimitry Andric case Type::StructTyID: {
601f8af5cf6SDimitry Andric // if the whole struct is 'undef' just reserve memory for the value.
602f8af5cf6SDimitry Andric if(StructType *STy = dyn_cast<StructType>(C->getType())) {
603f8af5cf6SDimitry Andric unsigned int elemNum = STy->getNumElements();
604f8af5cf6SDimitry Andric Result.AggregateVal.resize(elemNum);
605f8af5cf6SDimitry Andric for (unsigned int i = 0; i < elemNum; ++i) {
606f8af5cf6SDimitry Andric Type *ElemTy = STy->getElementType(i);
607f8af5cf6SDimitry Andric if (ElemTy->isIntegerTy())
608f8af5cf6SDimitry Andric Result.AggregateVal[i].IntVal =
609f8af5cf6SDimitry Andric APInt(ElemTy->getPrimitiveSizeInBits(), 0);
610f8af5cf6SDimitry Andric else if (ElemTy->isAggregateType()) {
611f8af5cf6SDimitry Andric const Constant *ElemUndef = UndefValue::get(ElemTy);
612f8af5cf6SDimitry Andric Result.AggregateVal[i] = getConstantValue(ElemUndef);
613f8af5cf6SDimitry Andric }
614f8af5cf6SDimitry Andric }
615f8af5cf6SDimitry Andric }
616f8af5cf6SDimitry Andric }
617f8af5cf6SDimitry Andric break;
618cfca06d7SDimitry Andric case Type::ScalableVectorTyID:
619cfca06d7SDimitry Andric report_fatal_error(
620cfca06d7SDimitry Andric "Scalable vector support not yet implemented in ExecutionEngine");
621b1c73532SDimitry Andric case Type::ArrayTyID: {
622b1c73532SDimitry Andric auto *ArrTy = cast<ArrayType>(C->getType());
623b1c73532SDimitry Andric Type *ElemTy = ArrTy->getElementType();
624b1c73532SDimitry Andric unsigned int elemNum = ArrTy->getNumElements();
625b1c73532SDimitry Andric Result.AggregateVal.resize(elemNum);
626b1c73532SDimitry Andric if (ElemTy->isIntegerTy())
627b1c73532SDimitry Andric for (unsigned int i = 0; i < elemNum; ++i)
628b1c73532SDimitry Andric Result.AggregateVal[i].IntVal =
629b1c73532SDimitry Andric APInt(ElemTy->getPrimitiveSizeInBits(), 0);
630b1c73532SDimitry Andric break;
631b1c73532SDimitry Andric }
632b1c73532SDimitry Andric case Type::FixedVectorTyID: {
6334a16efa3SDimitry Andric // if the whole vector is 'undef' just reserve memory for the value.
634cfca06d7SDimitry Andric auto *VTy = cast<FixedVectorType>(C->getType());
635dd58ef01SDimitry Andric Type *ElemTy = VTy->getElementType();
6364a16efa3SDimitry Andric unsigned int elemNum = VTy->getNumElements();
6374a16efa3SDimitry Andric Result.AggregateVal.resize(elemNum);
6384a16efa3SDimitry Andric if (ElemTy->isIntegerTy())
6394a16efa3SDimitry Andric for (unsigned int i = 0; i < elemNum; ++i)
6404a16efa3SDimitry Andric Result.AggregateVal[i].IntVal =
6414a16efa3SDimitry Andric APInt(ElemTy->getPrimitiveSizeInBits(), 0);
642829000e0SRoman Divacky break;
643829000e0SRoman Divacky }
644b1c73532SDimitry Andric }
645829000e0SRoman Divacky return Result;
646829000e0SRoman Divacky }
647009b1c42SEd Schouten
648cf099d11SDimitry Andric // Otherwise, if the value is a ConstantExpr...
649009b1c42SEd Schouten if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
650009b1c42SEd Schouten Constant *Op0 = CE->getOperand(0);
651009b1c42SEd Schouten switch (CE->getOpcode()) {
652009b1c42SEd Schouten case Instruction::GetElementPtr: {
653009b1c42SEd Schouten // Compute the index
654009b1c42SEd Schouten GenericValue Result = getConstantValue(Op0);
655dd58ef01SDimitry Andric APInt Offset(DL.getPointerSizeInBits(), 0);
656dd58ef01SDimitry Andric cast<GEPOperator>(CE)->accumulateConstantOffset(DL, Offset);
657009b1c42SEd Schouten
658009b1c42SEd Schouten char* tmp = (char*) Result.PointerVal;
6594a16efa3SDimitry Andric Result = PTOGV(tmp + Offset.getSExtValue());
660009b1c42SEd Schouten return Result;
661009b1c42SEd Schouten }
662009b1c42SEd Schouten case Instruction::Trunc: {
663009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
664009b1c42SEd Schouten uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
665009b1c42SEd Schouten GV.IntVal = GV.IntVal.trunc(BitWidth);
666009b1c42SEd Schouten return GV;
667009b1c42SEd Schouten }
668009b1c42SEd Schouten case Instruction::ZExt: {
669009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
670009b1c42SEd Schouten uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
671009b1c42SEd Schouten GV.IntVal = GV.IntVal.zext(BitWidth);
672009b1c42SEd Schouten return GV;
673009b1c42SEd Schouten }
674009b1c42SEd Schouten case Instruction::SExt: {
675009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
676009b1c42SEd Schouten uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
677009b1c42SEd Schouten GV.IntVal = GV.IntVal.sext(BitWidth);
678009b1c42SEd Schouten return GV;
679009b1c42SEd Schouten }
680009b1c42SEd Schouten case Instruction::FPTrunc: {
681009b1c42SEd Schouten // FIXME long double
682009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
683009b1c42SEd Schouten GV.FloatVal = float(GV.DoubleVal);
684009b1c42SEd Schouten return GV;
685009b1c42SEd Schouten }
686009b1c42SEd Schouten case Instruction::FPExt:{
687009b1c42SEd Schouten // FIXME long double
688009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
689009b1c42SEd Schouten GV.DoubleVal = double(GV.FloatVal);
690009b1c42SEd Schouten return GV;
691009b1c42SEd Schouten }
692009b1c42SEd Schouten case Instruction::UIToFP: {
693009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
69459850d08SRoman Divacky if (CE->getType()->isFloatTy())
695009b1c42SEd Schouten GV.FloatVal = float(GV.IntVal.roundToDouble());
69659850d08SRoman Divacky else if (CE->getType()->isDoubleTy())
697009b1c42SEd Schouten GV.DoubleVal = GV.IntVal.roundToDouble();
69859850d08SRoman Divacky else if (CE->getType()->isX86_FP80Ty()) {
699b915e9e0SDimitry Andric APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended());
700009b1c42SEd Schouten (void)apf.convertFromAPInt(GV.IntVal,
701009b1c42SEd Schouten false,
702009b1c42SEd Schouten APFloat::rmNearestTiesToEven);
703009b1c42SEd Schouten GV.IntVal = apf.bitcastToAPInt();
704009b1c42SEd Schouten }
705009b1c42SEd Schouten return GV;
706009b1c42SEd Schouten }
707009b1c42SEd Schouten case Instruction::SIToFP: {
708009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
70959850d08SRoman Divacky if (CE->getType()->isFloatTy())
710009b1c42SEd Schouten GV.FloatVal = float(GV.IntVal.signedRoundToDouble());
71159850d08SRoman Divacky else if (CE->getType()->isDoubleTy())
712009b1c42SEd Schouten GV.DoubleVal = GV.IntVal.signedRoundToDouble();
71359850d08SRoman Divacky else if (CE->getType()->isX86_FP80Ty()) {
714b915e9e0SDimitry Andric APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended());
715009b1c42SEd Schouten (void)apf.convertFromAPInt(GV.IntVal,
716009b1c42SEd Schouten true,
717009b1c42SEd Schouten APFloat::rmNearestTiesToEven);
718009b1c42SEd Schouten GV.IntVal = apf.bitcastToAPInt();
719009b1c42SEd Schouten }
720009b1c42SEd Schouten return GV;
721009b1c42SEd Schouten }
722009b1c42SEd Schouten case Instruction::FPToUI: // double->APInt conversion handles sign
723009b1c42SEd Schouten case Instruction::FPToSI: {
724009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
725009b1c42SEd Schouten uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
72659850d08SRoman Divacky if (Op0->getType()->isFloatTy())
727009b1c42SEd Schouten GV.IntVal = APIntOps::RoundFloatToAPInt(GV.FloatVal, BitWidth);
72859850d08SRoman Divacky else if (Op0->getType()->isDoubleTy())
729009b1c42SEd Schouten GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth);
73059850d08SRoman Divacky else if (Op0->getType()->isX86_FP80Ty()) {
731b915e9e0SDimitry Andric APFloat apf = APFloat(APFloat::x87DoubleExtended(), GV.IntVal);
732009b1c42SEd Schouten uint64_t v;
733009b1c42SEd Schouten bool ignored;
734e3b55780SDimitry Andric (void)apf.convertToInteger(MutableArrayRef(v), BitWidth,
735009b1c42SEd Schouten CE->getOpcode()==Instruction::FPToSI,
736009b1c42SEd Schouten APFloat::rmTowardZero, &ignored);
737009b1c42SEd Schouten GV.IntVal = v; // endian?
738009b1c42SEd Schouten }
739009b1c42SEd Schouten return GV;
740009b1c42SEd Schouten }
741009b1c42SEd Schouten case Instruction::PtrToInt: {
742009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
743dd58ef01SDimitry Andric uint32_t PtrWidth = DL.getTypeSizeInBits(Op0->getType());
744522600a2SDimitry Andric assert(PtrWidth <= 64 && "Bad pointer width");
745009b1c42SEd Schouten GV.IntVal = APInt(PtrWidth, uintptr_t(GV.PointerVal));
746dd58ef01SDimitry Andric uint32_t IntWidth = DL.getTypeSizeInBits(CE->getType());
747522600a2SDimitry Andric GV.IntVal = GV.IntVal.zextOrTrunc(IntWidth);
748009b1c42SEd Schouten return GV;
749009b1c42SEd Schouten }
750009b1c42SEd Schouten case Instruction::IntToPtr: {
751009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
752dd58ef01SDimitry Andric uint32_t PtrWidth = DL.getTypeSizeInBits(CE->getType());
753009b1c42SEd Schouten GV.IntVal = GV.IntVal.zextOrTrunc(PtrWidth);
754009b1c42SEd Schouten assert(GV.IntVal.getBitWidth() <= 64 && "Bad pointer width");
755009b1c42SEd Schouten GV.PointerVal = PointerTy(uintptr_t(GV.IntVal.getZExtValue()));
756009b1c42SEd Schouten return GV;
757009b1c42SEd Schouten }
758009b1c42SEd Schouten case Instruction::BitCast: {
759009b1c42SEd Schouten GenericValue GV = getConstantValue(Op0);
76030815c53SDimitry Andric Type* DestTy = CE->getType();
761009b1c42SEd Schouten switch (Op0->getType()->getTypeID()) {
76259850d08SRoman Divacky default: llvm_unreachable("Invalid bitcast operand");
763009b1c42SEd Schouten case Type::IntegerTyID:
7646fe5c7aaSRoman Divacky assert(DestTy->isFloatingPointTy() && "invalid bitcast");
76559850d08SRoman Divacky if (DestTy->isFloatTy())
766009b1c42SEd Schouten GV.FloatVal = GV.IntVal.bitsToFloat();
76759850d08SRoman Divacky else if (DestTy->isDoubleTy())
768009b1c42SEd Schouten GV.DoubleVal = GV.IntVal.bitsToDouble();
769009b1c42SEd Schouten break;
770009b1c42SEd Schouten case Type::FloatTyID:
7716fe5c7aaSRoman Divacky assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
772cf099d11SDimitry Andric GV.IntVal = APInt::floatToBits(GV.FloatVal);
773009b1c42SEd Schouten break;
774009b1c42SEd Schouten case Type::DoubleTyID:
7756fe5c7aaSRoman Divacky assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
776cf099d11SDimitry Andric GV.IntVal = APInt::doubleToBits(GV.DoubleVal);
777009b1c42SEd Schouten break;
778009b1c42SEd Schouten case Type::PointerTyID:
77967a71b31SRoman Divacky assert(DestTy->isPointerTy() && "Invalid bitcast");
780009b1c42SEd Schouten break; // getConstantValue(Op0) above already converted it
781009b1c42SEd Schouten }
782009b1c42SEd Schouten return GV;
783009b1c42SEd Schouten }
784009b1c42SEd Schouten case Instruction::Add:
785f4fe016fSEd Schouten case Instruction::FAdd:
786009b1c42SEd Schouten case Instruction::Sub:
787f4fe016fSEd Schouten case Instruction::FSub:
788009b1c42SEd Schouten case Instruction::Mul:
789f4fe016fSEd Schouten case Instruction::FMul:
790009b1c42SEd Schouten case Instruction::UDiv:
791009b1c42SEd Schouten case Instruction::SDiv:
792009b1c42SEd Schouten case Instruction::URem:
793009b1c42SEd Schouten case Instruction::SRem:
794009b1c42SEd Schouten case Instruction::And:
795009b1c42SEd Schouten case Instruction::Or:
796009b1c42SEd Schouten case Instruction::Xor: {
797009b1c42SEd Schouten GenericValue LHS = getConstantValue(Op0);
798009b1c42SEd Schouten GenericValue RHS = getConstantValue(CE->getOperand(1));
799009b1c42SEd Schouten GenericValue GV;
800009b1c42SEd Schouten switch (CE->getOperand(0)->getType()->getTypeID()) {
80159850d08SRoman Divacky default: llvm_unreachable("Bad add type!");
802009b1c42SEd Schouten case Type::IntegerTyID:
803009b1c42SEd Schouten switch (CE->getOpcode()) {
80459850d08SRoman Divacky default: llvm_unreachable("Invalid integer opcode");
805009b1c42SEd Schouten case Instruction::Add: GV.IntVal = LHS.IntVal + RHS.IntVal; break;
806009b1c42SEd Schouten case Instruction::Sub: GV.IntVal = LHS.IntVal - RHS.IntVal; break;
807009b1c42SEd Schouten case Instruction::Mul: GV.IntVal = LHS.IntVal * RHS.IntVal; break;
808009b1c42SEd Schouten case Instruction::UDiv:GV.IntVal = LHS.IntVal.udiv(RHS.IntVal); break;
809009b1c42SEd Schouten case Instruction::SDiv:GV.IntVal = LHS.IntVal.sdiv(RHS.IntVal); break;
810009b1c42SEd Schouten case Instruction::URem:GV.IntVal = LHS.IntVal.urem(RHS.IntVal); break;
811009b1c42SEd Schouten case Instruction::SRem:GV.IntVal = LHS.IntVal.srem(RHS.IntVal); break;
812009b1c42SEd Schouten case Instruction::And: GV.IntVal = LHS.IntVal & RHS.IntVal; break;
813009b1c42SEd Schouten case Instruction::Or: GV.IntVal = LHS.IntVal | RHS.IntVal; break;
814009b1c42SEd Schouten case Instruction::Xor: GV.IntVal = LHS.IntVal ^ RHS.IntVal; break;
815009b1c42SEd Schouten }
816009b1c42SEd Schouten break;
817009b1c42SEd Schouten case Type::FloatTyID:
818009b1c42SEd Schouten switch (CE->getOpcode()) {
81959850d08SRoman Divacky default: llvm_unreachable("Invalid float opcode");
820f4fe016fSEd Schouten case Instruction::FAdd:
821009b1c42SEd Schouten GV.FloatVal = LHS.FloatVal + RHS.FloatVal; break;
822f4fe016fSEd Schouten case Instruction::FSub:
823009b1c42SEd Schouten GV.FloatVal = LHS.FloatVal - RHS.FloatVal; break;
824f4fe016fSEd Schouten case Instruction::FMul:
825009b1c42SEd Schouten GV.FloatVal = LHS.FloatVal * RHS.FloatVal; break;
826009b1c42SEd Schouten case Instruction::FDiv:
827009b1c42SEd Schouten GV.FloatVal = LHS.FloatVal / RHS.FloatVal; break;
828009b1c42SEd Schouten case Instruction::FRem:
829abdf259dSRoman Divacky GV.FloatVal = std::fmod(LHS.FloatVal,RHS.FloatVal); break;
830009b1c42SEd Schouten }
831009b1c42SEd Schouten break;
832009b1c42SEd Schouten case Type::DoubleTyID:
833009b1c42SEd Schouten switch (CE->getOpcode()) {
83459850d08SRoman Divacky default: llvm_unreachable("Invalid double opcode");
835f4fe016fSEd Schouten case Instruction::FAdd:
836009b1c42SEd Schouten GV.DoubleVal = LHS.DoubleVal + RHS.DoubleVal; break;
837f4fe016fSEd Schouten case Instruction::FSub:
838009b1c42SEd Schouten GV.DoubleVal = LHS.DoubleVal - RHS.DoubleVal; break;
839f4fe016fSEd Schouten case Instruction::FMul:
840009b1c42SEd Schouten GV.DoubleVal = LHS.DoubleVal * RHS.DoubleVal; break;
841009b1c42SEd Schouten case Instruction::FDiv:
842009b1c42SEd Schouten GV.DoubleVal = LHS.DoubleVal / RHS.DoubleVal; break;
843009b1c42SEd Schouten case Instruction::FRem:
844abdf259dSRoman Divacky GV.DoubleVal = std::fmod(LHS.DoubleVal,RHS.DoubleVal); break;
845009b1c42SEd Schouten }
846009b1c42SEd Schouten break;
847009b1c42SEd Schouten case Type::X86_FP80TyID:
848009b1c42SEd Schouten case Type::PPC_FP128TyID:
849009b1c42SEd Schouten case Type::FP128TyID: {
8504a16efa3SDimitry Andric const fltSemantics &Sem = CE->getOperand(0)->getType()->getFltSemantics();
8514a16efa3SDimitry Andric APFloat apfLHS = APFloat(Sem, LHS.IntVal);
852009b1c42SEd Schouten switch (CE->getOpcode()) {
853cf099d11SDimitry Andric default: llvm_unreachable("Invalid long double opcode");
854f4fe016fSEd Schouten case Instruction::FAdd:
8554a16efa3SDimitry Andric apfLHS.add(APFloat(Sem, RHS.IntVal), APFloat::rmNearestTiesToEven);
856009b1c42SEd Schouten GV.IntVal = apfLHS.bitcastToAPInt();
857009b1c42SEd Schouten break;
858f4fe016fSEd Schouten case Instruction::FSub:
8594a16efa3SDimitry Andric apfLHS.subtract(APFloat(Sem, RHS.IntVal),
8604a16efa3SDimitry Andric APFloat::rmNearestTiesToEven);
861009b1c42SEd Schouten GV.IntVal = apfLHS.bitcastToAPInt();
862009b1c42SEd Schouten break;
863f4fe016fSEd Schouten case Instruction::FMul:
8644a16efa3SDimitry Andric apfLHS.multiply(APFloat(Sem, RHS.IntVal),
8654a16efa3SDimitry Andric APFloat::rmNearestTiesToEven);
866009b1c42SEd Schouten GV.IntVal = apfLHS.bitcastToAPInt();
867009b1c42SEd Schouten break;
868009b1c42SEd Schouten case Instruction::FDiv:
8694a16efa3SDimitry Andric apfLHS.divide(APFloat(Sem, RHS.IntVal),
8704a16efa3SDimitry Andric APFloat::rmNearestTiesToEven);
871009b1c42SEd Schouten GV.IntVal = apfLHS.bitcastToAPInt();
872009b1c42SEd Schouten break;
873009b1c42SEd Schouten case Instruction::FRem:
874dd58ef01SDimitry Andric apfLHS.mod(APFloat(Sem, RHS.IntVal));
875009b1c42SEd Schouten GV.IntVal = apfLHS.bitcastToAPInt();
876009b1c42SEd Schouten break;
877009b1c42SEd Schouten }
878009b1c42SEd Schouten }
879009b1c42SEd Schouten break;
880009b1c42SEd Schouten }
881009b1c42SEd Schouten return GV;
882009b1c42SEd Schouten }
883009b1c42SEd Schouten default:
884009b1c42SEd Schouten break;
885009b1c42SEd Schouten }
886cf099d11SDimitry Andric
887cf099d11SDimitry Andric SmallString<256> Msg;
888cf099d11SDimitry Andric raw_svector_ostream OS(Msg);
889cf099d11SDimitry Andric OS << "ConstantExpr not handled: " << *CE;
890cf099d11SDimitry Andric report_fatal_error(OS.str());
891009b1c42SEd Schouten }
892009b1c42SEd Schouten
8937fa27ce4SDimitry Andric if (auto *TETy = dyn_cast<TargetExtType>(C->getType())) {
8947fa27ce4SDimitry Andric assert(TETy->hasProperty(TargetExtType::HasZeroInit) && C->isNullValue() &&
8957fa27ce4SDimitry Andric "TargetExtType only supports null constant value");
8967fa27ce4SDimitry Andric C = Constant::getNullValue(TETy->getLayoutType());
8977fa27ce4SDimitry Andric }
8987fa27ce4SDimitry Andric
899cf099d11SDimitry Andric // Otherwise, we have a simple constant.
900009b1c42SEd Schouten GenericValue Result;
901009b1c42SEd Schouten switch (C->getType()->getTypeID()) {
902009b1c42SEd Schouten case Type::FloatTyID:
903009b1c42SEd Schouten Result.FloatVal = cast<ConstantFP>(C)->getValueAPF().convertToFloat();
904009b1c42SEd Schouten break;
905009b1c42SEd Schouten case Type::DoubleTyID:
906009b1c42SEd Schouten Result.DoubleVal = cast<ConstantFP>(C)->getValueAPF().convertToDouble();
907009b1c42SEd Schouten break;
908009b1c42SEd Schouten case Type::X86_FP80TyID:
909009b1c42SEd Schouten case Type::FP128TyID:
910009b1c42SEd Schouten case Type::PPC_FP128TyID:
911009b1c42SEd Schouten Result.IntVal = cast <ConstantFP>(C)->getValueAPF().bitcastToAPInt();
912009b1c42SEd Schouten break;
913009b1c42SEd Schouten case Type::IntegerTyID:
914009b1c42SEd Schouten Result.IntVal = cast<ConstantInt>(C)->getValue();
915009b1c42SEd Schouten break;
916009b1c42SEd Schouten case Type::PointerTyID:
917eb11fae6SDimitry Andric while (auto *A = dyn_cast<GlobalAlias>(C)) {
918eb11fae6SDimitry Andric C = A->getAliasee();
919eb11fae6SDimitry Andric }
920009b1c42SEd Schouten if (isa<ConstantPointerNull>(C))
9215ca98fd9SDimitry Andric Result.PointerVal = nullptr;
922009b1c42SEd Schouten else if (const Function *F = dyn_cast<Function>(C))
923009b1c42SEd Schouten Result = PTOGV(getPointerToFunctionOrStub(const_cast<Function*>(F)));
924009b1c42SEd Schouten else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
925009b1c42SEd Schouten Result = PTOGV(getOrEmitGlobalVariable(const_cast<GlobalVariable*>(GV)));
926009b1c42SEd Schouten else
92759850d08SRoman Divacky llvm_unreachable("Unknown constant pointer type!");
928009b1c42SEd Schouten break;
929cfca06d7SDimitry Andric case Type::ScalableVectorTyID:
930cfca06d7SDimitry Andric report_fatal_error(
931cfca06d7SDimitry Andric "Scalable vector support not yet implemented in ExecutionEngine");
932cfca06d7SDimitry Andric case Type::FixedVectorTyID: {
9334a16efa3SDimitry Andric unsigned elemNum;
9344a16efa3SDimitry Andric Type* ElemTy;
9354a16efa3SDimitry Andric const ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(C);
9364a16efa3SDimitry Andric const ConstantVector *CV = dyn_cast<ConstantVector>(C);
9374a16efa3SDimitry Andric const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(C);
9384a16efa3SDimitry Andric
9394a16efa3SDimitry Andric if (CDV) {
9404a16efa3SDimitry Andric elemNum = CDV->getNumElements();
9414a16efa3SDimitry Andric ElemTy = CDV->getElementType();
9424a16efa3SDimitry Andric } else if (CV || CAZ) {
943cfca06d7SDimitry Andric auto *VTy = cast<FixedVectorType>(C->getType());
9444a16efa3SDimitry Andric elemNum = VTy->getNumElements();
9454a16efa3SDimitry Andric ElemTy = VTy->getElementType();
9464a16efa3SDimitry Andric } else {
9474a16efa3SDimitry Andric llvm_unreachable("Unknown constant vector type!");
9484a16efa3SDimitry Andric }
9494a16efa3SDimitry Andric
9504a16efa3SDimitry Andric Result.AggregateVal.resize(elemNum);
9514a16efa3SDimitry Andric // Check if vector holds floats.
9524a16efa3SDimitry Andric if(ElemTy->isFloatTy()) {
9534a16efa3SDimitry Andric if (CAZ) {
9544a16efa3SDimitry Andric GenericValue floatZero;
9554a16efa3SDimitry Andric floatZero.FloatVal = 0.f;
9564a16efa3SDimitry Andric std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(),
9574a16efa3SDimitry Andric floatZero);
9584a16efa3SDimitry Andric break;
9594a16efa3SDimitry Andric }
9604a16efa3SDimitry Andric if(CV) {
9614a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
9624a16efa3SDimitry Andric if (!isa<UndefValue>(CV->getOperand(i)))
9634a16efa3SDimitry Andric Result.AggregateVal[i].FloatVal = cast<ConstantFP>(
9644a16efa3SDimitry Andric CV->getOperand(i))->getValueAPF().convertToFloat();
9654a16efa3SDimitry Andric break;
9664a16efa3SDimitry Andric }
9674a16efa3SDimitry Andric if(CDV)
9684a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
9694a16efa3SDimitry Andric Result.AggregateVal[i].FloatVal = CDV->getElementAsFloat(i);
9704a16efa3SDimitry Andric
9714a16efa3SDimitry Andric break;
9724a16efa3SDimitry Andric }
9734a16efa3SDimitry Andric // Check if vector holds doubles.
9744a16efa3SDimitry Andric if (ElemTy->isDoubleTy()) {
9754a16efa3SDimitry Andric if (CAZ) {
9764a16efa3SDimitry Andric GenericValue doubleZero;
9774a16efa3SDimitry Andric doubleZero.DoubleVal = 0.0;
9784a16efa3SDimitry Andric std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(),
9794a16efa3SDimitry Andric doubleZero);
9804a16efa3SDimitry Andric break;
9814a16efa3SDimitry Andric }
9824a16efa3SDimitry Andric if(CV) {
9834a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
9844a16efa3SDimitry Andric if (!isa<UndefValue>(CV->getOperand(i)))
9854a16efa3SDimitry Andric Result.AggregateVal[i].DoubleVal = cast<ConstantFP>(
9864a16efa3SDimitry Andric CV->getOperand(i))->getValueAPF().convertToDouble();
9874a16efa3SDimitry Andric break;
9884a16efa3SDimitry Andric }
9894a16efa3SDimitry Andric if(CDV)
9904a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
9914a16efa3SDimitry Andric Result.AggregateVal[i].DoubleVal = CDV->getElementAsDouble(i);
9924a16efa3SDimitry Andric
9934a16efa3SDimitry Andric break;
9944a16efa3SDimitry Andric }
9954a16efa3SDimitry Andric // Check if vector holds integers.
9964a16efa3SDimitry Andric if (ElemTy->isIntegerTy()) {
9974a16efa3SDimitry Andric if (CAZ) {
9984a16efa3SDimitry Andric GenericValue intZero;
9994a16efa3SDimitry Andric intZero.IntVal = APInt(ElemTy->getScalarSizeInBits(), 0ull);
10004a16efa3SDimitry Andric std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(),
10014a16efa3SDimitry Andric intZero);
10024a16efa3SDimitry Andric break;
10034a16efa3SDimitry Andric }
10044a16efa3SDimitry Andric if(CV) {
10054a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
10064a16efa3SDimitry Andric if (!isa<UndefValue>(CV->getOperand(i)))
10074a16efa3SDimitry Andric Result.AggregateVal[i].IntVal = cast<ConstantInt>(
10084a16efa3SDimitry Andric CV->getOperand(i))->getValue();
10094a16efa3SDimitry Andric else {
10104a16efa3SDimitry Andric Result.AggregateVal[i].IntVal =
10114a16efa3SDimitry Andric APInt(CV->getOperand(i)->getType()->getPrimitiveSizeInBits(), 0);
10124a16efa3SDimitry Andric }
10134a16efa3SDimitry Andric break;
10144a16efa3SDimitry Andric }
10154a16efa3SDimitry Andric if(CDV)
10164a16efa3SDimitry Andric for (unsigned i = 0; i < elemNum; ++i)
10174a16efa3SDimitry Andric Result.AggregateVal[i].IntVal = APInt(
10184a16efa3SDimitry Andric CDV->getElementType()->getPrimitiveSizeInBits(),
10194a16efa3SDimitry Andric CDV->getElementAsInteger(i));
10204a16efa3SDimitry Andric
10214a16efa3SDimitry Andric break;
10224a16efa3SDimitry Andric }
10234a16efa3SDimitry Andric llvm_unreachable("Unknown constant pointer type!");
1024cfca06d7SDimitry Andric } break;
10254a16efa3SDimitry Andric
1026009b1c42SEd Schouten default:
1027cf099d11SDimitry Andric SmallString<256> Msg;
1028cf099d11SDimitry Andric raw_svector_ostream OS(Msg);
1029cf099d11SDimitry Andric OS << "ERROR: Constant unimplemented for type: " << *C->getType();
1030cf099d11SDimitry Andric report_fatal_error(OS.str());
1031009b1c42SEd Schouten }
1032cf099d11SDimitry Andric
1033009b1c42SEd Schouten return Result;
1034009b1c42SEd Schouten }
1035009b1c42SEd Schouten
StoreValueToMemory(const GenericValue & Val,GenericValue * Ptr,Type * Ty)1036009b1c42SEd Schouten void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
103730815c53SDimitry Andric GenericValue *Ptr, Type *Ty) {
10387fa27ce4SDimitry Andric // It is safe to treat TargetExtType as its layout type since the underlying
10397fa27ce4SDimitry Andric // bits are only copied and are not inspected.
10407fa27ce4SDimitry Andric if (auto *TETy = dyn_cast<TargetExtType>(Ty))
10417fa27ce4SDimitry Andric Ty = TETy->getLayoutType();
10427fa27ce4SDimitry Andric
1043dd58ef01SDimitry Andric const unsigned StoreBytes = getDataLayout().getTypeStoreSize(Ty);
1044009b1c42SEd Schouten
1045009b1c42SEd Schouten switch (Ty->getTypeID()) {
10464a16efa3SDimitry Andric default:
10474a16efa3SDimitry Andric dbgs() << "Cannot store value of type " << *Ty << "!\n";
10484a16efa3SDimitry Andric break;
1049009b1c42SEd Schouten case Type::IntegerTyID:
1050009b1c42SEd Schouten StoreIntToMemory(Val.IntVal, (uint8_t*)Ptr, StoreBytes);
1051009b1c42SEd Schouten break;
1052009b1c42SEd Schouten case Type::FloatTyID:
1053009b1c42SEd Schouten *((float*)Ptr) = Val.FloatVal;
1054009b1c42SEd Schouten break;
1055009b1c42SEd Schouten case Type::DoubleTyID:
1056009b1c42SEd Schouten *((double*)Ptr) = Val.DoubleVal;
1057009b1c42SEd Schouten break;
1058009b1c42SEd Schouten case Type::X86_FP80TyID:
1059009b1c42SEd Schouten memcpy(Ptr, Val.IntVal.getRawData(), 10);
1060009b1c42SEd Schouten break;
1061009b1c42SEd Schouten case Type::PointerTyID:
1062009b1c42SEd Schouten // Ensure 64 bit target pointers are fully initialized on 32 bit hosts.
1063009b1c42SEd Schouten if (StoreBytes != sizeof(PointerTy))
10646b943ff3SDimitry Andric memset(&(Ptr->PointerVal), 0, StoreBytes);
1065009b1c42SEd Schouten
1066009b1c42SEd Schouten *((PointerTy*)Ptr) = Val.PointerVal;
1067009b1c42SEd Schouten break;
1068cfca06d7SDimitry Andric case Type::FixedVectorTyID:
1069cfca06d7SDimitry Andric case Type::ScalableVectorTyID:
10704a16efa3SDimitry Andric for (unsigned i = 0; i < Val.AggregateVal.size(); ++i) {
10714a16efa3SDimitry Andric if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
10724a16efa3SDimitry Andric *(((double*)Ptr)+i) = Val.AggregateVal[i].DoubleVal;
10734a16efa3SDimitry Andric if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
10744a16efa3SDimitry Andric *(((float*)Ptr)+i) = Val.AggregateVal[i].FloatVal;
10754a16efa3SDimitry Andric if (cast<VectorType>(Ty)->getElementType()->isIntegerTy()) {
10764a16efa3SDimitry Andric unsigned numOfBytes =(Val.AggregateVal[i].IntVal.getBitWidth()+7)/8;
10774a16efa3SDimitry Andric StoreIntToMemory(Val.AggregateVal[i].IntVal,
10784a16efa3SDimitry Andric (uint8_t*)Ptr + numOfBytes*i, numOfBytes);
10794a16efa3SDimitry Andric }
10804a16efa3SDimitry Andric }
10814a16efa3SDimitry Andric break;
1082009b1c42SEd Schouten }
1083009b1c42SEd Schouten
1084dd58ef01SDimitry Andric if (sys::IsLittleEndianHost != getDataLayout().isLittleEndian())
1085009b1c42SEd Schouten // Host and target are different endian - reverse the stored bytes.
1086009b1c42SEd Schouten std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
1087009b1c42SEd Schouten }
1088009b1c42SEd Schouten
1089009b1c42SEd Schouten /// FIXME: document
1090009b1c42SEd Schouten ///
LoadValueFromMemory(GenericValue & Result,GenericValue * Ptr,Type * Ty)1091009b1c42SEd Schouten void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
1092009b1c42SEd Schouten GenericValue *Ptr,
109330815c53SDimitry Andric Type *Ty) {
10947fa27ce4SDimitry Andric if (auto *TETy = dyn_cast<TargetExtType>(Ty))
10957fa27ce4SDimitry Andric Ty = TETy->getLayoutType();
10967fa27ce4SDimitry Andric
1097dd58ef01SDimitry Andric const unsigned LoadBytes = getDataLayout().getTypeStoreSize(Ty);
1098009b1c42SEd Schouten
1099009b1c42SEd Schouten switch (Ty->getTypeID()) {
1100009b1c42SEd Schouten case Type::IntegerTyID:
1101009b1c42SEd Schouten // An APInt with all words initially zero.
1102009b1c42SEd Schouten Result.IntVal = APInt(cast<IntegerType>(Ty)->getBitWidth(), 0);
1103009b1c42SEd Schouten LoadIntFromMemory(Result.IntVal, (uint8_t*)Ptr, LoadBytes);
1104009b1c42SEd Schouten break;
1105009b1c42SEd Schouten case Type::FloatTyID:
1106009b1c42SEd Schouten Result.FloatVal = *((float*)Ptr);
1107009b1c42SEd Schouten break;
1108009b1c42SEd Schouten case Type::DoubleTyID:
1109009b1c42SEd Schouten Result.DoubleVal = *((double*)Ptr);
1110009b1c42SEd Schouten break;
1111009b1c42SEd Schouten case Type::PointerTyID:
1112009b1c42SEd Schouten Result.PointerVal = *((PointerTy*)Ptr);
1113009b1c42SEd Schouten break;
1114009b1c42SEd Schouten case Type::X86_FP80TyID: {
1115009b1c42SEd Schouten // This is endian dependent, but it will only work on x86 anyway.
1116009b1c42SEd Schouten // FIXME: Will not trap if loading a signaling NaN.
1117009b1c42SEd Schouten uint64_t y[2];
1118009b1c42SEd Schouten memcpy(y, Ptr, 10);
111930815c53SDimitry Andric Result.IntVal = APInt(80, y);
1120009b1c42SEd Schouten break;
1121009b1c42SEd Schouten }
1122cfca06d7SDimitry Andric case Type::ScalableVectorTyID:
1123cfca06d7SDimitry Andric report_fatal_error(
1124cfca06d7SDimitry Andric "Scalable vector support not yet implemented in ExecutionEngine");
1125cfca06d7SDimitry Andric case Type::FixedVectorTyID: {
1126cfca06d7SDimitry Andric auto *VT = cast<FixedVectorType>(Ty);
1127dd58ef01SDimitry Andric Type *ElemT = VT->getElementType();
11284a16efa3SDimitry Andric const unsigned numElems = VT->getNumElements();
11294a16efa3SDimitry Andric if (ElemT->isFloatTy()) {
11304a16efa3SDimitry Andric Result.AggregateVal.resize(numElems);
11314a16efa3SDimitry Andric for (unsigned i = 0; i < numElems; ++i)
11324a16efa3SDimitry Andric Result.AggregateVal[i].FloatVal = *((float*)Ptr+i);
11334a16efa3SDimitry Andric }
11344a16efa3SDimitry Andric if (ElemT->isDoubleTy()) {
11354a16efa3SDimitry Andric Result.AggregateVal.resize(numElems);
11364a16efa3SDimitry Andric for (unsigned i = 0; i < numElems; ++i)
11374a16efa3SDimitry Andric Result.AggregateVal[i].DoubleVal = *((double*)Ptr+i);
11384a16efa3SDimitry Andric }
11394a16efa3SDimitry Andric if (ElemT->isIntegerTy()) {
11404a16efa3SDimitry Andric GenericValue intZero;
11414a16efa3SDimitry Andric const unsigned elemBitWidth = cast<IntegerType>(ElemT)->getBitWidth();
11424a16efa3SDimitry Andric intZero.IntVal = APInt(elemBitWidth, 0);
11434a16efa3SDimitry Andric Result.AggregateVal.resize(numElems, intZero);
11444a16efa3SDimitry Andric for (unsigned i = 0; i < numElems; ++i)
11454a16efa3SDimitry Andric LoadIntFromMemory(Result.AggregateVal[i].IntVal,
11464a16efa3SDimitry Andric (uint8_t*)Ptr+((elemBitWidth+7)/8)*i, (elemBitWidth+7)/8);
11474a16efa3SDimitry Andric }
11484a16efa3SDimitry Andric break;
11494a16efa3SDimitry Andric }
1150009b1c42SEd Schouten default:
1151cf099d11SDimitry Andric SmallString<256> Msg;
1152cf099d11SDimitry Andric raw_svector_ostream OS(Msg);
1153cf099d11SDimitry Andric OS << "Cannot load value of type " << *Ty << "!";
1154cf099d11SDimitry Andric report_fatal_error(OS.str());
1155009b1c42SEd Schouten }
1156009b1c42SEd Schouten }
1157009b1c42SEd Schouten
InitializeMemory(const Constant * Init,void * Addr)1158009b1c42SEd Schouten void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
1159eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "JIT: Initializing " << Addr << " ");
1160eb11fae6SDimitry Andric LLVM_DEBUG(Init->dump());
116163faed5bSDimitry Andric if (isa<UndefValue>(Init))
1162009b1c42SEd Schouten return;
116363faed5bSDimitry Andric
116463faed5bSDimitry Andric if (const ConstantVector *CP = dyn_cast<ConstantVector>(Init)) {
1165009b1c42SEd Schouten unsigned ElementSize =
1166dd58ef01SDimitry Andric getDataLayout().getTypeAllocSize(CP->getType()->getElementType());
1167009b1c42SEd Schouten for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
1168009b1c42SEd Schouten InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize);
1169009b1c42SEd Schouten return;
117063faed5bSDimitry Andric }
117163faed5bSDimitry Andric
117263faed5bSDimitry Andric if (isa<ConstantAggregateZero>(Init)) {
1173dd58ef01SDimitry Andric memset(Addr, 0, (size_t)getDataLayout().getTypeAllocSize(Init->getType()));
1174009b1c42SEd Schouten return;
117563faed5bSDimitry Andric }
117663faed5bSDimitry Andric
117763faed5bSDimitry Andric if (const ConstantArray *CPA = dyn_cast<ConstantArray>(Init)) {
1178009b1c42SEd Schouten unsigned ElementSize =
1179dd58ef01SDimitry Andric getDataLayout().getTypeAllocSize(CPA->getType()->getElementType());
1180009b1c42SEd Schouten for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
1181009b1c42SEd Schouten InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize);
1182009b1c42SEd Schouten return;
118363faed5bSDimitry Andric }
118463faed5bSDimitry Andric
118563faed5bSDimitry Andric if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(Init)) {
1186009b1c42SEd Schouten const StructLayout *SL =
1187dd58ef01SDimitry Andric getDataLayout().getStructLayout(cast<StructType>(CPS->getType()));
1188009b1c42SEd Schouten for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
1189009b1c42SEd Schouten InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->getElementOffset(i));
1190009b1c42SEd Schouten return;
119163faed5bSDimitry Andric }
119263faed5bSDimitry Andric
119363faed5bSDimitry Andric if (const ConstantDataSequential *CDS =
119463faed5bSDimitry Andric dyn_cast<ConstantDataSequential>(Init)) {
119563faed5bSDimitry Andric // CDS is already laid out in host memory order.
119663faed5bSDimitry Andric StringRef Data = CDS->getRawDataValues();
119763faed5bSDimitry Andric memcpy(Addr, Data.data(), Data.size());
119863faed5bSDimitry Andric return;
119963faed5bSDimitry Andric }
120063faed5bSDimitry Andric
120163faed5bSDimitry Andric if (Init->getType()->isFirstClassType()) {
1202009b1c42SEd Schouten GenericValue Val = getConstantValue(Init);
1203009b1c42SEd Schouten StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType());
1204009b1c42SEd Schouten return;
1205009b1c42SEd Schouten }
1206009b1c42SEd Schouten
1207eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Bad Type: " << *Init->getType() << "\n");
120859850d08SRoman Divacky llvm_unreachable("Unknown constant type to initialize memory with!");
1209009b1c42SEd Schouten }
1210009b1c42SEd Schouten
1211009b1c42SEd Schouten /// EmitGlobals - Emit all of the global variables to memory, storing their
1212009b1c42SEd Schouten /// addresses into GlobalAddress. This must make sure to copy the contents of
1213009b1c42SEd Schouten /// their initializers into the memory.
emitGlobals()1214009b1c42SEd Schouten void ExecutionEngine::emitGlobals() {
1215009b1c42SEd Schouten // Loop over all of the global variables in the program, allocating the memory
1216009b1c42SEd Schouten // to hold them. If there is more than one module, do a prepass over globals
1217009b1c42SEd Schouten // to figure out how the different modules should link together.
121830815c53SDimitry Andric std::map<std::pair<std::string, Type*>,
1219009b1c42SEd Schouten const GlobalValue*> LinkedGlobalsMap;
1220009b1c42SEd Schouten
1221009b1c42SEd Schouten if (Modules.size() != 1) {
1222ac9a064cSDimitry Andric for (const auto &M : Modules) {
1223ac9a064cSDimitry Andric for (const auto &GV : M->globals()) {
12245ca98fd9SDimitry Andric if (GV.hasLocalLinkage() || GV.isDeclaration() ||
12255ca98fd9SDimitry Andric GV.hasAppendingLinkage() || !GV.hasName())
1226009b1c42SEd Schouten continue;// Ignore external globals and globals with internal linkage.
1227009b1c42SEd Schouten
1228cfca06d7SDimitry Andric const GlobalValue *&GVEntry = LinkedGlobalsMap[std::make_pair(
1229cfca06d7SDimitry Andric std::string(GV.getName()), GV.getType())];
1230009b1c42SEd Schouten
1231009b1c42SEd Schouten // If this is the first time we've seen this global, it is the canonical
1232009b1c42SEd Schouten // version.
1233009b1c42SEd Schouten if (!GVEntry) {
12345ca98fd9SDimitry Andric GVEntry = &GV;
1235009b1c42SEd Schouten continue;
1236009b1c42SEd Schouten }
1237009b1c42SEd Schouten
1238009b1c42SEd Schouten // If the existing global is strong, never replace it.
12395ca98fd9SDimitry Andric if (GVEntry->hasExternalLinkage())
1240009b1c42SEd Schouten continue;
1241009b1c42SEd Schouten
1242009b1c42SEd Schouten // Otherwise, we know it's linkonce/weak, replace it if this is a strong
1243009b1c42SEd Schouten // symbol. FIXME is this right for common?
12445ca98fd9SDimitry Andric if (GV.hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())
12455ca98fd9SDimitry Andric GVEntry = &GV;
1246009b1c42SEd Schouten }
1247009b1c42SEd Schouten }
1248009b1c42SEd Schouten }
1249009b1c42SEd Schouten
1250009b1c42SEd Schouten std::vector<const GlobalValue*> NonCanonicalGlobals;
1251ac9a064cSDimitry Andric for (const auto &M : Modules) {
1252ac9a064cSDimitry Andric for (const auto &GV : M->globals()) {
1253009b1c42SEd Schouten // In the multi-module case, see what this global maps to.
1254009b1c42SEd Schouten if (!LinkedGlobalsMap.empty()) {
1255cfca06d7SDimitry Andric if (const GlobalValue *GVEntry = LinkedGlobalsMap[std::make_pair(
1256cfca06d7SDimitry Andric std::string(GV.getName()), GV.getType())]) {
1257009b1c42SEd Schouten // If something else is the canonical global, ignore this one.
12585ca98fd9SDimitry Andric if (GVEntry != &GV) {
12595ca98fd9SDimitry Andric NonCanonicalGlobals.push_back(&GV);
1260009b1c42SEd Schouten continue;
1261009b1c42SEd Schouten }
1262009b1c42SEd Schouten }
1263009b1c42SEd Schouten }
1264009b1c42SEd Schouten
12655ca98fd9SDimitry Andric if (!GV.isDeclaration()) {
12665ca98fd9SDimitry Andric addGlobalMapping(&GV, getMemoryForGV(&GV));
1267009b1c42SEd Schouten } else {
1268009b1c42SEd Schouten // External variable reference. Try to use the dynamic loader to
1269009b1c42SEd Schouten // get a pointer to it.
1270cfca06d7SDimitry Andric if (void *SymAddr = sys::DynamicLibrary::SearchForAddressOfSymbol(
1271cfca06d7SDimitry Andric std::string(GV.getName())))
12725ca98fd9SDimitry Andric addGlobalMapping(&GV, SymAddr);
1273009b1c42SEd Schouten else {
1274d7f7719eSRoman Divacky report_fatal_error("Could not resolve external global address: "
12755ca98fd9SDimitry Andric +GV.getName());
1276009b1c42SEd Schouten }
1277009b1c42SEd Schouten }
1278009b1c42SEd Schouten }
1279009b1c42SEd Schouten
1280009b1c42SEd Schouten // If there are multiple modules, map the non-canonical globals to their
1281009b1c42SEd Schouten // canonical location.
1282009b1c42SEd Schouten if (!NonCanonicalGlobals.empty()) {
1283f65dcba8SDimitry Andric for (const GlobalValue *GV : NonCanonicalGlobals) {
1284cfca06d7SDimitry Andric const GlobalValue *CGV = LinkedGlobalsMap[std::make_pair(
1285cfca06d7SDimitry Andric std::string(GV->getName()), GV->getType())];
1286009b1c42SEd Schouten void *Ptr = getPointerToGlobalIfAvailable(CGV);
1287009b1c42SEd Schouten assert(Ptr && "Canonical global wasn't codegen'd!");
1288009b1c42SEd Schouten addGlobalMapping(GV, Ptr);
1289009b1c42SEd Schouten }
1290009b1c42SEd Schouten }
1291009b1c42SEd Schouten
1292009b1c42SEd Schouten // Now that all of the globals are set up in memory, loop through them all
1293009b1c42SEd Schouten // and initialize their contents.
1294ac9a064cSDimitry Andric for (const auto &GV : M->globals()) {
12955ca98fd9SDimitry Andric if (!GV.isDeclaration()) {
1296009b1c42SEd Schouten if (!LinkedGlobalsMap.empty()) {
1297cfca06d7SDimitry Andric if (const GlobalValue *GVEntry = LinkedGlobalsMap[std::make_pair(
1298cfca06d7SDimitry Andric std::string(GV.getName()), GV.getType())])
12995ca98fd9SDimitry Andric if (GVEntry != &GV) // Not the canonical variable.
1300009b1c42SEd Schouten continue;
1301009b1c42SEd Schouten }
1302cfca06d7SDimitry Andric emitGlobalVariable(&GV);
1303009b1c42SEd Schouten }
1304009b1c42SEd Schouten }
1305009b1c42SEd Schouten }
1306009b1c42SEd Schouten }
1307009b1c42SEd Schouten
1308009b1c42SEd Schouten // EmitGlobalVariable - This method emits the specified global variable to the
1309009b1c42SEd Schouten // address specified in GlobalAddresses, or allocates new memory if it's not
1310009b1c42SEd Schouten // already in the map.
emitGlobalVariable(const GlobalVariable * GV)1311cfca06d7SDimitry Andric void ExecutionEngine::emitGlobalVariable(const GlobalVariable *GV) {
1312009b1c42SEd Schouten void *GA = getPointerToGlobalIfAvailable(GV);
1313009b1c42SEd Schouten
13145ca98fd9SDimitry Andric if (!GA) {
1315009b1c42SEd Schouten // If it's not already specified, allocate memory for the global.
1316009b1c42SEd Schouten GA = getMemoryForGV(GV);
1317f8af5cf6SDimitry Andric
1318f8af5cf6SDimitry Andric // If we failed to allocate memory for this global, return.
13195ca98fd9SDimitry Andric if (!GA) return;
1320f8af5cf6SDimitry Andric
1321009b1c42SEd Schouten addGlobalMapping(GV, GA);
1322009b1c42SEd Schouten }
1323009b1c42SEd Schouten
1324009b1c42SEd Schouten // Don't initialize if it's thread local, let the client do it.
1325009b1c42SEd Schouten if (!GV->isThreadLocal())
1326009b1c42SEd Schouten InitializeMemory(GV->getInitializer(), GA);
1327009b1c42SEd Schouten
132801095a5dSDimitry Andric Type *ElTy = GV->getValueType();
1329dd58ef01SDimitry Andric size_t GVSize = (size_t)getDataLayout().getTypeAllocSize(ElTy);
1330009b1c42SEd Schouten NumInitBytes += (unsigned)GVSize;
1331009b1c42SEd Schouten ++NumGlobals;
1332009b1c42SEd Schouten }
1333