Skip to content

Commit

Permalink
RedundantFlagCalculationElimination: optimize parity globally
Browse files Browse the repository at this point in the history
Signed-off-by: Alyssa Rosenzweig <[email protected]>
  • Loading branch information
alyssarosenzweig committed Sep 4, 2024
1 parent 9b4bad1 commit 561f7ba
Showing 1 changed file with 29 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class DeadFlagCalculationEliminination final : public FEXCore::IR::Pass {
void FoldBranch(IREmitter* IREmit, IRListView& CurrentIR, IROp_CondJump* Op, Ref CodeNode);
CondClassType X86ToArmFloatCond(CondClassType X86);
bool ProcessBlock(IREmitter* IREmit, IRListView& CurrentIR, Ref Block, ControlFlowGraph& CFG, bool& ReadsParity);
void OptimizeParity(IREmitter* IREmit, IRListView& CurrentIR);
void OptimizeParity(IREmitter* IREmit, IRListView& CurrentIR, ControlFlowGraph& CFG);
};

unsigned DeadFlagCalculationEliminination::FlagForReg(unsigned Reg) {
Expand Down Expand Up @@ -571,11 +571,31 @@ bool DeadFlagCalculationEliminination::ProcessBlock(IREmitter* IREmit, IRListVie
return Progress;
}

void DeadFlagCalculationEliminination::OptimizeParity(IREmitter* IREmit, IRListView& CurrentIR) {
// Pass to determine if 8-bit parity is required.
void DeadFlagCalculationEliminination::OptimizeParity(IREmitter* IREmit, IRListView& CurrentIR, ControlFlowGraph& CFG) {
// Mapping for flags inside this pass.
const uint8_t PARTIAL = 0;
const uint8_t FULL = 1;

// Initialize conservatively: all blocks need full parity. This initialization
// matters for proper handling of backedges.
for (auto [Block, BlockHeader] : CurrentIR.GetBlocks()) {
CFG.Get(Block)->Flags = FULL;
}

for (auto [Block, BlockHeader] : CurrentIR.GetBlocks()) {
// TODO: This is local for now, but we should propagate this globally.
bool Full = true;
bool Full = false;
auto Predecessors = CFG.Get(Block)->Predecessors;

if (Predecessors.empty()) {
// Conservatively assume there was full parity before the start block
Full = true;
} else {
// If any predecessor needs full parity at the end, we need full parity.
for (auto Pred : Predecessors) {
Full |= (CFG.Get(Pred)->Flags == FULL);
}
}

for (auto [CodeNode, IROp] : CurrentIR.GetCode(Block)) {
if (IROp->Op == OP_STOREREGISTER) {
auto Op = IROp->CW<IR::IROp_StoreRegister>();
Expand Down Expand Up @@ -611,6 +631,9 @@ void DeadFlagCalculationEliminination::OptimizeParity(IREmitter* IREmit, IRListV
IREmit->Remove(CodeNode);
}
}

// Record our final state for our successors to read.
CFG.Get(Block)->Flags = Full ? FULL : PARTIAL;
}
}

Expand Down Expand Up @@ -675,7 +698,7 @@ void DeadFlagCalculationEliminination::Run(IREmitter* IREmit) {
}

if (ReadsParity) {
OptimizeParity(IREmit, CurrentIR);
OptimizeParity(IREmit, CurrentIR, CFG);
}
}

Expand Down

0 comments on commit 561f7ba

Please sign in to comment.