};
private:
+ // XXX-update: A flag that checks whether we can eliminate this machine basic
+ // block.
+ bool canEliminateMachineBB;
+
typedef ilist<MachineInstr> Instructions;
Instructions Insts;
const BasicBlock *BB;
friend class MachineFunction;
public:
+ // XXX-update:
+ void disableCanEliminateMachineBB() {
+ canEliminateMachineBB = false;
+ }
+
+ bool getCanEliminateMachineBB() {
+ return canEliminateMachineBB;
+ }
+
/// Return the LLVM basic block that this instance corresponded to originally.
/// Note that this may be NULL if this instance does not correspond directly
/// to an LLVM basic block.
BundledSucc = 1 << 3 // Instruction has bundled successors.
};
private:
+ // XXX-update: A flag that checks whether we can eliminate this instruction.
+ bool canEliminateMachineInstr;
+
const MCInstrDesc *MCID; // Instruction descriptor.
MachineBasicBlock *Parent; // Pointer to the owning basic block.
friend class MachineFunction;
public:
+ // XXX-update:
+ void disableCanEliminateMachineInstr() {
+ canEliminateMachineInstr = false;
+ }
+
+ bool getCanEliminateMachineInstr() {
+ return canEliminateMachineInstr;
+ }
+
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
MachineBasicBlock *NextBB = &*I;
if (TBB == NextBB && !Cond.empty() && !FBB) {
if (!TII->ReverseBranchCondition(Cond)) {
- // XXX-disabled: Don't fold conditional branches that we added
- // intentionally.
- MachineBasicBlock::iterator I = CurMBB->getLastNonDebugInstr();
- if (I != CurMBB->end()) {
- if (I->isConditionalBranch()) {
- return;
- }
- }
-
TII->RemoveBranch(*CurMBB);
TII->InsertBranch(*CurMBB, SuccBB, nullptr, Cond, dl);
return;
for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
I != E; ) {
MachineBasicBlock *MBB = &*I++;
+ // XXX-disabled: Don't optimize blocks that contain intentionally added fake
+ // conditional branch.
+ if (!MBB->getCanEliminateMachineBB()) {
+ continue;
+ }
+
MadeChange |= OptimizeBlock(MBB);
// If it is dead, remove it.
// If the previous branch *only* branches to *this* block (conditional or
// not) remove the branch.
if (PriorTBB == MBB && !PriorFBB) {
- // XXX-disabled: Don't fold conditional branches that we added
- // intentionally.
- MachineBasicBlock::iterator I = PrevBB.getLastNonDebugInstr();
- if (I != PrevBB.end()) {
- if (I->isConditionalBranch()) {
- return MadeChange ;
- }
- }
-
TII->RemoveBranch(PrevBB);
MadeChange = true;
++NumBranchOpts;
// If the prior block branches somewhere else on the condition and here if
// the condition is false, remove the uncond second branch.
if (PriorFBB == MBB) {
- // XXX-disabled: Don't fold conditional branches that we added
- // intentionally.
- MachineBasicBlock::iterator I = PrevBB.getLastNonDebugInstr();
- if (I != PrevBB.end()) {
- if (I->isConditionalBranch()) {
- return MadeChange ;
- }
- }
-
DebugLoc dl = getBranchDebugLoc(PrevBB);
TII->RemoveBranch(PrevBB);
TII->InsertBranch(PrevBB, PriorTBB, nullptr, PriorCond, dl);
// if the branch condition is reversible, reverse the branch to create a
// fall-through.
if (PriorTBB == MBB) {
- // XXX-disabled: Don't fold conditional branches that we added
- // intentionally.
- MachineBasicBlock::iterator I = PrevBB.getLastNonDebugInstr();
- if (I != PrevBB.end()) {
- if (I->isConditionalBranch()) {
- return MadeChange ;
- }
- }
-
SmallVector<MachineOperand, 4> NewPriorCond(PriorCond);
if (!TII->ReverseBranchCondition(NewPriorCond)) {
DebugLoc dl = getBranchDebugLoc(PrevBB);
TerminatorInst* ThenTerm = nullptr;
TerminatorInst* ElseTerm = nullptr;
SplitBlockAndInsertIfThenElse(Condition, SplitInst, &ThenTerm, &ElseTerm);
+ assert(ThenTerm && ElseTerm &&
+ "Then/Else terminators cannot be empty after basic block spliting");
auto* ThenBB = ThenTerm->getParent();
auto* ElseBB = ElseTerm->getParent();
+ auto* TailBB = ThenBB->getSingleSuccessor();
+ assert(TailBB && "Tail block cannot be empty after basic block spliting");
+
ThenBB->disableCanEliminateBlock();
ThenBB->disableCanEliminateBlock();
+ TailBB->disableCanEliminateBlock();
ThenBB->setName(BB->getName() + "Then.Fake");
ElseBB->setName(BB->getName() + "Else.Fake");
DEBUG(dbgs() << "Add fake conditional branch:\n"
}
// XXX-comment: Returns whether the code has been changed.
-bool AddsFakeConditionalBranchAfterMonotonicLoads(
+bool AddFakeConditionalBranchAfterMonotonicLoads(
const SmallVector<LoadInst*, 1>& MonotonicLoadInsts) {
bool Changed = false;
for (auto* LI : MonotonicLoadInsts) {
bool CodeGenPrepare::runOnFunction(Function &F) {
- // XXX-comment: Delay dealing with relaxed loads in this function to avoid
- // further changes done by other passes (e.g., SimplifyCFG).
-
- // Collect all the relaxed loads.
- SmallVector<LoadInst*, 1> MonotonicLoadInsts;
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (I->isAtomic()) {
- switch (I->getOpcode()) {
- case Instruction::Load: {
- auto* LI = dyn_cast<LoadInst>(&*I);
- if (LI->getOrdering() == Monotonic) {
- MonotonicLoadInsts.push_back(LI);
- }
- break;
- }
- default: {
- break;
- }
- }
- }
- }
- bool EverMadeChange =
- AddsFakeConditionalBranchAfterMonotonicLoads(MonotonicLoadInsts);
+ bool EverMadeChange = false;
if (skipOptnoneFunction(F))
return false;
EverMadeChange |= simplifyOffsetableRelocate(*I);
}
+ // XXX-comment: Delay dealing with relaxed loads in this function to avoid
+ // further changes done by other passes (e.g., SimplifyCFG).
+ // Collect all the relaxed loads.
+ SmallVector<LoadInst*, 1> MonotonicLoadInsts;
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (I->isAtomic()) {
+ switch (I->getOpcode()) {
+ case Instruction::Load: {
+ auto* LI = dyn_cast<LoadInst>(&*I);
+ if (LI->getOrdering() == Monotonic) {
+ MonotonicLoadInsts.push_back(LI);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+ EverMadeChange |=
+ AddFakeConditionalBranchAfterMonotonicLoads(MonotonicLoadInsts);
+
return EverMadeChange;
}
// Note that this intentionally skips the entry block.
for (Function::iterator I = std::next(F.begin()), E = F.end(); I != E;) {
BasicBlock *BB = &*I++;
- // XXX-disabled: Do not eliminate the added fake basic block.
- if (!BB->getCanEliminateBlock()) {
- continue;
- }
-
// If this block doesn't end with an uncond branch, ignore it.
BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
if (!BI || !BI->isUnconditional())
#define DEBUG_TYPE "codegen"
MachineBasicBlock::MachineBasicBlock(MachineFunction &MF, const BasicBlock *B)
- : BB(B), Number(-1), xParent(&MF) {
+ : BB(B), Number(-1), xParent(&MF), canEliminateMachineBB(true) {
Insts.Parent = this;
}
//
bool needUpdateBr = true;
if (!Cond.empty() && (!FBB || FBB == ChainBB)) {
- // XXX-disabled: Don't bother with added fake conditional branches.
- /*
PrevBB->updateTerminator();
- */
needUpdateBr = false;
Cond.clear();
TBB = FBB = nullptr;
DebugLoc dl, bool NoImp)
: MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0),
AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr),
- debugLoc(std::move(dl)) {
+ debugLoc(std::move(dl)), canEliminateMachineInstr(true) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
// Reserve space for the expected number of operands.
: MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0),
Flags(0), AsmPrinterFlags(0),
NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs),
- debugLoc(MI.getDebugLoc()) {
+ debugLoc(MI.getDebugLoc()), canEliminateMachineInstr(true) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
CapOperands = OperandCapacity::get(MI.getNumOperands());
// at this point.
FuncInfo->clear();
+ // XXX-update: Right after instruction selection, check through the
+ // intentionally added fake conditional branches and mark them as unremovable.
+ for (auto& MBB : *MF) {
+ // Check whether MBB has two successors which only contains an unconditional
+ // branch to the same destination.
+ if (MBB.succ_size() != 2 ||
+ !MBB.getLastNonDebugInstr()->isUnconditionalBranch()) {
+ continue;
+ }
+ auto MBBSuccIter = MBB.succ_begin();
+ auto* Succ1 = *MBBSuccIter;
+ MBBSuccIter++;
+ auto* Succ2 = *MBBSuccIter;
+
+ MachineBasicBlock* Succ1Succ = nullptr;
+ MachineBasicBlock* Succ2Succ = nullptr;
+ if ((Succ1->size() == 1 && Succ1->begin()->isUnconditionalBranch()) ||
+ (Succ1->size() == 0)) {
+ Succ1Succ = *Succ1->succ_begin();
+ }
+ if ((Succ2->size() == 1 && Succ2->begin()->isUnconditionalBranch()) ||
+ (Succ2->size() == 0)) {
+ Succ2Succ = *Succ2->succ_begin();
+ }
+
+ bool HasCommonDest = Succ1Succ && Succ1Succ == Succ2Succ;
+ if (HasCommonDest) {
+ auto MBBIter = MBB.end();
+ std::advance(MBBIter, -2);
+ assert(MBBIter->isConditionalBranch());
+ MBBIter->disableCanEliminateMachineInstr();
+ MBB.disableCanEliminateMachineBB();
+ Succ1->disableCanEliminateMachineBB();
+ Succ2->disableCanEliminateMachineBB();
+ Succ1Succ->disableCanEliminateMachineBB();
+ DEBUG(dbgs() << "Mark as unremovable machine basic block: " << MBB
+ << "\nMark as unremovable branch instruction: " << *MBBIter
+ << "\n");
+ }
+ }
+
DEBUG(dbgs() << "*** MachineFunction at end of ISel ***\n");
DEBUG(MF->print(dbgs()));
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
- : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) {
+ : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr),
+ canEliminateBlock(true) {
if (NewParent)
insertInto(NewParent, InsertBefore);
return false;
}
-// XXX-update: Returns whether we can remove a conditional branch instruction.
-// If it's one that is mannually added by us, then don't remove it (return
-// false). All their successors are the same.
-static bool shouldRemoveConditionalBranch(MachineInstr* I) {
- auto* MBB = I->getParent();
- assert(isCondBranchOpcode(I->getOpcode()));
- bool SameSuccessor = true;
- MachineBasicBlock* BB = nullptr;
- for (auto* Succ : MBB->successors()) {
- if (!BB) {
- BB = Succ;
- }
- if (BB != Succ) {
- SameSuccessor = false;
- }
- }
- return !SameSuccessor;
-}
-
unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
if (I == MBB.end())
!isCondBranchOpcode(I->getOpcode()))
return 0;
- // XXX-update: Don't remove fake conditional branches.
- if (isCondBranchOpcode(I->getOpcode()) && !shouldRemoveConditionalBranch(I)) {
- return 0;
- }
-
// Remove the branch.
I->eraseFromParent();
if (!isCondBranchOpcode(I->getOpcode()))
return 1;
- // XXX-update: Don't remove fake conditional branches.
- if (!shouldRemoveConditionalBranch(I)) {
- return 1;
- }
-
// Remove the branch.
I->eraseFromParent();
return 2;