From 784929d0454c4df6a98ef6fbbd1d30a6f71f9c16 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 8 Feb 2019 20:48:56 +0000 Subject: Implementation of asm-goto support in LLVM This patch accompanies the RFC posted here: http://lists.llvm.org/pipermail/llvm-dev/2018-October/127239.html This patch adds a new CallBr IR instruction to support asm-goto inline assembly like gcc as used by the linux kernel. This instruction is both a call instruction and a terminator instruction with multiple successors. Only inline assembly usage is supported today. This also adds a new INLINEASM_BR opcode to SelectionDAG and MachineIR to represent an INLINEASM block that is also considered a terminator instruction. There will likely be more bug fixes and optimizations to follow this, but we felt it had reached a point where we would like to switch to an incremental development model. Patch by Craig Topper, Alexander Ivchenko, Mikhail Dvoretckii Differential Revision: https://reviews.llvm.org/D53765 llvm-svn: 353563 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp') diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 3fec17ac8cc..00bcb8479c3 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1265,8 +1265,10 @@ static bool HoistThenElseCodeToIf(BranchInst *BI, while (isa(I2)) I2 = &*BB2_Itr++; } + // FIXME: Can we define a safety predicate for CallBr? if (isa(I1) || !I1->isIdenticalToWhenDefined(I2) || - (isa(I1) && !isSafeToHoistInvoke(BB1, BB2, I1, I2))) + (isa(I1) && !isSafeToHoistInvoke(BB1, BB2, I1, I2)) || + isa(I1)) return false; BasicBlock *BIParent = BI->getParent(); @@ -1349,9 +1351,14 @@ static bool HoistThenElseCodeToIf(BranchInst *BI, HoistTerminator: // It may not be possible to hoist an invoke. + // FIXME: Can we define a safety predicate for CallBr? if (isa(I1) && !isSafeToHoistInvoke(BB1, BB2, I1, I2)) return Changed; + // TODO: callbr hoisting currently disabled pending further study. + if (isa(I1)) + return Changed; + for (BasicBlock *Succ : successors(BB1)) { for (PHINode &PN : Succ->phis()) { Value *BB1V = PN.getIncomingValueForBlock(BB1); @@ -1443,7 +1450,7 @@ static bool canSinkInstructions( // Conservatively return false if I is an inline-asm instruction. Sinking // and merging inline-asm instructions can potentially create arguments // that cannot satisfy the inline-asm constraints. - if (const auto *C = dyn_cast(I)) + if (const auto *C = dyn_cast(I)) if (C->isInlineAsm()) return false; @@ -1506,7 +1513,7 @@ static bool canSinkInstructions( // We can't create a PHI from this GEP. return false; // Don't create indirect calls! The called value is the final operand. - if ((isa(I0) || isa(I0)) && OI == OE - 1) { + if (isa(I0) && OI == OE - 1) { // FIXME: if the call was *already* indirect, we should do this. return false; } -- cgit v1.2.3