Skip to content

Commit d33142e

Browse files
[HWToLLVM][ArcToLLVM] Spill array values early (#9218)
Spill hw.array values on the stack at their definition site instead of their use sites to reduce the number of redundant alloca + store ops created.
1 parent 2c70b88 commit d33142e

File tree

7 files changed

+389
-71
lines changed

7 files changed

+389
-71
lines changed

include/circt/Conversion/HWToLLVM.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,46 @@ struct HWToLLVMEndianessConverter {
4242
StringRef fieldName);
4343
};
4444

45+
/// Helper class mapping array values (HW or LLVM Dialect) to pointers to
46+
/// buffers containing the array value.
47+
struct HWToLLVMArraySpillCache {
48+
/// Spill HW array values produced by 'foreign' dialects on the stack.
49+
/// The converter is used to map HW array types to the corresponding
50+
/// LLVM array types. Should be called before dialect conversion.
51+
void spillNonHWOps(mlir::OpBuilder &builder,
52+
mlir::LLVMTypeConverter &converter,
53+
Operation *containerOp);
54+
55+
/// Map an LLVM array value to an LLVM pointer.
56+
/// For the entire lifetime of the array value the pointer must
57+
/// refer to a valid buffer containing the respective array value.
58+
void map(mlir::Value arrayValue, mlir::Value bufferPtr);
59+
60+
/// Retrieve a pointer to a buffer containing the given array
61+
/// value (HW or LLVM Dialect). The buffer must not be modified or
62+
/// deallocated. Returns a null value if no buffer has been mapped.
63+
Value lookup(Value arrayValue);
64+
65+
private:
66+
Value spillLLVMArrayValue(OpBuilder &builder, Location loc, Value llvmArray);
67+
Value spillHWArrayValue(OpBuilder &builder, Location loc,
68+
mlir::LLVMTypeConverter &converter, Value hwArray);
69+
70+
llvm::DenseMap<Value, Value> spillMap;
71+
};
72+
4573
/// Get the HW to LLVM type conversions.
4674
void populateHWToLLVMTypeConversions(mlir::LLVMTypeConverter &converter);
4775

4876
/// Get the HW to LLVM conversion patterns.
77+
/// Note: The spill cache may only be used when conversion
78+
/// pattern rollback is disabled.
4979
void populateHWToLLVMConversionPatterns(
5080
mlir::LLVMTypeConverter &converter, RewritePatternSet &patterns,
5181
Namespace &globals,
5282
DenseMap<std::pair<Type, ArrayAttr>, mlir::LLVM::GlobalOp>
53-
&constAggregateGlobalsMap);
54-
55-
/// Create an HW to LLVM conversion pass.
56-
std::unique_ptr<OperationPass<ModuleOp>> createConvertHWToLLVMPass();
83+
&constAggregateGlobalsMap,
84+
std::optional<HWToLLVMArraySpillCache> &spillCacheOpt);
5785

5886
} // namespace circt
5987

include/circt/Conversion/Passes.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,11 @@ def ConvertHWToLLVM : Pass<"convert-hw-to-llvm", "mlir::ModuleOp"> {
509509
let description = [{
510510
This pass translates HW to LLVM.
511511
}];
512-
let constructor = "circt::createConvertHWToLLVMPass()";
512+
let options = [
513+
Option<"spillArraysEarly", "spill-arrays-early", "bool", "true",
514+
"If true, array values will be materialized on the stack at the"
515+
"point of definition. This can reduce redundant stack allocations.">
516+
];
513517
let dependentDialects = ["mlir::LLVM::LLVMDialect"];
514518
}
515519

lib/Conversion/ArcToLLVM/LowerArcToLLVM.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,16 @@ void LowerArcToLLVMPass::runOnOperation() {
760760

761761
// CIRCT patterns.
762762
DenseMap<std::pair<Type, ArrayAttr>, LLVM::GlobalOp> constAggregateGlobalsMap;
763-
populateHWToLLVMConversionPatterns(converter, patterns, globals,
764-
constAggregateGlobalsMap);
765763
populateHWToLLVMTypeConversions(converter);
764+
std::optional<HWToLLVMArraySpillCache> spillCacheOpt =
765+
HWToLLVMArraySpillCache();
766+
{
767+
OpBuilder spillBuilder(getOperation());
768+
spillCacheOpt->spillNonHWOps(spillBuilder, converter, getOperation());
769+
}
770+
populateHWToLLVMConversionPatterns(converter, patterns, globals,
771+
constAggregateGlobalsMap, spillCacheOpt);
772+
766773
populateCombToArithConversionPatterns(converter, patterns);
767774
populateCombToLLVMConversionPatterns(converter, patterns);
768775

0 commit comments

Comments
 (0)