Skip to content

Commit 0818e89

Browse files
committed
Convert control point pass to new pass manager.
The pass previously used the legacy pass manager, since that was default in LLVM 12. In LLVM 13 the new pass manager is default. This change converts the control point pass from a legacy pass to a new pass.
1 parent 619b06e commit 0818e89

File tree

8 files changed

+101
-112
lines changed

8 files changed

+101
-112
lines changed

llvm/include/llvm/Transforms/Yk/ControlPoint.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
#define YK_NEW_CONTROL_POINT "yk_new_control_point"
1212

1313
namespace llvm {
14-
class ModulePass;
15-
ModulePass *createYkControlPointPass();
14+
class YkControlPointPass : public PassInfoMixin<YkControlPointPass> {
15+
public:
16+
explicit YkControlPointPass();
17+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
18+
};
1619
} // namespace llvm
1720

1821
#endif

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ add_llvm_component_library(LLVMCodeGen
216216
Support
217217
Target
218218
TransformUtils
219-
YkControlPoint
220219
)
221220

222221
add_subdirectory(SelectionDAG)

llvm/lib/LTO/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ add_llvm_component_library(LLVMLTO
3535
Support
3636
Target
3737
TransformUtils
38+
YkControlPoint
3839
)

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Transforms/Scalar/LoopPassManager.h"
4747
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
4848
#include "llvm/Transforms/Utils/SplitModule.h"
49+
#include "llvm/Transforms/Yk/ControlPoint.h"
4950

5051
using namespace llvm;
5152
using namespace lto;
@@ -74,6 +75,11 @@ static cl::opt<bool> ThinLTOAssumeMerged(
7475
cl::desc("Assume the input has already undergone ThinLTO function "
7576
"importing and the other pre-optimization pipeline changes."));
7677

78+
static cl::opt<bool>
79+
YkPatchCtrlPoint("yk-patch-control-point",
80+
cl::init(false), cl::NotHidden,
81+
cl::desc("Patch yk_control_point()"));
82+
7783
LLVM_ATTRIBUTE_NORETURN static void reportOpenError(StringRef Path, Twine Msg) {
7884
errs() << "failed to open " << Path << ": " << Msg << '\n';
7985
errs().flush();
@@ -300,6 +306,13 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
300306
MPM.addPass(PB.buildLTODefaultPipeline(OL, ExportSummary));
301307
}
302308

309+
// We add the yk control point pass late in the pipeline (after all
310+
// optimisation and just before verification and codegen) so that no IR
311+
// optimisation passes have a chance to change the interface to the control
312+
// point. The JIT runtime relies on the signature not being changed.
313+
if (YkPatchCtrlPoint)
314+
MPM.addPass(YkControlPointPass());
315+
303316
if (!Conf.DisableVerify)
304317
MPM.addPass(VerifierPass());
305318

llvm/lib/Transforms/IPO/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,4 @@ add_llvm_component_library(LLVMipo
7171
TransformUtils
7272
Vectorize
7373
Instrumentation
74-
YkControlPoint
7574
)

llvm/lib/Transforms/IPO/PassManagerBuilder.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
#include "llvm/Transforms/Vectorize/LoopVectorize.h"
5252
#include "llvm/Transforms/Vectorize/SLPVectorizer.h"
5353
#include "llvm/Transforms/Vectorize/VectorCombine.h"
54-
#include "llvm/Transforms/Yk/ControlPoint.h"
5554

5655
using namespace llvm;
5756

@@ -189,11 +188,6 @@ cl::opt<AttributorRunOption> AttributorRun(
189188
clEnumValN(AttributorRunOption::NONE, "none",
190189
"disable attributor runs")));
191190

192-
static cl::opt<bool>
193-
YkPatchCtrlPoint("yk-patch-control-point",
194-
cl::init(false), cl::NotHidden,
195-
cl::desc("Patch yk_control_point()"));
196-
197191
extern cl::opt<bool> EnableKnowledgeRetention;
198192
} // namespace llvm
199193

