1*9880d681SAndroid Build Coastguard Worker //===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker namespace llvm {
18*9880d681SAndroid Build Coastguard Worker namespace orc {
19*9880d681SAndroid Build Coastguard Worker
CtorDtorIterator(const GlobalVariable * GV,bool End)20*9880d681SAndroid Build Coastguard Worker CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
21*9880d681SAndroid Build Coastguard Worker : InitList(
22*9880d681SAndroid Build Coastguard Worker GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
23*9880d681SAndroid Build Coastguard Worker I((InitList && End) ? InitList->getNumOperands() : 0) {
24*9880d681SAndroid Build Coastguard Worker }
25*9880d681SAndroid Build Coastguard Worker
operator ==(const CtorDtorIterator & Other) const26*9880d681SAndroid Build Coastguard Worker bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const {
27*9880d681SAndroid Build Coastguard Worker assert(InitList == Other.InitList && "Incomparable iterators.");
28*9880d681SAndroid Build Coastguard Worker return I == Other.I;
29*9880d681SAndroid Build Coastguard Worker }
30*9880d681SAndroid Build Coastguard Worker
operator !=(const CtorDtorIterator & Other) const31*9880d681SAndroid Build Coastguard Worker bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const {
32*9880d681SAndroid Build Coastguard Worker return !(*this == Other);
33*9880d681SAndroid Build Coastguard Worker }
34*9880d681SAndroid Build Coastguard Worker
operator ++()35*9880d681SAndroid Build Coastguard Worker CtorDtorIterator& CtorDtorIterator::operator++() {
36*9880d681SAndroid Build Coastguard Worker ++I;
37*9880d681SAndroid Build Coastguard Worker return *this;
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker
operator ++(int)40*9880d681SAndroid Build Coastguard Worker CtorDtorIterator CtorDtorIterator::operator++(int) {
41*9880d681SAndroid Build Coastguard Worker CtorDtorIterator Temp = *this;
42*9880d681SAndroid Build Coastguard Worker ++I;
43*9880d681SAndroid Build Coastguard Worker return Temp;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
operator *() const46*9880d681SAndroid Build Coastguard Worker CtorDtorIterator::Element CtorDtorIterator::operator*() const {
47*9880d681SAndroid Build Coastguard Worker ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I));
48*9880d681SAndroid Build Coastguard Worker assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors");
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker Constant *FuncC = CS->getOperand(1);
51*9880d681SAndroid Build Coastguard Worker Function *Func = nullptr;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker // Extract function pointer, pulling off any casts.
54*9880d681SAndroid Build Coastguard Worker while (FuncC) {
55*9880d681SAndroid Build Coastguard Worker if (Function *F = dyn_cast_or_null<Function>(FuncC)) {
56*9880d681SAndroid Build Coastguard Worker Func = F;
57*9880d681SAndroid Build Coastguard Worker break;
58*9880d681SAndroid Build Coastguard Worker } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
59*9880d681SAndroid Build Coastguard Worker if (CE->isCast())
60*9880d681SAndroid Build Coastguard Worker FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
61*9880d681SAndroid Build Coastguard Worker else
62*9880d681SAndroid Build Coastguard Worker break;
63*9880d681SAndroid Build Coastguard Worker } else {
64*9880d681SAndroid Build Coastguard Worker // This isn't anything we recognize. Bail out with Func left set to null.
65*9880d681SAndroid Build Coastguard Worker break;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
70*9880d681SAndroid Build Coastguard Worker Value *Data = CS->getOperand(2);
71*9880d681SAndroid Build Coastguard Worker return Element(Priority->getZExtValue(), Func, Data);
72*9880d681SAndroid Build Coastguard Worker }
73*9880d681SAndroid Build Coastguard Worker
getConstructors(const Module & M)74*9880d681SAndroid Build Coastguard Worker iterator_range<CtorDtorIterator> getConstructors(const Module &M) {
75*9880d681SAndroid Build Coastguard Worker const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors");
76*9880d681SAndroid Build Coastguard Worker return make_range(CtorDtorIterator(CtorsList, false),
77*9880d681SAndroid Build Coastguard Worker CtorDtorIterator(CtorsList, true));
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
getDestructors(const Module & M)80*9880d681SAndroid Build Coastguard Worker iterator_range<CtorDtorIterator> getDestructors(const Module &M) {
81*9880d681SAndroid Build Coastguard Worker const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors");
82*9880d681SAndroid Build Coastguard Worker return make_range(CtorDtorIterator(DtorsList, false),
83*9880d681SAndroid Build Coastguard Worker CtorDtorIterator(DtorsList, true));
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker
runDestructors()86*9880d681SAndroid Build Coastguard Worker void LocalCXXRuntimeOverrides::runDestructors() {
87*9880d681SAndroid Build Coastguard Worker auto& CXXDestructorDataPairs = DSOHandleOverride;
88*9880d681SAndroid Build Coastguard Worker for (auto &P : CXXDestructorDataPairs)
89*9880d681SAndroid Build Coastguard Worker P.first(P.second);
90*9880d681SAndroid Build Coastguard Worker CXXDestructorDataPairs.clear();
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
CXAAtExitOverride(DestructorPtr Destructor,void * Arg,void * DSOHandle)93*9880d681SAndroid Build Coastguard Worker int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor,
94*9880d681SAndroid Build Coastguard Worker void *Arg, void *DSOHandle) {
95*9880d681SAndroid Build Coastguard Worker auto& CXXDestructorDataPairs =
96*9880d681SAndroid Build Coastguard Worker *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
97*9880d681SAndroid Build Coastguard Worker CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
98*9880d681SAndroid Build Coastguard Worker return 0;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker } // End namespace orc.
102*9880d681SAndroid Build Coastguard Worker } // End namespace llvm.
103