diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index c04f1954ce1e4..966f44a8316f1 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -723,13 +723,18 @@ static inline bool verify_partitioning(const SmallVectorImpl &partiti gvars[gvar.second] = i+1; } } - for (auto &GV : M.globals()) { + for (auto &GV : M.global_values()) { if (GV.isDeclaration()) { if (GVNames.count(GV.getName())) { bad = true; dbgs() << "Global " << GV.getName() << " is a declaration but is in partition " << GVNames[GV.getName()] << "\n"; } } else { + if (auto F = dyn_cast(&GV)) { + // Ignore alwaysinline functions + if (F->hasFnAttribute(Attribute::AlwaysInline)) + continue; + } if (!GVNames.count(GV.getName())) { bad = true; dbgs() << "Global " << GV << " not in any partition\n"; @@ -809,8 +814,12 @@ static SmallVector partitionModule(Module &M, unsigned threads) { for (auto &G : M.global_values()) { if (G.isDeclaration()) continue; - if (isa(G)) { - partitioner.make(&G, getFunctionWeight(cast(G)).weight); + if (auto F = dyn_cast(&G)) { + // alwaysinline functions cannot be partitioned, + // they must remain in every module in order to be inlined + if (F->hasFnAttribute(Attribute::AlwaysInline)) + continue; + partitioner.make(&G, getFunctionWeight(*F).weight); } else { partitioner.make(&G, 1); } @@ -1109,6 +1118,12 @@ static void materializePreserved(Module &M, Partition &partition) { for (auto &F : M.functions()) { if (!F.isDeclaration()) { if (!Preserve.contains(&F)) { + if (F.hasFnAttribute(Attribute::AlwaysInline)) { + F.setLinkage(GlobalValue::InternalLinkage); + F.setVisibility(GlobalValue::DefaultVisibility); + F.setDSOLocal(true); + continue; + } F.deleteBody(); F.setLinkage(GlobalValue::ExternalLinkage); F.setVisibility(GlobalValue::HiddenVisibility);