@@ -1246,13 +1240,6 @@ void PassManagerBuilder::populateLTOPassManager(legacy::PassManagerBase &PM) {
12461240

12471241
PM.add(createAnnotationRemarksLegacyPass());
12481242

1249-
// We add the yk control point pass late in the pipeline (after all
1250-
// optimisation and just before verification and codegen) so that no IR
1251-
// optimisation passes have a chance to change the interface to the control
1252-
// point. The JIT runtime relies on the signature not being changed.
1253-
if (YkPatchCtrlPoint)
1254-
PM.add(createYkControlPointPass());
1255-
12561243
if (VerifyOutput)
12571244
PM.add(createVerifierPass());
12581245
}

llvm/lib/Transforms/Yk/ControlPoint.cpp

Lines changed: 81 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,15 @@ void createControlPoint(Module &Mod, Function *F, std::vector<Value *> LiveVars,
169169
(GlobalVariable *)nullptr);
170170

171171
// Create control point entry block. Checks if we are currently tracing.
172-
Value *GVTracingVal = Builder.CreateLoad(GVTracing);
172+
Value *GVTracingVal = Builder.CreateLoad(Type::getInt8Ty(Context), GVTracing);
173173
Value *IsTracing =
174174
Builder.CreateICmp(CmpInst::Predicate::ICMP_EQ, GVTracingVal, Int0);
175175
Builder.CreateCondBr(IsTracing, BBNotTracing, BBTracing);
176176

