Skip to content

Commit 5848ae4

Browse files
doru1004cursoragent
authored andcommitted
Change vector interleaving to 8 (#8)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2e2b43b commit 5848ae4

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

quadrants/runtime/amdgpu/jit_amdgpu.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ std::string JITSessionAMDGPU::compile_module_to_hsaco(std::unique_ptr<llvm::Modu
142142
pb.registerLoopAnalyses(lam);
143143
pb.crossRegisterProxies(lam, fam, cgam, mam);
144144

145+
// Annotate innermost loops with interleave-count=8 via IR metadata so the
146+
// LLVM loop vectorizer uses it. This is scoped to this compilation pipeline
147+
// and avoids mutating process-wide command-line state.
148+
pb.registerLoopOptimizerEndEPCallback(
149+
[](llvm::LoopPassManager &lpm, llvm::OptimizationLevel) {
150+
lpm.addPass(AMDGPUSetLoopInterleavePass(8));
151+
});
152+
145153
llvm::ModulePassManager mpm = pb.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3);
146154

147155
// Run the new optimization pipeline

quadrants/runtime/llvm/llvm_context_pass.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
#include "llvm/Transforms/IPO.h"
99
#include "llvm/IR/Instructions.h"
1010
#include "llvm/IR/IRBuilder.h"
11+
#include "llvm/IR/Metadata.h"
1112
#include "llvm/Support/SourceMgr.h"
1213
#include "llvm/Transforms/Utils/ValueMapper.h"
1314
#include "llvm/Transforms/Utils/Cloning.h"
15+
#include "llvm/Analysis/LoopInfo.h"
16+
#include "llvm/Transforms/Scalar/LoopPassManager.h"
1417

1518
#if defined(QD_WITH_AMDGPU)
1619
#include "quadrants/rhi/amdgpu/amdgpu_context.h"
@@ -295,5 +298,63 @@ struct AMDGPUConvertFuncParamAddressSpacePass : public ModulePass {
295298

296299
#endif
297300

301+
// New-PM loop pass: annotates innermost loops with llvm.loop.interleave.count
302+
// IR metadata so the loop vectorizer uses the requested interleave factor.
303+
// Scoped to the compilation pipeline where it is registered; does not touch
304+
// any process-wide LLVM command-line state.
305+
struct AMDGPUSetLoopInterleavePass
306+
: public llvm::PassInfoMixin<AMDGPUSetLoopInterleavePass> {
307+
unsigned count_;
308+
explicit AMDGPUSetLoopInterleavePass(unsigned count) : count_(count) {}
309+
310+
llvm::PreservedAnalyses run(llvm::Loop &L,
311+
llvm::LoopAnalysisManager &,
312+
llvm::LoopStandardAnalysisResults &,
313+
llvm::LPMUpdater &) {
314+
// Only annotate innermost loops
315+
if (!L.getSubLoops().empty())
316+
return llvm::PreservedAnalyses::all();
317+
318+
llvm::LLVMContext &ctx = L.getHeader()->getContext();
319+
llvm::MDNode *existing_id = L.getLoopID();
320+
321+
// Skip if interleave count is already specified
322+
if (existing_id) {
323+
for (unsigned i = 1, e = existing_id->getNumOperands(); i < e; ++i) {
324+
if (auto *node = llvm::dyn_cast<llvm::MDNode>(existing_id->getOperand(i))) {
325+
if (node->getNumOperands() > 0) {
326+
if (auto *s = llvm::dyn_cast<llvm::MDString>(node->getOperand(0))) {
327+
if (s->getString() == "llvm.loop.interleave.count")
328+
return llvm::PreservedAnalyses::all();
329+
}
330+
}
331+
}
332+
}
333+
}
334+
335+
// Build new interleave hint node
336+
llvm::MDNode *hint = llvm::MDNode::get(ctx, {
337+
llvm::MDString::get(ctx, "llvm.loop.interleave.count"),
338+
llvm::ConstantAsMetadata::get(
339+
llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), count_))
340+
});
341+
342+
// Assemble updated loop metadata: [self-ref, ...existing..., hint]
343+
llvm::SmallVector<llvm::Metadata *, 4> ops;
344+
ops.push_back(nullptr); // placeholder for self-reference
345+
if (existing_id) {
346+
for (unsigned i = 1, e = existing_id->getNumOperands(); i < e; ++i)
347+
ops.push_back(existing_id->getOperand(i).get());
348+
}
349+
ops.push_back(hint);
350+
351+
llvm::MDNode *new_id = llvm::MDNode::get(ctx, ops);
352+
new_id->replaceOperandWith(0, new_id); // fix self-reference
353+
L.setLoopID(new_id);
354+
355+
return llvm::PreservedAnalyses::none();
356+
}
357+
};
358+
298359
} // namespace lang
299360
} // namespace quadrants

0 commit comments

Comments
 (0)