================ @@ -456,3 +463,170 @@ declare void @_ZN5Base35func3Ev(ptr) // 1 call instruction from the entry block. EXPECT_EQ(F->front().size(), OrigEntryBBSize + 4); } + +using namespace llvm::ctx_profile; + +class ContextManager final { + std::vector<std::unique_ptr<char[]>> Nodes; + std::map<GUID, const ContextNode *> Roots; + +public: + ContextNode *createNode(GUID Guid, uint32_t NrCounters, uint32_t NrCallsites, + ContextNode *Next = nullptr) { + auto AllocSize = ContextNode::getAllocSize(NrCounters, NrCallsites); + auto *Mem = Nodes.emplace_back(std::make_unique<char[]>(AllocSize)).get(); + std::memset(Mem, 0, AllocSize); + auto *Ret = new (Mem) ContextNode(Guid, NrCounters, NrCallsites, Next); + return Ret; + } +}; + +TEST(CallPromotionUtilsTest, PromoteWithIcmpAndCtxProf) { + LLVMContext C; + std::unique_ptr<Module> M = parseIR(C, + R"IR( +define i32 @testfunc1(ptr %d) !guid !0 { + call void @llvm.instrprof.increment(ptr null, i64 0, i32 1, i32 0) + call void @llvm.instrprof.callsite(ptr null, i64 0, i32 1, i32 0, ptr %d) + %call = call i32 %d() + ret i32 %call +} + +define i32 @f1() !guid !1 { + call void @llvm.instrprof.increment(ptr null, i64 0, i32 1, i32 0) + ret i32 2 +} + +define i32 @f2() !guid !2 { + call void @llvm.instrprof.increment(ptr null, i64 0, i32 1, i32 0) + call void @llvm.instrprof.callsite(ptr null, i64 0, i32 1, i32 0, ptr @f4) + %r = call i32 @f4() + ret i32 %r +} + +define i32 @testfunc2(ptr %p) !guid !4 { + call void @llvm.instrprof.increment(ptr null, i64 0, i32 1, i32 0) + call void @llvm.instrprof.callsite(ptr null, i64 0, i32 1, i32 0, ptr @testfunc1) + %r = call i32 @testfunc1(ptr %p) + ret i32 %r +} + +declare i32 @f3() + +define i32 @f4() !guid !3 { + ret i32 3 +} + +!0 = !{i64 1000} +!1 = !{i64 1001} +!2 = !{i64 1002} +!3 = !{i64 1004} +!4 = !{i64 1005} +)IR"); + + const char *Profile = R"( + [ + { + "Guid": 1000, + "Counters": [1], + "Callsites": [ + [{ "Guid": 1001, + "Counters": [10]}, + { "Guid": 1002, + "Counters": [11], + "Callsites": [[{"Guid": 1004, "Counters":[13]}]] + }, + { "Guid": 1003, + "Counters": [12] + }]] + }, + { + "Guid": 1005, + "Counters": [2], + "Callsites": [ + [{ "Guid": 1000, + "Counters": [1], + "Callsites": [ + [{ "Guid": 1001, + "Counters": [101]}, + { "Guid": 1002, + "Counters": [102], + "Callsites": [[{"Guid": 1004, "Counters":[104]}]] + }, + { "Guid": 1003, + "Counters": [103] + }]]}]]}] + )"; + + llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true); + { + std::error_code EC; + raw_fd_stream Out(ProfileFile.path(), EC); + ASSERT_FALSE(EC); + // "False" means no error. + ASSERT_FALSE(llvm::createCtxProfFromJSON(Profile, Out)); + } + + ModuleAnalysisManager MAM; + MAM.registerPass([&]() { return CtxProfAnalysis(ProfileFile.path()); }); + MAM.registerPass([&]() { return PassInstrumentationAnalysis(); }); + auto &CtxProf = MAM.getResult<CtxProfAnalysis>(*M); + auto *Caller = M->getFunction("testfunc1"); + ASSERT_TRUE(!!Caller); ---------------- snehasish wrote:
`getFunction` returns Function* or nullptr. Why do you need `!!` here? Can this be `ASSERT_NE(Caller, nullptr);`? Same for similar usage below. https://github.com/llvm/llvm-project/pull/105469 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits