xref: /aosp_15_r20/external/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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