[EmitC] Cache values instead of operations (#18507)
This changes the lookup table for local `iree_vm_ref_t*` variables to
work directly on the value instead of the operation defining it.
Signed-off-by: Simon Camphausen <simon.camphausen@iml.fraunhofer.de>
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp
index c57802d..24fb391 100644
--- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp
+++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp
@@ -125,12 +125,10 @@
auto [ref, refPtr] = emitc_builders::allocZeroInitializedVar(
builder, loc, emitc::OpaqueType::get(ctx, "iree_vm_ref_t"));
- auto refPtrOp = cast<emitc::ApplyOp>(refPtr.getDefiningOp());
-
// Cache local refs so that we can release them before a return operation.
// Here we rely on the fact that the register allocation maps arguments in
// the first slots.
- funcAnalysis.cacheLocalRef(i + numRefArgs, refPtrOp);
+ funcAnalysis.cacheLocalRef(i + numRefArgs, refPtr);
}
for (Block &block : llvm::drop_begin(newFuncOp.getBlocks(), 1)) {
@@ -332,13 +330,7 @@
if (funcAnalysis.hasLocalRefs()) {
- for (auto pair : funcAnalysis.localRefs()) {
- Operation *op = pair.second;
-
- assert(isa<emitc::ApplyOp>(op));
-
- Value localRef = cast<emitc::ApplyOp>(op).getResult();
-
+ for (auto &[key, localRef] : funcAnalysis.localRefs()) {
emitc_builders::ireeVmRefRelease(builder, location, localRef);
}
}
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/VMAnalysis.h b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/VMAnalysis.h
index f5ebb30..cbfcc92 100644
--- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/VMAnalysis.h
+++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/VMAnalysis.h
@@ -33,7 +33,7 @@
valueLiveness = ValueLiveness(op);
originalFunctionType = funcOp.getFunctionType();
callingConvention = makeCallingConventionString(funcOp).value();
- refs = DenseMap<int64_t, Operation *>{};
+ refs = DenseMap<int64_t, Value>{};
}
FuncAnalysis(mlir::emitc::FuncOp funcOp) {
originalFunctionType = funcOp.getFunctionType();
@@ -101,22 +101,21 @@
return lastUse && false;
}
- void cacheLocalRef(int64_t ordinal, emitc::ApplyOp applyOp) {
+ void cacheLocalRef(int64_t ordinal, Value ref) {
assert(refs.has_value());
assert(!refs.value().count(ordinal) && "ref was already cached");
- refs.value()[ordinal] = applyOp.getOperation();
+ refs.value()[ordinal] = ref;
}
- emitc::ApplyOp lookupLocalRef(int64_t ordinal) {
+ Value lookupLocalRef(int64_t ordinal) {
assert(refs.has_value());
assert(refs.value().count(ordinal) && "ref not found in cache");
- Operation *op = refs.value()[ordinal];
- return cast<emitc::ApplyOp>(op);
+ return refs.value()[ordinal];
}
bool hasLocalRefs() { return refs.has_value(); }
- DenseMap<int64_t, Operation *> &localRefs() {
+ DenseMap<int64_t, Value> &localRefs() {
assert(refs.has_value());
return refs.value();
}
@@ -124,7 +123,7 @@
private:
std::optional<RegisterAllocation> registerAllocation;
std::optional<ValueLiveness> valueLiveness;
- std::optional<DenseMap<int64_t, Operation *>> refs;
+ std::optional<DenseMap<int64_t, Value>> refs;
std::optional<FunctionType> originalFunctionType;
std::optional<std::string> callingConvention;
std::optional<std::string> exportName;
@@ -233,8 +232,7 @@
}
}
- emitc::ApplyOp applyOp = analysis.lookupLocalRef(ordinal);
- return applyOp.getResult();
+ return analysis.lookupLocalRef(ordinal);
}
std::vector<TypeDef> typeTable;