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.
bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
APInt KnownZero, KnownOne;
-
- // XXX-disabled:
- auto Opcode = Op.getOpcode();
- if (Opcode == ISD::AND || Opcode == ISD::OR) {
- auto* Op1 = Op.getOperand(0).getNode();
- auto* Op2 = Op.getOperand(1).getNode();
- auto* Op1C = dyn_cast<ConstantSDNode>(Op1);
- auto* Op2C = dyn_cast<ConstantSDNode>(Op2);
-
- // and X, 0
- if (Opcode == ISD::AND && !Op1C && Op2C && Op2C->isNullValue()) {
- return false;
- }
-
- // or (and X, 0), Y
- if (Opcode == ISD::OR) {
- if (Op1->getOpcode() == ISD::AND) {
- auto* Op11 = Op1->getOperand(0).getNode();
- auto* Op12 = Op1->getOperand(1).getNode();
- auto* Op11C = dyn_cast<ConstantSDNode>(Op11);
- auto* Op12C = dyn_cast<ConstantSDNode>(Op12);
- if (!Op11C && Op12C && Op12C->isNullValue()) {
- return false;
- }
- }
- if (Op1->getOpcode() == ISD::TRUNCATE) {
- // or (trunc (and %0, 0)), Y
- auto* Op11 = Op1->getOperand(0).getNode();
- if (Op11->getOpcode() == ISD::AND) {
- auto* Op111 = Op11->getOperand(0).getNode();
- auto* Op112 = Op11->getOperand(1).getNode();
- auto* Op111C = dyn_cast<ConstantSDNode>(Op111);
- auto* Op112C = dyn_cast<ConstantSDNode>(Op112);
- if (!Op111C && Op112C && Op112C->isNullValue()) {
- // or (and X, 0), Y
- return false;
- }
- }
- }
- }
- }
-
- // trunc (and X, 0)
- if (Opcode == ISD::TRUNCATE) {
- auto* Op1 = Op.getOperand(0).getNode();
- if (Op1->getOpcode() == ISD::AND) {
- auto* Op11 = Op1->getOperand(0).getNode();
- auto* Op12 = Op1->getOperand(1).getNode();
- auto* Op11C = dyn_cast<ConstantSDNode>(Op11);
- auto* Op12C = dyn_cast<ConstantSDNode>(Op12);
- if (!Op11C && Op12C && Op12C->isNullValue()) {
- return false;
- }
- }
- }
-
if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
return false;
// fold (and c1, c2) -> c1&c2
ConstantSDNode *N0C = getAsNonOpaqueConstant(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
-
- // XXX-disabled: (and x, 0) should not be folded.
- // (and (and x, 0), y) shouldn't either.
- if (!N0C && N1C && N1C->isNullValue()) {
- return SDValue();
- }
- if (!N0C) {
- if (N0.getOpcode() == ISD::AND) {
- auto* N01 = N0.getOperand(1).getNode();
- auto* N01C = dyn_cast<ConstantSDNode>(N01);
- if (N01C && N01C->isNullValue()) {
- return SDValue();
- }
- }
- }
-
if (N0C && N1C && !N1C->isOpaque())
return DAG.FoldConstantArithmetic(ISD::AND, SDLoc(N), VT, N0C, N1C);
// canonicalize constant to RHS
assert(VT.isInteger() && "This operator does not apply to FP types!");
assert(N1.getValueType() == N2.getValueType() &&
N1.getValueType() == VT && "Binary operator types must match!");
-
- // XXX-disabled:
- /*
// (X & 0) -> 0. This commonly occurs when legalizing i64 values, so it's
// worth handling here.
if (N2C && N2C->isNullValue())
return N2;
- */
if (N2C && N2C->isAllOnesValue()) // X & -1 -> X
return N1;
break;
// 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)) {
- if (Succ1->succ_size()) {
- Succ1Succ = *Succ1->succ_begin();
- }
- }
- if ((Succ2->size() == 1 && Succ2->begin()->isUnconditionalBranch()) ||
- (Succ2->size() == 0)) {
- if (Succ1->succ_size()) {
- Succ2Succ = *Succ2->succ_begin();
- }
- }
-
- bool HasCommonDest = Succ1Succ && Succ1Succ == Succ2Succ;
- if (HasCommonDest) {
- auto MBBIter = MBB.end();
- std::advance(MBBIter, -2);
- assert(MBBIter->isConditionalBranch());
- 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()));
"PHI nodes must have at least one entry. If the block is dead, "
"the PHI should be removed!",
PN);
- if (PN->getNumIncomingValues() != Preds.size()) {
- dbgs() << "Problematic function: \n" << *PN->getParent()->getParent() << "\n";
- dbgs() << "Problematic block: \n" << *PN->getParent() << "\n";
- }
Assert(PN->getNumIncomingValues() == Preds.size(),
"PHINode should have one entry for each predecessor of its "
"parent basic block!",
}
const Use &U = I.getOperandUse(i);
- if (!(InstsInThisBlock.count(Op) || DT.dominates(Op, U))) {
- dbgs() << "Problematic function: \n" << *I.getParent()->getParent() << "\n";
- }
Assert(InstsInThisBlock.count(Op) || DT.dominates(Op, U),
"Instruction does not dominate all uses!", Op, &I);
}
// Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
// ourselves.
addPass(createAtomicExpandPass(TM));
- // XXX-update: Immediate add -licm pass after atomic expand pass to deal with
- // loop invariants introduced mannually.
-// addPass(createLICMPass());
// Cmpxchg instructions are often used with a subsequent comparison to
// determine whether it succeeded. We can exploit existing control-flow in