177177
// Create block for "not tracing" case. Checks if we already compiled a trace.
178178
Builder.SetInsertPoint(BBNotTracing);
179-
Value *GVCompiledTraceVal = Builder.CreateLoad(GVCompiledTrace);
179+
Value *GVCompiledTraceVal =
180+
Builder.CreateLoad(Type::getInt8PtrTy(Context), GVCompiledTrace);
180181
Value *HasTrace = Builder.CreateICmp(CmpInst::Predicate::ICMP_EQ,
181182
GVCompiledTraceVal, PtNull);
182183
Builder.CreateCondBr(HasTrace, BBHasNoTrace, BBHasTrace);
@@ -193,7 +194,8 @@ void createControlPoint(Module &Mod, Function *F, std::vector<Value *> LiveVars,
193194
// Create block that checks if we've reached the same location again so we
194195
// can execute a compiled trace.
195196
Builder.SetInsertPoint(BBHasTrace);
196-
Value *ValStartLoc = Builder.CreateLoad(GVStartLoc);
197+
Value *ValStartLoc =
198+
Builder.CreateLoad(Type::getInt32Ty(Context), GVStartLoc);
197199
Value *ExecTraceCond = Builder.CreateICmp(CmpInst::Predicate::ICMP_EQ,
198200
ValStartLoc, F->getArg(0));
199201
Builder.CreateCondBr(ExecTraceCond, BBExecuteTrace, BBReturn);
@@ -216,7 +218,8 @@ void createControlPoint(Module &Mod, Function *F, std::vector<Value *> LiveVars,
216218

217219
// Create block that decides when to stop tracing.
218220
Builder.SetInsertPoint(BBTracing);
219-
Value *ValStartLoc2 = Builder.CreateLoad(GVStartLoc);
221+
Value *ValStartLoc2 =
222+
Builder.CreateLoad(Type::getInt32Ty(Context), GVStartLoc);
220223
Value *StopTracingCond = Builder.CreateICmp(CmpInst::Predicate::ICMP_EQ,
221224
ValStartLoc2, F->getArg(0));
222225
Builder.CreateCondBr(StopTracingCond, BBStopTracing, BBReturn);
@@ -264,102 +267,86 @@ std::vector<Value *> getLiveVars(DominatorTree &DT, CallInst *OldCtrlPoint) {
264267
return Vec;
265268
}
266269

267-
namespace {
268-
struct YkControlPointPass : public ModulePass {
269-
static char ID;
270+
YkControlPointPass::YkControlPointPass() {}
270271

271-
YkControlPointPass() : ModulePass(ID) {}
272+
PreservedAnalyses YkControlPointPass::run(Module &M,
273+
ModuleAnalysisManager &AM) {
274+
LLVMContext &Context = M.getContext();
272275

273-
StringRef getPassName() const override {
274-
return "Control Point Patching Pass";
276+
// Locate the "dummy" control point provided by the user.
277+
CallInst *OldCtrlPointCall = findControlPointCall(M);
278+
if (OldCtrlPointCall == nullptr) {
279+
Context.emitError("ykllvm couldn't find the call to `yk_control_point()`");
280+
return PreservedAnalyses::all();
275281
}
276282

277-
bool runOnModule(Module &M) override {
278-
LLVMContext &Context = M.getContext();
279-
280-
// Locate the "dummy" control point provided by the user.
281-
CallInst *OldCtrlPointCall = findControlPointCall(M);
282-
if (OldCtrlPointCall == nullptr) {
283-
Context.emitError(
284-
"ykllvm couldn't find the call to `yk_control_point()`");
285-
return false;
286-
}
287-
288-
// Replace old control point call.
289-
IRBuilder<> Builder(OldCtrlPointCall);
290-
291-
// Get function containing the control point.
292-
Function *Caller = OldCtrlPointCall->getFunction();
293-
294-
// Find all live variables just before the call to the control point.
295-
DominatorTree DT(*Caller);
296-
std::vector<Value *> LiveVals = getLiveVars(DT, OldCtrlPointCall);
297-
if (LiveVals.size() == 0) {
298-
Context.emitError(
299-
"The interpreter loop has no live variables!\n"
300-
"ykllvm doesn't support this scenario, as such an interpreter would "
301-
"make little sense.");
302-
return false;
303-
}
304-
305-
// Generate the YkCtrlPointVars struct. This struct is used to package up a
306-
// copy of all LLVM variables that are live just before the call to the
307-
// control point. These are passed in to the patched control point so that
308-
// they can be used as inputs and outputs to JITted trace code. The control
309-
// point returns a new YkCtrlPointVars whose members may have been mutated
310-
// by JITted trace code (if a trace was executed).
311-
std::vector<Type *> TypeParams;
312-
for (Value *V : LiveVals) {
313-
TypeParams.push_back(V->getType());
314-
}
315-
StructType *CtrlPointReturnTy =
316-
StructType::create(TypeParams, "YkCtrlPointVars");
317-
318-
// Create the new control point.
319-
FunctionType *FType = FunctionType::get(
320-
CtrlPointReturnTy, {Type::getInt32Ty(Context), CtrlPointReturnTy},
321-
false);
322-
Function *NF = Function::Create(FType, GlobalVariable::ExternalLinkage,
323-
YK_NEW_CONTROL_POINT, M);
324-
325-
// Instantiate the YkCtrlPointStruct to pass in to the control point.
326-
Value *InputStruct = cast<Value>(Constant::getNullValue(CtrlPointReturnTy));
327-
unsigned LvIdx = 0;
328-
for (Value *LV : LiveVals) {
329-
InputStruct = Builder.CreateInsertValue(InputStruct, LV, LvIdx);
330-
assert(LvIdx != UINT_MAX);
331-
LvIdx++;
332-
}
283+
// Replace old control point call.
284+
IRBuilder<> Builder(OldCtrlPointCall);
285+
286+
// Get function containing the control point.
287+
Function *Caller = OldCtrlPointCall->getFunction();
288+
289+
// Find all live variables just before the call to the control point.
290+
DominatorTree DT(*Caller);
291+
std::vector<Value *> LiveVals = getLiveVars(DT, OldCtrlPointCall);
292+
if (LiveVals.size() == 0) {
293+
Context.emitError(
294+
"The interpreter loop has no live variables!\n"
295+
"ykllvm doesn't support this scenario, as such an interpreter would "
296+
"make little sense.");
297+
return PreservedAnalyses::all();
298+
}
333299

334-
// Insert call to the new control point.
335-
CallInst *CtrlPointRet = Builder.CreateCall(
336-
NF, {OldCtrlPointCall->getArgOperand(0), InputStruct});
337-
338-
// Once the control point returns we need to extract the (potentially
339-
// mutated) values from the returned YkCtrlPointStruct and reassign them to
340-
// their corresponding live variables. In LLVM IR we can do this by simply
341-
// replacing all future references with the new values.
342-
LvIdx = 0;
343-
for (Value *LV : LiveVals) {
344-
Value *New = Builder.CreateExtractValue(cast<Value>(CtrlPointRet), LvIdx);
345-
LV->replaceUsesWithIf(
346-
New, [&](Use &U) { return DT.dominates(CtrlPointRet, U); });
347-
assert(LvIdx != UINT_MAX);
348-
LvIdx++;
349-
}
300+
// Generate the YkCtrlPointVars struct. This struct is used to package up a
301+
// copy of all LLVM variables that are live just before the call to the
302+
// control point. These are passed in to the patched control point so that
303+
// they can be used as inputs and outputs to JITted trace code. The control
304+
// point returns a new YkCtrlPointVars whose members may have been mutated
305+
// by JITted trace code (if a trace was executed).
306+
std::vector<Type *> TypeParams;
307+
for (Value *V : LiveVals) {
308+
TypeParams.push_back(V->getType());
309+
}
310+
StructType *CtrlPointReturnTy =
311+
StructType::create(TypeParams, "YkCtrlPointVars");
312+
313+
// Create the new control point.
314+
FunctionType *FType = FunctionType::get(
315+
CtrlPointReturnTy, {Type::getInt32Ty(Context), CtrlPointReturnTy}, false);
316+
Function *NF = Function::Create(FType, GlobalVariable::ExternalLinkage,
317+
YK_NEW_CONTROL_POINT, M);
318+
319+
// Instantiate the YkCtrlPointStruct to pass in to the control point.
320+
Value *InputStruct = cast<Value>(Constant::getNullValue(CtrlPointReturnTy));
321+
unsigned LvIdx = 0;
322+
for (Value *LV : LiveVals) {
323+
InputStruct = Builder.CreateInsertValue(InputStruct, LV, LvIdx);
324+
assert(LvIdx != UINT_MAX);
325+
LvIdx++;
326+
}
350327

351-
// Replace the call to the dummy control point.
352-
OldCtrlPointCall->eraseFromParent();
328+
// Insert call to the new control point.
329+
CallInst *CtrlPointRet =
330+
Builder.CreateCall(NF, {OldCtrlPointCall->getArgOperand(0), InputStruct});
331+
332+
// Once the control point returns we need to extract the (potentially
333+
// mutated) values from the returned YkCtrlPointStruct and reassign them to
334+
// their corresponding live variables. In LLVM IR we can do this by simply
335+
// replacing all future references with the new values.
336+
LvIdx = 0;
337+
for (Value *LV : LiveVals) {
338+
Value *New = Builder.CreateExtractValue(cast<Value>(CtrlPointRet), LvIdx);
339+
LV->replaceUsesWithIf(
340+
New, [&](Use &U) { return DT.dominates(CtrlPointRet, U); });
341+
assert(LvIdx != UINT_MAX);
342+
LvIdx++;
343+
}
353344

354-
// Generate new control point logic.
355-
createControlPoint(M, NF, LiveVals, CtrlPointReturnTy);
345+
// Replace the call to the dummy control point.
346+
OldCtrlPointCall->eraseFromParent();
356347

357-
return true;
358-
}
359-
};
360-
char YkControlPointPass::ID = 0;
361-
} // namespace
348+
// Generate new control point logic.
349+
createControlPoint(M, NF, LiveVals, CtrlPointReturnTy);
362350

363-
namespace llvm {
364-
ModulePass *createYkControlPointPass() { return new YkControlPointPass(); }
365-
} // namespace llvm
351+
return PreservedAnalyses::none();
352+
}

yk_format_new_files.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Format any new files that we have added in our fork.
44

55
# The LLVM version tag we are forked from.
6-
FORKED_LLVM_VERSION=llvmorg-12.0.0
6+
FORKED_LLVM_VERSION=llvmorg-13.0.0
77

88
git diff --name-only --diff-filter=A ${FORKED_LLVM_VERSION} \
99
`git branch --show-current` | egrep '\.(cpp|h)$' | xargs clang-format -i

0 commit comments

Comments
 (0)