1283625Sdim//===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===// 2283625Sdim// 3283625Sdim// The LLVM Compiler Infrastructure 4283625Sdim// 5283625Sdim// This file is distributed under the University of Illinois Open Source 6283625Sdim// License. See LICENSE.TXT for details. 7283625Sdim// 8283625Sdim//===----------------------------------------------------------------------===// 9283625Sdim 10283625Sdim#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 11283625Sdim 12283625Sdim#include "llvm/IR/Constants.h" 13283625Sdim#include "llvm/IR/Function.h" 14283625Sdim#include "llvm/IR/GlobalVariable.h" 15283625Sdim#include "llvm/IR/Module.h" 16283625Sdim 17283625Sdimnamespace llvm { 18283625Sdimnamespace orc { 19283625Sdim 20283625SdimCtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) 21283625Sdim : InitList( 22283625Sdim GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), 23283625Sdim I((InitList && End) ? InitList->getNumOperands() : 0) { 24283625Sdim} 25283625Sdim 26283625Sdimbool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { 27283625Sdim assert(InitList == Other.InitList && "Incomparable iterators."); 28283625Sdim return I == Other.I; 29283625Sdim} 30283625Sdim 31283625Sdimbool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { 32283625Sdim return !(*this == Other); 33283625Sdim} 34283625Sdim 35283625SdimCtorDtorIterator& CtorDtorIterator::operator++() { 36283625Sdim ++I; 37283625Sdim return *this; 38283625Sdim} 39283625Sdim 40283625SdimCtorDtorIterator CtorDtorIterator::operator++(int) { 41283625Sdim CtorDtorIterator Temp = *this; 42283625Sdim ++I; 43283625Sdim return Temp; 44283625Sdim} 45283625Sdim 46283625SdimCtorDtorIterator::Element CtorDtorIterator::operator*() const { 47283625Sdim ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); 48283625Sdim assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); 49283625Sdim 50283625Sdim Constant *FuncC = CS->getOperand(1); 51283625Sdim Function *Func = nullptr; 52283625Sdim 53283625Sdim // Extract function pointer, pulling off any casts. 54283625Sdim while (FuncC) { 55283625Sdim if (Function *F = dyn_cast_or_null<Function>(FuncC)) { 56283625Sdim Func = F; 57283625Sdim break; 58283625Sdim } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { 59283625Sdim if (CE->isCast()) 60283625Sdim FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0)); 61283625Sdim else 62283625Sdim break; 63283625Sdim } else { 64283625Sdim // This isn't anything we recognize. Bail out with Func left set to null. 65283625Sdim break; 66283625Sdim } 67283625Sdim } 68283625Sdim 69283625Sdim ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 70283625Sdim Value *Data = CS->getOperand(2); 71283625Sdim return Element(Priority->getZExtValue(), Func, Data); 72283625Sdim} 73283625Sdim 74283625Sdimiterator_range<CtorDtorIterator> getConstructors(const Module &M) { 75283625Sdim const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); 76283625Sdim return make_range(CtorDtorIterator(CtorsList, false), 77283625Sdim CtorDtorIterator(CtorsList, true)); 78283625Sdim} 79283625Sdim 80283625Sdimiterator_range<CtorDtorIterator> getDestructors(const Module &M) { 81283625Sdim const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); 82283625Sdim return make_range(CtorDtorIterator(DtorsList, false), 83283625Sdim CtorDtorIterator(DtorsList, true)); 84283625Sdim} 85283625Sdim 86283625Sdimvoid LocalCXXRuntimeOverrides::runDestructors() { 87283625Sdim auto& CXXDestructorDataPairs = DSOHandleOverride; 88283625Sdim for (auto &P : CXXDestructorDataPairs) 89283625Sdim P.first(P.second); 90283625Sdim CXXDestructorDataPairs.clear(); 91283625Sdim} 92283625Sdim 93283625Sdimint LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor, 94283625Sdim void *Arg, void *DSOHandle) { 95283625Sdim auto& CXXDestructorDataPairs = 96283625Sdim *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); 97283625Sdim CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); 98283625Sdim return 0; 99283625Sdim} 100283625Sdim 101283625Sdim} // End namespace orc. 102283625Sdim} // End namespace llvm. 103