LLVM: lib/ExecutionEngine/Orc/IRPartitionLayer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12

13using namespace llvm;

15

19

20 auto DeleteExtractedDefs = [](GlobalValue &GV) {

21

23

24

27 F.deleteBody();

28 F.setPersonalityFn(nullptr);

32

33

35 Constant *Aliasee = A.getAliasee();

36 assert(A.hasName() && "Anonymous alias?");

37 assert(Aliasee->hasName() && "Anonymous aliasee");

38 std::string AliasName = std::string(A.getName());

39

42 A.replaceAllUsesWith(F);

43 A.eraseFromParent();

44 F->setName(AliasName);

48 A.replaceAllUsesWith(G);

49 A.eraseFromParent();

50 G->setName(AliasName);

51 } else

53 } else

55 };

56

57 auto NewTSM = cloneToNewContext(TSM, ShouldExtract, DeleteExtractedDefs);

58 NewTSM.withModuleDo([&](Module &M) {

59 M.setModuleIdentifier((M.getModuleIdentifier() + Suffix).str());

60 });

61

62 return NewTSM;

63}

64

65namespace llvm {

66namespace orc {

67

69public:

75

82

83private:

84 void materialize(std::unique_ptr R) override {

85 Parent.emitPartition(std::move(R), std::move(TSM),

87 }

88

90

91

93 "ExtractingIRMaterializationUnit");

94 }

95

97};

98

99}

100}

101

104

106 this->Partition = Partition;

107}

108

109std::optionalIRPartitionLayer::GlobalValueSet

111 return std::move(Requested);

112}

113

114std::optionalIRPartitionLayer::GlobalValueSet

116 return std::nullopt;

117}

118

121 assert(TSM && "Null module");

122

125

126 cleanUpModule(M);

127 });

128

129

130 if (auto Err = R->replace(std::make_unique(

132 ES.reportError(std::move(Err));

133 R->failMaterialization();

134 return;

135 }

136}

137

138void IRPartitionLayer::cleanUpModule(Module &M) {

139 for (auto &F : M.functions()) {

140 if (F.isDeclaration())

141 continue;

142

143 if (F.hasAvailableExternallyLinkage()) {

144 F.deleteBody();

145 F.setPersonalityFn(nullptr);

146 continue;

147 }

148 }

149}

150

151void IRPartitionLayer::expandPartition(GlobalValueSet &Partition) {

152

153

154

155

156

157

158 assert(!Partition.empty() && "Unexpected empty partition");

159

160 const Module &M = *(*Partition.begin())->getParent();

161 bool ContainsGlobalVariables = false;

162 std::vector<const GlobalValue *> GVsToAdd;

163

164 for (const auto *GV : Partition)

166 GVsToAdd.push_back(

169 ContainsGlobalVariables = true;

170

171 for (auto &A : M.aliases())

173 GVsToAdd.push_back(&A);

174

175 if (ContainsGlobalVariables)

176 for (auto &G : M.globals())

177 GVsToAdd.push_back(&G);

178

179 for (const auto *GV : GVsToAdd)

180 Partition.insert(GV);

181}

182

183void IRPartitionLayer::emitPartition(

184 std::unique_ptr R, ThreadSafeModule TSM,

186

187

188

189

190

191

194 for (auto &Name : R->getRequestedSymbols()) {

195 if (Name == R->getInitializerSymbol())

198 RequestedGVs.insert(&GV);

199 });

200 else {

201 assert(Defs.count(Name) && "No definition for symbol");

202 RequestedGVs.insert(Defs[Name]);

203 }

204 }

205

206

207

208 auto GVsToExtract =

209 TSM.withModuleDo([&](Module &M) { return Partition(RequestedGVs); });

210

211

212

213

214 if (GVsToExtract == std::nullopt) {

215 Defs.clear();

216 BaseLayer.emit(std::move(R), std::move(TSM));

217 return;

218 }

219

220

221 if (GVsToExtract->empty()) {

222 if (auto Err =

223 R->replace(std::make_unique(

224 std::move(TSM),

225 MaterializationUnit::Interface(R->getSymbols(),

226 R->getInitializerSymbol()),

227 std::move(Defs), *this))) {

229 R->failMaterialization();

230 return;

231 }

232 return;

233 }

234

235

236

237

238

239

240

241

243 -> Expected {

244 auto PromotedGlobals = PromoteSymbols(M);

245 if (!PromotedGlobals.empty()) {

246

247 MangleAndInterner Mangle(ES, M.getDataLayout());

250 SymbolFlags);

251

252 if (auto Err = R->defineMaterializing(SymbolFlags))

253 return std::move(Err);

254 }

255

256 expandPartition(*GVsToExtract);

257

258

259 std::string SubModuleName;

260 {

261 std::vector<const GlobalValue *> HashGVs;

262 HashGVs.reserve(GVsToExtract->size());

264 llvm::sort(HashGVs, [](const GlobalValue *LHS, const GlobalValue *RHS) {

266 });

267 hash_code HC(0);

268 for (const auto *GV : HashGVs) {

269 assert(GV->hasName() && "All GVs to extract should be named by now");

270 auto GVName = GV->getName();

272 }

273 raw_string_ostream(SubModuleName)

274 << ".submodule."

275 << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",

276 static_cast<size_t>(HC))

277 << ".ll";

278 }

