llvm.org GIT mirror llvm / b88a26c
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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_90@371057 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 2 months ago
5 changed file(s) with 34 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
461461 break;
462462
463463 // A terminator that isn't a branch can't easily be handled by this
464 // analysis. Asm goto is not understood / optimized.
465 if (!I->isBranch() || I->getOpcode() == SystemZ::INLINEASM_BR)
464 // analysis.
465 if (!I->isBranch())
466466 return true;
467467
468468 // Can't handle indirect branches.
469469 SystemZII::Branch Branch(getBranchInfo(*I));
470 if (!Branch.Target->isMBB())
470 if (!Branch.hasMBBTarget())
471471 return true;
472472
473473 // Punt on compound branches.
477477 if (Branch.CCMask == SystemZ::CCMASK_ANY) {
478478 // Handle unconditional branches.
479479 if (!AllowModify) {
480 TBB = Branch.Target->getMBB();
480 TBB = Branch.getMBBTarget();
481481 continue;
482482 }
483483
489489 FBB = nullptr;
490490
491491 // Delete the JMP if it's equivalent to a fall-through.
492 if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
492 if (MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
493493 TBB = nullptr;
494494 I->eraseFromParent();
495495 I = MBB.end();
497497 }
498498
499499 // TBB is used to indicate the unconditinal destination.
500 TBB = Branch.Target->getMBB();
500 TBB = Branch.getMBBTarget();
501501 continue;
502502 }
503503
505505 if (Cond.empty()) {
506506 // FIXME: add X86-style branch swap
507507 FBB = TBB;
508 TBB = Branch.Target->getMBB();
508 TBB = Branch.getMBBTarget();
509509 Cond.push_back(MachineOperand::CreateImm(Branch.CCValid));
510510 Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
511511 continue;
516516
517517 // Only handle the case where all conditional branches branch to the same
518518 // destination.
519 if (TBB != Branch.Target->getMBB())
519 if (TBB != Branch.getMBBTarget())
520520 return true;
521521
522522 // If the conditions are the same, we can leave them alone.
546546 continue;
547547 if (!I->isBranch())
548548 break;
549 if (!getBranchInfo(*I).Target->isMBB())
549 if (!getBranchInfo(*I).hasMBBTarget())
550550 break;
551551 // Remove the branch.
552552 I->eraseFromParent();
15431543 case SystemZ::CLGRJ:
15441544 return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP,
15451545 MI.getOperand(2).getImm(), &MI.getOperand(3));
1546
1547 case SystemZ::INLINEASM_BR:
1548 // Don't try to analyze asm goto, so pass nullptr as branch target argument.
1549 return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr);
15461550
15471551 default:
15481552 llvm_unreachable("Unrecognized branch opcode");
9999
100100 // An instruction that decrements a 64-bit register and branches if
101101 // the result is nonzero.
102 BranchCTG
102 BranchCTG,
103
104 // An instruction representing an asm goto statement.
105 AsmGoto
103106 };
104107
105108 // Information about a branch instruction.
106 struct Branch {
109 class Branch {
110 // The target of the branch. In case of INLINEASM_BR, this is nullptr.
111 const MachineOperand *Target;
112
113 public:
107114 // The type of the branch.
108115 BranchType Type;
109116
113120 // CCMASK_ is set if the branch should be taken when CC == N.
114121 unsigned CCMask;
115122
116 // The target of the branch.
117 const MachineOperand *Target;
118
119123 Branch(BranchType type, unsigned ccValid, unsigned ccMask,
120124 const MachineOperand *target)
121 : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
125 : Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}
126
127 bool isIndirect() { return Target != nullptr && Target->isReg(); }
128 bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }
129 MachineBasicBlock *getMBBTarget() {
130 return hasMBBTarget() ? Target->getMBB() : nullptr;
131 }
122132 };
123133
124134 // Kinds of fused compares in compare-and-* instructions. Together with type
256256 }
257257 Terminator.Branch = &MI;
258258 Terminator.TargetBlock =
259 TII->getBranchInfo(MI).Target->getMBB()->getNumber();
259 TII->getBranchInfo(MI).getMBBTarget()->getNumber();
260260 }
261261 return Terminator;
262262 }
107107 I != SinglePredMBB->end(); I++) {
108108 LLVM_DEBUG(dbgs() << "** Emitting incoming branch: "; I->dump(););
109109 bool TakenBranch = (I->isBranch() &&
110 (TII->getBranchInfo(*I).Target->isReg() || // Relative branch
111 TII->getBranchInfo(*I).Target->getMBB() == MBB));
110 (TII->getBranchInfo(*I).isIndirect() ||
111 TII->getBranchInfo(*I).getMBBTarget() == MBB));
112112 HazardRec->emitInstruction(&*I, TakenBranch);
113113 if (TakenBranch)
114114 break;
0 ; Test that asm goto can be compiled.
11 ;
2 ; RUN: llc < %s -mtriple=s390x-linux-gnu
2 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14
33
44 define i32 @c() {
55 entry:
6 callbr void asm sideeffect "", "X"(i8* blockaddress(@c, %d))
6 callbr void asm sideeffect "j d", "X"(i8* blockaddress(@c, %d))
77 to label %asm.fallthrough [label %d]
88
99 asm.fallthrough: ; preds = %entry