This commit is contained in:
@@ -414,31 +414,35 @@ size_t PimAcceleratorMemory::getValueAddress(mlir::Value value,
|
||||
const StaticValueKnowledge& knowledge,
|
||||
std::optional<unsigned> lane) const {
|
||||
value = resolveCachedAlias(value, knowledge);
|
||||
auto compiledIt = compiledAddressExprs.find(value);
|
||||
if (compiledIt == compiledAddressExprs.end()) {
|
||||
auto compiledExpr = compileContiguousAddressExpr(value);
|
||||
if (failed(compiledExpr)) {
|
||||
errs() << "Failed to compile contiguous address for value: ";
|
||||
|
||||
FailureOr<ResolvedContiguousAddress> resolvedAddress = resolveContiguousAddress(value, knowledge);
|
||||
if (failed(resolvedAddress)) {
|
||||
auto compiledIt = compiledAddressExprs.find(value);
|
||||
if (compiledIt == compiledAddressExprs.end()) {
|
||||
auto compiledExpr = compileContiguousAddressExpr(value);
|
||||
if (failed(compiledExpr)) {
|
||||
errs() << "Failed to compile contiguous address for value: ";
|
||||
value.print(errs());
|
||||
errs() << " : " << value.getType();
|
||||
errs() << "\n";
|
||||
llvm_unreachable("Failed to compile contiguous address");
|
||||
}
|
||||
compiledIt = compiledAddressExprs.try_emplace(value, *compiledExpr).first;
|
||||
}
|
||||
|
||||
resolvedAddress = compiledIt->second.evaluate(knowledge, lane);
|
||||
if (failed(resolvedAddress)) {
|
||||
errs() << "Failed to evaluate contiguous address for value: ";
|
||||
value.print(errs());
|
||||
errs() << " : " << value.getType();
|
||||
errs() << "\n";
|
||||
llvm_unreachable("Failed to compile contiguous address");
|
||||
if (auto* definingOp = value.getDefiningOp()) {
|
||||
errs() << "Defining op:\n";
|
||||
definingOp->print(errs());
|
||||
errs() << "\n";
|
||||
}
|
||||
llvm_unreachable("Failed to resolve contiguous address");
|
||||
}
|
||||
compiledIt = compiledAddressExprs.try_emplace(value, *compiledExpr).first;
|
||||
}
|
||||
|
||||
auto resolvedAddress = compiledIt->second.evaluate(knowledge, lane);
|
||||
if (failed(resolvedAddress)) {
|
||||
errs() << "Failed to evaluate contiguous address for value: ";
|
||||
value.print(errs());
|
||||
errs() << " : " << value.getType();
|
||||
errs() << "\n";
|
||||
if (auto* definingOp = value.getDefiningOp()) {
|
||||
errs() << "Defining op:\n";
|
||||
definingOp->print(errs());
|
||||
errs() << "\n";
|
||||
}
|
||||
llvm_unreachable("Failed to resolve contiguous address");
|
||||
}
|
||||
|
||||
MemoryValueKey key = getMemoryValueKey(resolvedAddress->base, lane);
|
||||
@@ -1114,7 +1118,8 @@ enum class CompiledCoreOpKind : uint8_t {
|
||||
struct CompiledCoreNode {
|
||||
enum class Kind : uint8_t {
|
||||
Op,
|
||||
Loop
|
||||
Loop,
|
||||
If
|
||||
};
|
||||
|
||||
Kind kind = Kind::Op;
|
||||
@@ -1123,7 +1128,10 @@ struct CompiledCoreNode {
|
||||
CompiledIndexExpr lowerBound;
|
||||
CompiledIndexExpr upperBound;
|
||||
CompiledIndexExpr step;
|
||||
CompiledIndexExpr condition;
|
||||
std::unique_ptr<llvm::SmallVector<CompiledCoreNode, 8>> loopBody;
|
||||
std::unique_ptr<llvm::SmallVector<CompiledCoreNode, 8>> thenBody;
|
||||
std::unique_ptr<llvm::SmallVector<CompiledCoreNode, 8>> elseBody;
|
||||
};
|
||||
|
||||
static FailureOr<CompiledCoreOpKind> classifyCompiledCoreOpKind(Operation& op) {
|
||||
@@ -1201,6 +1209,28 @@ compileCoreEmissionPlan(Block& block, Operation* weightOwner, llvm::SmallVectorI
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto ifOp = dyn_cast<mlir::scf::IfOp>(op)) {
|
||||
auto condition = compileIndexExpr(ifOp.getCondition());
|
||||
if (failed(condition)) {
|
||||
ifOp.emitOpError("requires statically evaluable scf.if condition for PIM codegen");
|
||||
return failure();
|
||||
}
|
||||
|
||||
CompiledCoreNode ifNode;
|
||||
ifNode.kind = CompiledCoreNode::Kind::If;
|
||||
ifNode.op = ifOp.getOperation();
|
||||
ifNode.condition = *condition;
|
||||
ifNode.thenBody = std::make_unique<llvm::SmallVector<CompiledCoreNode, 8>>();
|
||||
if (failed(compileCoreEmissionPlan(ifOp.getThenRegion().front(), weightOwner, *ifNode.thenBody)))
|
||||
return failure();
|
||||
ifNode.elseBody = std::make_unique<llvm::SmallVector<CompiledCoreNode, 8>>();
|
||||
if (!ifOp.getElseRegion().empty())
|
||||
if (failed(compileCoreEmissionPlan(ifOp.getElseRegion().front(), weightOwner, *ifNode.elseBody)))
|
||||
return failure();
|
||||
plan.push_back(std::move(ifNode));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto opKind = classifyCompiledCoreOpKind(op);
|
||||
if (failed(opKind)) {
|
||||
InFlightDiagnostic diag = op.emitError() << "unsupported codegen for op '" << op.getName().getStringRef() << "'";
|
||||
@@ -1263,6 +1293,26 @@ static LogicalResult executeCompiledCorePlan(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node.kind == CompiledCoreNode::Kind::If) {
|
||||
auto condition = node.condition.evaluate(knowledge);
|
||||
auto ifOp = cast<mlir::scf::IfOp>(node.op);
|
||||
if (failed(condition)) {
|
||||
ifOp.emitOpError("requires statically evaluable scf.if condition for PIM codegen");
|
||||
return failure();
|
||||
}
|
||||
|
||||
const auto& selectedBody = *condition != 0 ? node.thenBody : node.elseBody;
|
||||
if (selectedBody && failed(executeCompiledCorePlan(*selectedBody,
|
||||
coreCodeGen,
|
||||
knowledge,
|
||||
resolveWeightSlot,
|
||||
processedOperations,
|
||||
batchLane,
|
||||
batchLaneCount)))
|
||||
return failure();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (node.opKind) {
|
||||
case CompiledCoreOpKind::Load:
|
||||
coreCodeGen.codeGenLoadOp(cast<pim::PimMemCopyHostToDevOp>(node.op), knowledge);
|
||||
|
||||
Reference in New Issue
Block a user