Skip to content

Commit

Permalink
scf index switch to if-else
Browse files Browse the repository at this point in the history
  • Loading branch information
jiahanxie353 committed Oct 6, 2024
1 parent 09f07f5 commit dfc0671
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions lib/Conversion/SCFToCalyx/SCFToCalyx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,70 @@ class BuildIfGroups : public calyx::FuncOpPartialLoweringPattern {
}
};

class BuildSwitchGroups : public calyx::FuncOpPartialLoweringPattern {
using FuncOpPartialLoweringPattern::FuncOpPartialLoweringPattern;

LogicalResult
partiallyLowerFuncToComp(FuncOp funcOp,
PatternRewriter &rewriter) const override {
LogicalResult res = success();
funcOp.walk([&](Operation *op) {
if (!isa<scf::IndexSwitchOp>(op))
return WalkResult::advance();

auto switchOp = cast<scf::IndexSwitchOp>(op);
auto loc = switchOp.getLoc();

Region &defaultRegion = switchOp.getDefaultRegion();
Operation *yieldOp = defaultRegion.front().getTerminator();
Value defaultResult = yieldOp->getOperand(0);

Value finalResult = defaultResult;
scf::IfOp prevIfOp = nullptr;

rewriter.setInsertionPointAfter(switchOp);
for (size_t i = 0; i < switchOp.getCases().size(); i++) {
auto caseValueInt = switchOp.getCases()[i];
if (prevIfOp)
rewriter.setInsertionPointToStart(&prevIfOp.getElseRegion().front());

Value caseValue = rewriter.create<ConstantIndexOp>(loc, caseValueInt);
Value cond = rewriter.create<CmpIOp>(
loc, CmpIPredicate::eq, *switchOp.getODSOperands(0).begin(),
caseValue);

auto ifOp = rewriter.create<scf::IfOp>(loc, switchOp.getResultTypes(),
cond, /*hasElseRegion=*/true);

Region &caseRegion = switchOp.getCaseRegions()[i];
IRMapping mapping;
Block &emptyThenBlock = ifOp.getThenRegion().front();
emptyThenBlock.erase();
caseRegion.cloneInto(&ifOp.getThenRegion(), mapping);

if (i == switchOp.getCases().size() - 1) {
rewriter.setInsertionPointToEnd(&ifOp.getElseRegion().front());
rewriter.create<scf::YieldOp>(loc, defaultResult);
}

if (prevIfOp) {
rewriter.setInsertionPointToEnd(&prevIfOp.getElseRegion().front());
rewriter.create<scf::YieldOp>(loc, ifOp.getResult(0));
}

if (i == 0)
finalResult = ifOp.getResult(0);
prevIfOp = ifOp;
}

rewriter.replaceOp(switchOp, finalResult);

return WalkResult::advance();
});
return res;
}
};

/// Builds a control schedule by traversing the CFG of the function and
/// associating this with the previously created groups.
/// For simplicity, the generated control flow is expanded for all possible
Expand Down Expand Up @@ -1957,6 +2021,9 @@ void SCFToCalyxPass::runOnOperation() {
/// This pass inlines scf.ExecuteRegionOp's by adding control-flow.
addGreedyPattern<InlineExecuteRegionOpPattern>(loweringPatterns);

addOncePattern<BuildSwitchGroups>(loweringPatterns, patternState, funcMap,
*loweringState);

/// This pattern converts all index typed values to an i32 integer.
addOncePattern<calyx::ConvertIndexTypes>(loweringPatterns, patternState,
funcMap, *loweringState);
Expand Down

0 comments on commit dfc0671

Please sign in to comment.