Commit ab62fa56 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r371048:

------------------------------------------------------------------------
r371048 | jonpa | 2019-09-05 12:20:05 +0200 (Thu, 05 Sep 2019) | 7 lines

[SystemZ]  Recognize INLINEASM_BR in backend

Handle the remaining cases also by handling asm goto in
SystemZInstrInfo::getBranchInfo().

Review: Ulrich Weigand
https://reviews.llvm.org/D67151
------------------------------------------------------------------------

llvm-svn: 371057
parent d8975f4f
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -462,13 +462,13 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
      break;

    // A terminator that isn't a branch can't easily be handled by this
    // analysis.  Asm goto is not understood / optimized.
    if (!I->isBranch() || I->getOpcode() == SystemZ::INLINEASM_BR)
    // analysis.
    if (!I->isBranch())
      return true;

    // Can't handle indirect branches.
    SystemZII::Branch Branch(getBranchInfo(*I));
    if (!Branch.Target->isMBB())
    if (!Branch.hasMBBTarget())
      return true;

    // Punt on compound branches.
@@ -478,7 +478,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
    if (Branch.CCMask == SystemZ::CCMASK_ANY) {
      // Handle unconditional branches.
      if (!AllowModify) {
        TBB = Branch.Target->getMBB();
        TBB = Branch.getMBBTarget();
        continue;
      }

@@ -490,7 +490,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
      FBB = nullptr;

      // Delete the JMP if it's equivalent to a fall-through.
      if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
      if (MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
        TBB = nullptr;
        I->eraseFromParent();
        I = MBB.end();
@@ -498,7 +498,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
      }

      // TBB is used to indicate the unconditinal destination.
      TBB = Branch.Target->getMBB();
      TBB = Branch.getMBBTarget();
      continue;
    }

@@ -506,7 +506,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
    if (Cond.empty()) {
      // FIXME: add X86-style branch swap
      FBB = TBB;
      TBB = Branch.Target->getMBB();
      TBB = Branch.getMBBTarget();
      Cond.push_back(MachineOperand::CreateImm(Branch.CCValid));
      Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
      continue;
@@ -517,7 +517,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,

    // Only handle the case where all conditional branches branch to the same
    // destination.
    if (TBB != Branch.Target->getMBB())
    if (TBB != Branch.getMBBTarget())
      return true;

    // If the conditions are the same, we can leave them alone.
@@ -547,7 +547,7 @@ unsigned SystemZInstrInfo::removeBranch(MachineBasicBlock &MBB,
      continue;
    if (!I->isBranch())
      break;
    if (!getBranchInfo(*I).Target->isMBB())
    if (!getBranchInfo(*I).hasMBBTarget())
      break;
    // Remove the branch.
    I->eraseFromParent();
@@ -1545,6 +1545,10 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const {
    return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP,
                             MI.getOperand(2).getImm(), &MI.getOperand(3));

  case SystemZ::INLINEASM_BR:
    // Don't try to analyze asm goto, so pass nullptr as branch target argument.
    return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr);

  default:
    llvm_unreachable("Unrecognized branch opcode");
  }
+16 −6
Original line number Diff line number Diff line
@@ -100,11 +100,18 @@ enum BranchType {

  // An instruction that decrements a 64-bit register and branches if
  // the result is nonzero.
  BranchCTG
  BranchCTG,

  // An instruction representing an asm goto statement.
  AsmGoto
};

// Information about a branch instruction.
struct Branch {
class Branch {
  // The target of the branch. In case of INLINEASM_BR, this is nullptr.
  const MachineOperand *Target;

public:
  // The type of the branch.
  BranchType Type;

@@ -114,12 +121,15 @@ struct Branch {
  // CCMASK_<N> is set if the branch should be taken when CC == N.
  unsigned CCMask;

  // The target of the branch.
  const MachineOperand *Target;

  Branch(BranchType type, unsigned ccValid, unsigned ccMask,
         const MachineOperand *target)
    : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
    : Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}

  bool isIndirect() { return Target != nullptr && Target->isReg(); }
  bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }
  MachineBasicBlock *getMBBTarget() {
    return hasMBBTarget() ? Target->getMBB() : nullptr;
  }
};

// Kinds of fused compares in compare-and-* instructions.  Together with type
+1 −1
Original line number Diff line number Diff line
@@ -257,7 +257,7 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) {
    }
    Terminator.Branch = &MI;
    Terminator.TargetBlock =
      TII->getBranchInfo(MI).Target->getMBB()->getNumber();
      TII->getBranchInfo(MI).getMBBTarget()->getNumber();
  }
  return Terminator;
}
+2 −2
Original line number Diff line number Diff line
@@ -108,8 +108,8 @@ void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) {
       I != SinglePredMBB->end(); I++) {
    LLVM_DEBUG(dbgs() << "** Emitting incoming branch: "; I->dump(););
    bool TakenBranch = (I->isBranch() &&
      (TII->getBranchInfo(*I).Target->isReg() || // Relative branch
       TII->getBranchInfo(*I).Target->getMBB() == MBB));
                        (TII->getBranchInfo(*I).isIndirect() ||
                         TII->getBranchInfo(*I).getMBBTarget() == MBB));
    HazardRec->emitInstruction(&*I, TakenBranch);
    if (TakenBranch)
      break;
+2 −2
Original line number Diff line number Diff line
; Test that asm goto can be compiled.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14

define i32 @c() {
entry:
  callbr void asm sideeffect "", "X"(i8* blockaddress(@c, %d))
  callbr void asm sideeffect "j d", "X"(i8* blockaddress(@c, %d))
          to label %asm.fallthrough [label %d]

asm.fallthrough:               ; preds = %entry