279

280

281

282 auto ShouldExtract = [&](const GlobalValue &GV) -> bool {

283 return GVsToExtract->count(&GV);

284 };

285

287 });

288

289 if (!ExtractedTSM) {

290 ES.reportError(ExtractedTSM.takeError());

291 R->failMaterialization();

292 return;

293 }

294

295 if (auto Err = R->replace(std::make_unique(

297 ES.reportError(std::move(Err));

298 R->failMaterialization();

299 return;

300 }

301 BaseLayer.emit(std::move(R), std::move(*ExtractedTSM));

302}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static ThreadSafeModule extractSubModule(ThreadSafeModule &TSM, StringRef Suffix, GVPredicate ShouldExtract)

Definition IRPartitionLayer.cpp:16

Machine Check Debug Module

This is an important base class in LLVM.

@ ExternalLinkage

Externally visible function.

A Module instance is used to store all the information related to an LLVM module.

StringRef - Represent a constant reference to a string, i.e.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

An ExecutionSession represents a running JIT program.

void reportError(Error Err)

Report a error for this execution session.

IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)

ExecutionSession & getExecutionSession()

Returns the ExecutionSession for this layer.

const IRSymbolMapper::ManglingOptions *& getManglingOptions() const

Get the mangling options for this layer.

SymbolNameToDefinitionMap SymbolToDefinition

IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)

Create an IRMaterializationLayer.

std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap

A layer that breaks up IR modules into smaller submodules that only contains looked up symbols.

std::function< std::optional< GlobalValueSet >(GlobalValueSet Requested)> PartitionFunction

Partitioning function.

void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM) override

Emits the given module.

Definition IRPartitionLayer.cpp:119

static std::optional< GlobalValueSet > compileWholeModule(GlobalValueSet Requested)

Off-the-shelf partitioning which compiles whole modules whenever any symbol in them is requested.

Definition IRPartitionLayer.cpp:115

std::set< const GlobalValue * > GlobalValueSet

IRPartitionLayer(ExecutionSession &ES, IRLayer &BaseLayer)

Construct a IRPartitionLayer.

Definition IRPartitionLayer.cpp:102

void setPartitionFunction(PartitionFunction Partition)

Sets the partition function.

Definition IRPartitionLayer.cpp:105

static std::optional< GlobalValueSet > compileRequested(GlobalValueSet Requested)

Off-the-shelf partitioning which compiles all requested symbols (usually a single function at a time)...

Definition IRPartitionLayer.cpp:110

static LLVM_ABI void add(ExecutionSession &ES, const ManglingOptions &MO, ArrayRef< GlobalValue * > GVs, SymbolFlagsMap &SymbolFlags, SymbolNameToDefinitionMap *SymbolToDefinition=nullptr)

Add mangled symbols for the given GlobalValues to SymbolFlags.

Represents a JIT'd dynamic library.

PartitioningIRMaterializationUnit(ThreadSafeModule TSM, Interface I, SymbolNameToDefinitionMap SymbolToDefinition, IRPartitionLayer &Parent)

Definition IRPartitionLayer.cpp:76

PartitioningIRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, IRPartitionLayer &Parent)

Definition IRPartitionLayer.cpp:70

Pointer to a pooled string representing a symbol name.

An LLVM Module together with a shared ThreadSafeContext.

decltype(auto) withModuleDo(Func &&F)

Locks the associated ThreadSafeContext and calls the given function on the contained Module.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

std::function< bool(const GlobalValue &)> GVPredicate

iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)

Create an iterator range over the GlobalValues that contribute to static initialization.

LLVM_ABI GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)

Clone a global variable declaration into a new module.

LLVM_ABI Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)

Clone a function declaration into a new module.

LLVM_ABI ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())

Clones the given module on to a new context.

DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap

A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.

This is an optimization pass for GlobalISel generic memory operations.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void sort(IteratorTy Start, IteratorTy End)

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

hash_code hash_combine(const Ts &...args)

Combine values into a single hash_code.

hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)

Compute a hash_code for a sequence of values.

Implement std::hash so that hash_code can be used in STL containers.