[LLVMdev] [PATCH] New calling convention for use by GHC

Chris Lattner clattner at apple.com
Wed Mar 3 13:19:03 PST 2010


On Mar 2, 2010, at 5:33 PM, David Terei wrote:

> Hi all,
> 
> As previously mentioned on this list the Haskell compiler GHC has a new LLVM based back-end. The back-end needs a new calling convention to efficiently use LLVM and that is what this patch does, just for X86 at the moment.

Nice, 

> The GHC developers would love to get this included in LLVM so that we don't need to carry around our own version of LLVM. If this patch isn't something that you would want to include in LLVM can you suggest an alternative way to do this that you would consider including?

Yes, I'd like to get this in, preferably before 2.7 branches in a couple days.  A couple questions:

1) is the GHC calling conv intended to be target specific?  If it is x86 specific, it should get an X86 prefix.  If not, it should move up to be #10 after Cold.

2) In either case, please document the new calling convention in docs/LangRef.html#callingconv

3) IN X86RegisterInfo.cpp, this patch:

   if (Is64Bit) {
     if (IsWin64)
-      return CalleeSavedRegsWin64;
+      return (ghcCall ? GhcCalleeSavedRegsWin64 : CalleeSavedRegsWin64);
     else
-      return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
+      if (ghcCall)
+        return (callsEHReturn ?
+                  GhcCalleeSavedRegs64EHRet : GhcCalleeSavedRegs64Bit);
+      else
+        return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);

Seems like it could be simplified.  Have you tested the Win64 support?  It isn't clear why your patch needs to depend on the host ABI here.  Also, does EHRet matter for your calling conv?


4) In X86ISelLowering.cpp:

-    if (!Is64Bit && CallConv != CallingConv::Fast && ArgsAreStructReturn(Ins))
+    if (!Is64Bit && CallConv != CallingConv::Fast &&
+          CallConv != CallingConv::GHC && ArgsAreStructReturn(Ins))

This should probably use !IsTailCallConvention(CallConv) instead of duplicating the two conventions

   assert(!(isVarArg && CallConv == CallingConv::Fast) &&
          "Var args not supported with calling convention fastcc");
+  assert(!(isVarArg && CallConv == CallingConv::GHC) &&
+         "Var args not supported with calling convention ghc");

Likewise.

@@ -2151,7 +2168,8 @@
   unsigned NumBytesForCalleeToPush;
   if (IsCalleePop(isVarArg, CallConv))
     NumBytesForCalleeToPush = NumBytes;    // Callee pops everything
-  else if (!Is64Bit && CallConv != CallingConv::Fast && IsStructRet)
+  else if (!Is64Bit && CallConv != CallingConv::Fast &&
+             CallConv != CallingConv::GHC && IsStructRet)

Likewise.

5) Please include a .ll testcase that uses the new calling conv and shows that the arguments are getting passed right.  For example it could take two ints add them together and return it, the generated code should show the assigned registers.

Otherwise the patch looks great, please resend a new spin of it and I'll commit it.  Thanks! Also, congrats on the great work on LLVM+GHC,

-Chris





More information about the llvm-dev mailing list