diff options
Diffstat (limited to 'lib/Target/R600/AMDILCFGStructurizer.cpp')
-rw-r--r-- | lib/Target/R600/AMDILCFGStructurizer.cpp | 112 |
1 files changed, 81 insertions, 31 deletions
diff --git a/lib/Target/R600/AMDILCFGStructurizer.cpp b/lib/Target/R600/AMDILCFGStructurizer.cpp index 687eadb..507570f 100644 --- a/lib/Target/R600/AMDILCFGStructurizer.cpp +++ b/lib/Target/R600/AMDILCFGStructurizer.cpp @@ -1005,13 +1005,14 @@ int AMDGPUCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) { return 0; assert(isCondBranch(BranchMI)); + int NumMatch = 0; MachineBasicBlock *TrueMBB = getTrueBranch(BranchMI); - serialPatternMatch(TrueMBB); - ifPatternMatch(TrueMBB); + NumMatch += serialPatternMatch(TrueMBB); + NumMatch += ifPatternMatch(TrueMBB); MachineBasicBlock *FalseMBB = getFalseBranch(MBB, BranchMI); - serialPatternMatch(FalseMBB); - ifPatternMatch(FalseMBB); + NumMatch += serialPatternMatch(FalseMBB); + NumMatch += ifPatternMatch(FalseMBB); MachineBasicBlock *LandBlk; int Cloned = 0; @@ -1040,7 +1041,7 @@ int AMDGPUCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) { && isSameloopDetachedContbreak(FalseMBB, TrueMBB)) { LandBlk = *TrueMBB->succ_begin(); } else { - return handleJumpintoIf(MBB, TrueMBB, FalseMBB); + return NumMatch + handleJumpintoIf(MBB, TrueMBB, FalseMBB); } // improveSimpleJumpinfoIf can handle the case where landBlk == NULL but the @@ -1068,7 +1069,7 @@ int AMDGPUCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) { numClonedBlock += Cloned; - return 1 + Cloned; + return 1 + Cloned + NumMatch; } int AMDGPUCFGStructurizer::loopendPatternMatch() { @@ -1233,7 +1234,7 @@ int AMDGPUCFGStructurizer::handleJumpintoIfImp(MachineBasicBlock *HeadMBB, numClonedBlock += Num; Num += serialPatternMatch(*HeadMBB->succ_begin()); - Num += serialPatternMatch(*(++HeadMBB->succ_begin())); + Num += serialPatternMatch(*llvm::next(HeadMBB->succ_begin())); Num += ifPatternMatch(HeadMBB); assert(Num > 0); @@ -1335,32 +1336,77 @@ int AMDGPUCFGStructurizer::improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB, // add initReg = initVal to headBlk const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); - unsigned InitReg = - HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC); - if (!MigrateTrue || !MigrateFalse) - llvm_unreachable("Extra register needed to handle CFG"); + if (!MigrateTrue || !MigrateFalse) { + // XXX: We have an opportunity here to optimize the "branch into if" case + // here. Branch into if looks like this: + // entry + // / | + // diamond_head branch_from + // / \ | + // diamond_false diamond_true + // \ / + // done + // + // The diamond_head block begins the "if" and the diamond_true block + // is the block being "branched into". + // + // If MigrateTrue is true, then TrueBB is the block being "branched into" + // and if MigrateFalse is true, then FalseBB is the block being + // "branched into" + // + // Here is the pseudo code for how I think the optimization should work: + // 1. Insert MOV GPR0, 0 before the branch instruction in diamond_head. + // 2. Insert MOV GPR0, 1 before the branch instruction in branch_from. + // 3. Move the branch instruction from diamond_head into its own basic + // block (new_block). + // 4. Add an unconditional branch from diamond_head to new_block + // 5. Replace the branch instruction in branch_from with an unconditional + // branch to new_block. If branch_from has multiple predecessors, then + // we need to replace the True/False block in the branch + // instruction instead of replacing it. + // 6. Change the condition of the branch instruction in new_block from + // COND to (COND || GPR0) + // + // In order insert these MOV instruction, we will need to use the + // RegisterScavenger. Usually liveness stops being tracked during + // the late machine optimization passes, however if we implement + // bool TargetRegisterInfo::requiresRegisterScavenging( + // const MachineFunction &MF) + // and have it return true, liveness will be tracked correctly + // by generic optimization passes. We will also need to make sure that + // all of our target-specific passes that run after regalloc and before + // the CFGStructurizer track liveness and we will need to modify this pass + // to correctly track liveness. + // + // After the above changes, the new CFG should look like this: + // entry + // / | + // diamond_head branch_from + // \ / + // new_block + // / | + // diamond_false diamond_true + // \ / + // done + // + // Without this optimization, we are forced to duplicate the diamond_true + // block and we will end up with a CFG like this: + // + // entry + // / | + // diamond_head branch_from + // / \ | + // diamond_false diamond_true diamond_true (duplicate) + // \ / | + // done --------------------| + // + // Duplicating diamond_true can be very costly especially if it has a + // lot of instructions. + return 0; + } int NumNewBlk = 0; - if (!LandBlk) { - LandBlk = HeadMBB->getParent()->CreateMachineBasicBlock(); - HeadMBB->getParent()->push_back(LandBlk); //insert to function - - if (TrueMBB) { - TrueMBB->addSuccessor(LandBlk); - } else { - HeadMBB->addSuccessor(LandBlk); - } - - if (FalseMBB) { - FalseMBB->addSuccessor(LandBlk); - } else { - HeadMBB->addSuccessor(LandBlk); - } - - NumNewBlk ++; - } - bool LandBlkHasOtherPred = (LandBlk->pred_size() > 2); //insert AMDGPU::ENDIF to avoid special case "input landBlk == NULL" @@ -1375,6 +1421,10 @@ int AMDGPUCFGStructurizer::improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB, CmpResReg, DebugLoc()); } + // XXX: We are running this after RA, so creating virtual registers will + // cause an assertion failure in the PostRA scheduling pass. + unsigned InitReg = + HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC); insertCondBranchBefore(LandBlk, I, AMDGPU::IF_PREDICATE_SET, InitReg, DebugLoc()); @@ -1713,7 +1763,7 @@ void AMDGPUCFGStructurizer::removeRedundantConditionalBranch( if (MBB->succ_size() != 2) return; MachineBasicBlock *MBB1 = *MBB->succ_begin(); - MachineBasicBlock *MBB2 = *(++MBB->succ_begin()); + MachineBasicBlock *MBB2 = *llvm::next(MBB->succ_begin()); if (MBB1 != MBB2) return; |