]> granicus.if.org Git - llvm/commitdiff
GlobalISel: merge invoke and call translation paths.
authorTim Northover <tnorthover@apple.com>
Tue, 31 Jan 2017 18:36:11 +0000 (18:36 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 31 Jan 2017 18:36:11 +0000 (18:36 +0000)
Well, sort of. But the lower-level code that invoke used to be using completely
botched the handling of varargs functions, which hopefully won't be possible if
they're using the same code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293670 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/GlobalISel/CallLowering.h
lib/CodeGen/GlobalISel/CallLowering.cpp
lib/CodeGen/GlobalISel/IRTranslator.cpp
test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll

index 8eec32cece275d784af1ec8cea8e8576ffb7da3c..41bba8a4750f51b1b58913b758c02a2e8581ac45 100644 (file)
@@ -169,6 +169,9 @@ public:
   /// This hook must be implemented to lower the given call instruction,
   /// including argument and return value marshalling.
   ///
+  /// \p CI is either a CallInst or InvokeInst reference (other instantiations
+  /// will fail at link time).
+  ///
   /// \p ResReg is a register where the call's return value should be stored (or
   /// 0 if there is no return value).
   ///
@@ -181,9 +184,10 @@ public:
   /// range of an immediate jump.
   ///
   /// \return true if the lowering succeeded, false otherwise.
-  virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
-                         unsigned ResReg, ArrayRef<unsigned> ArgRegs,
-                         std::function<unsigned()> GetCalleeReg) const;
+  template <typename CallInstTy>
+  bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInstTy &CI,
+                 unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+                 std::function<unsigned()> GetCalleeReg) const;
 };
 } // End namespace llvm.
 
index 33e70856c95792dca5becab4c1b8a7de68c9fd6e..2d6f7d23e3b08591cc6c92335a2f34e5d519202a 100644 (file)
@@ -23,8 +23,9 @@
 
 using namespace llvm;
 
+template<typename CallInstTy>
 bool CallLowering::lowerCall(
-    MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg,
+    MachineIRBuilder &MIRBuilder, const CallInstTy &CI, unsigned ResReg,
     ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
   auto &DL = CI.getParent()->getParent()->getParent()->getDataLayout();
 
@@ -55,6 +56,16 @@ bool CallLowering::lowerCall(
   return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs);
 }
 
+template bool
+CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI,
+                        unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+                        std::function<unsigned()> GetCalleeReg) const;
+
+template bool
+CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const InvokeInst &CI,
+                        unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+                        std::function<unsigned()> GetCalleeReg) const;
+
 template <typename FuncInfoTy>
 void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
                                const DataLayout &DL,
index 0f66bd9d1716cebcbc32940a718139fe0892df39..51613ab81f62d88c3dbbac9d9148d9b467e7af50 100644 (file)
@@ -733,17 +733,12 @@ bool IRTranslator::translateInvoke(const User &U,
   MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
 
   unsigned Res = I.getType()->isVoidTy() ? 0 : getOrCreateVReg(I);
-  SmallVector<CallLowering::ArgInfo, 8> Args;
+  SmallVector<unsigned, 8> Args;
   for (auto &Arg: I.arg_operands())
-    Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType());
+    Args.push_back(getOrCreateVReg(*Arg));
 
-  auto CalleeMO =
-      Fn ? MachineOperand::CreateGA(Fn, 0)
-         : MachineOperand::CreateReg(getOrCreateVReg(*Callee), false);
-
-  if (!CLI->lowerCall(MIRBuilder, CalleeMO,
-                      CallLowering::ArgInfo(Res, I.getType()), Args))
-    return false;
+ CLI->lowerCall(MIRBuilder, I, Res, Args,
+                 [&]() { return getOrCreateVReg(*I.getCalledValue()); });
 
   MCSymbol *EndSymbol = Context.createTempSymbol();
   MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
index 412f70e17b2cdd1935ab6a715e5ffc8e04f782e1..9cb3923fd2ad7c42f88e4cf184cc73e8f93927b4 100644 (file)
@@ -57,3 +57,34 @@ broken:
 continue:
   ret void
 }
+
+; CHECK-LABEL: name: test_invoke_varargs
+
+; CHECK: [[NULL:%[0-9]+]](p0) = G_CONSTANT i64 0
+; CHECK: [[ANSWER:%[0-9]+]](s32) = G_CONSTANT i32 42
+; CHECK: [[ONE:%[0-9]+]](s32) = G_FCONSTANT float 1.0
+
+; CHECK: %x0 = COPY [[NULL]]
+
+; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
+; CHECK: [[OFFSET:%[0-9]+]](s64) = G_CONSTANT i64 0
+; CHECK: [[SLOT:%[0-9]+]](p0) = G_GEP [[SP]], [[OFFSET]](s64)
+; CHECK: G_STORE [[ANSWER]](s32), [[SLOT]]
+
+; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
+; CHECK: [[OFFSET:%[0-9]+]](s64) = G_CONSTANT i64 8
+; CHECK: [[SLOT:%[0-9]+]](p0) = G_GEP [[SP]], [[OFFSET]](s64)
+; CHECK: G_STORE [[ONE]](s32), [[SLOT]]
+
+; CHECK: BL @printf
+declare void @printf(i8*, ...)
+define void @test_invoke_varargs() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+  invoke void(i8*, ...) @printf(i8* null, i32 42, float 1.0) to label %continue unwind label %broken
+
+broken:
+  landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
+  ret void
+
+continue:
+  ret void
+}