summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/AsmWriter.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2019-02-08 20:48:56 +0000
committerCraig Topper <craig.topper@intel.com>2019-02-08 20:48:56 +0000
commit784929d0454c4df6a98ef6fbbd1d30a6f71f9c16 (patch)
treeee2091fd647c20c3279800a14f7ce36c85b8c00b /llvm/lib/IR/AsmWriter.cpp
parent0e5dd512aae057aeceb34089c93a380f8edd37da (diff)
downloadbcm5719-llvm-784929d0454c4df6a98ef6fbbd1d30a6f71f9c16.tar.gz
bcm5719-llvm-784929d0454c4df6a98ef6fbbd1d30a6f71f9c16.zip
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
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 980de9ab1ee..af3db5186a2 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -3836,6 +3836,51 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(II->getNormalDest(), true);
Out << " unwind ";
writeOperand(II->getUnwindDest(), true);
+ } else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
+ Operand = CBI->getCalledValue();
+ FunctionType *FTy = CBI->getFunctionType();
+ Type *RetTy = FTy->getReturnType();
+ const AttributeList &PAL = CBI->getAttributes();
+
+ // Print the calling convention being used.
+ if (CBI->getCallingConv() != CallingConv::C) {
+ Out << " ";
+ PrintCallingConv(CBI->getCallingConv(), Out);
+ }
+
+ if (PAL.hasAttributes(AttributeList::ReturnIndex))
+ Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
+
+ // If possible, print out the short form of the callbr instruction. We can
+ // only do this if the first argument is a pointer to a nonvararg function,
+ // and if the return type is not a pointer to a function.
+ //
+ Out << ' ';
+ TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
+ Out << ' ';
+ writeOperand(Operand, false);
+ Out << '(';
+ for (unsigned op = 0, Eop = CBI->getNumArgOperands(); op < Eop; ++op) {
+ if (op)
+ Out << ", ";
+ writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttributes(op));
+ }
+
+ Out << ')';
+ if (PAL.hasAttributes(AttributeList::FunctionIndex))
+ Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+
+ writeOperandBundles(CBI);
+
+ Out << "\n to ";
+ writeOperand(CBI->getDefaultDest(), true);
+ Out << " [";
+ for (unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
+ if (i != 0)
+ Out << ", ";
+ writeOperand(CBI->getIndirectDest(i), true);
+ }
+ Out << ']';
} else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
Out << ' ';
if (AI->isUsedWithInAlloca())
OpenPOWER on IntegriCloud