forked from OSchip/llvm-project
[Hexagon] Extract function that checks endloops with other branches
Change location number to point to conflicting branch instruction. Patch by Colin LeMahieu. llvm-svn: 301946
This commit is contained in:
parent
1cc6bfbc83
commit
c15f8d2a08
|
@ -246,6 +246,7 @@ bool HexagonMCChecker::check(bool FullCheck) {
|
|||
bool chkNV = checkNewValues();
|
||||
bool chkR = checkRegisters();
|
||||
bool chkRRO = checkRegistersReadOnly();
|
||||
bool chkELB = checkEndloopBranches();
|
||||
checkRegisterCurDefs();
|
||||
bool chkS = checkSolo();
|
||||
bool chkSh = true;
|
||||
|
@ -254,11 +255,30 @@ bool HexagonMCChecker::check(bool FullCheck) {
|
|||
bool chkSl = true;
|
||||
if (FullCheck)
|
||||
chkSl = checkSlots();
|
||||
bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkS && chkSh && chkSl;
|
||||
bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkELB && chkS &&
|
||||
chkSh && chkSl;
|
||||
|
||||
return chk;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::checkEndloopBranches() {
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
|
||||
if (Desc.isBranch() || Desc.isCall()) {
|
||||
auto Inner = HexagonMCInstrInfo::isInnerLoop(MCB);
|
||||
if (Inner || HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
||||
reportError(I.getLoc(),
|
||||
llvm::Twine("packet marked with `:endloop") +
|
||||
(Inner ? "0" : "1") + "' " +
|
||||
"cannot contain instructions that modify register " +
|
||||
"`" + llvm::Twine(RI.getName(Hexagon::PC)) + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::checkSlots() {
|
||||
unsigned slotsUsed = 0;
|
||||
for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
|
@ -304,16 +324,6 @@ bool HexagonMCChecker::checkBranches() {
|
|||
}
|
||||
}
|
||||
|
||||
if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too?
|
||||
if (HexagonMCInstrInfo::isInnerLoop(MCB) ||
|
||||
HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
||||
// Error out if there's any branch in a loop-end packet.
|
||||
Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
|
||||
reportError("packet marked with `:endloop" + N + "' " +
|
||||
"cannot contain instructions that modify register " + "`" +
|
||||
llvm::Twine(RI.getName(Hexagon::PC)) + "'");
|
||||
return false;
|
||||
}
|
||||
if (Branches > 1)
|
||||
if (!hasConditional || Conditional > Unconditional) {
|
||||
// Error out if more than one unconditional branch or
|
||||
|
@ -391,29 +401,23 @@ bool HexagonMCChecker::checkRegistersReadOnly() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::registerUsed(MCInst const &Inst, unsigned Register) {
|
||||
unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
|
||||
for (unsigned j = Defs, n = Inst.getNumOperands(); j < n; ++j) {
|
||||
MCOperand const &Operand = Inst.getOperand(j);
|
||||
if (Operand.isReg() && Operand.getReg() == Register)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::registerUsed(unsigned Register) {
|
||||
for (auto const &I: HexagonMCInstrInfo::bundleInstructions(MCII, MCB))
|
||||
if (registerUsed(I, Register))
|
||||
return true;
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB))
|
||||
for (unsigned j = HexagonMCInstrInfo::getDesc(MCII, I).getNumDefs(),
|
||||
n = I.getNumOperands();
|
||||
j < n; ++j) {
|
||||
MCOperand const &Operand = I.getOperand(j);
|
||||
if (Operand.isReg() && Operand.getReg() == Register)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HexagonMCChecker::checkRegisterCurDefs() {
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
MCInst const &Inst = *I.getInst();
|
||||
if (HexagonMCInstrInfo::isCVINew(MCII, Inst) &&
|
||||
HexagonMCInstrInfo::getDesc(MCII, Inst).mayLoad()) {
|
||||
unsigned Register = Inst.getOperand(0).getReg();
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
if (HexagonMCInstrInfo::isCVINew(MCII, I) &&
|
||||
HexagonMCInstrInfo::getDesc(MCII, I).mayLoad()) {
|
||||
unsigned Register = I.getOperand(0).getReg();
|
||||
if (!registerUsed(Register))
|
||||
reportWarning("Register `" + llvm::Twine(RI.getName(Register)) +
|
||||
"' used with `.cur' "
|
||||
|
@ -512,12 +516,11 @@ bool HexagonMCChecker::checkRegisters() {
|
|||
// Check for legal use of solo insns.
|
||||
bool HexagonMCChecker::checkSolo() {
|
||||
if (HexagonMCInstrInfo::bundleSize(MCB) > 1)
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) {
|
||||
SMLoc Loc = I.getInst()->getLoc();
|
||||
reportError(Loc, "Instruction is marked `isSolo' and "
|
||||
"cannot have other instructions in "
|
||||
"the same packet");
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
if (llvm::HexagonMCInstrInfo::isSolo(MCII, I)) {
|
||||
reportError(I.getLoc(), "Instruction is marked `isSolo' and "
|
||||
"cannot have other instructions in "
|
||||
"the same packet");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,13 +107,13 @@ class HexagonMCChecker {
|
|||
void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue);
|
||||
|
||||
bool registerUsed(unsigned Register);
|
||||
bool registerUsed(MCInst const &Inst, unsigned Register);
|
||||
// Checks performed.
|
||||
bool checkBranches();
|
||||
bool checkPredicates();
|
||||
bool checkNewValues();
|
||||
bool checkRegisters();
|
||||
bool checkRegistersReadOnly();
|
||||
bool checkEndloopBranches();
|
||||
void checkRegisterCurDefs();
|
||||
bool checkSolo();
|
||||
bool checkShuffle();
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# RUN: not llvm-mc -triple=hexagon -filetype=asm %s 2>&1 | FileCheck %s
|
||||
|
||||
# Check that a branch in an end-loop packet is caught.
|
||||
|
||||
{ jump unknown
|
||||
}:endloop0
|
||||
# CHECK: 5:3: error: packet marked with `:endloop0' cannot contain instructions that modify register
|
||||
|
||||
{ jump unknown
|
||||
}:endloop1
|
||||
|
||||
# CHECK: 9:3: error: packet marked with `:endloop1' cannot contain instructions that modify register
|
|
@ -1,19 +0,0 @@
|
|||
# RUN: not llvm-mc -triple=hexagon -filetype=asm %s 2>&1 | FileCheck %s
|
||||
|
||||
# Check that a branch in an end-loop packet is caught.
|
||||
|
||||
1:
|
||||
{
|
||||
r0 = #1
|
||||
p0 = cmp.eq (r1, r2)
|
||||
if (p0) jump 1b
|
||||
}:endloop0
|
||||
|
||||
2:
|
||||
{
|
||||
r0 = #1
|
||||
p0 = cmp.eq (r1, r2)
|
||||
if (p0) jump 2b
|
||||
}:endloop1
|
||||
|
||||
# CHECK: rror: packet marked with `:endloop{{.}}' cannot contain instructions that modify register
|
Loading…
Reference in New Issue