Anton,

Going back to the list now that it's working. :)

On 2008-01-04, at 08:22, Anton Korobeynikov wrote:

Hello, Gordon.

Here goes quick review.


+// Determines whether a CALL node uses struct return semantics.
+static bool CallIsStructReturn(SDOperand Op)
I like these predicates, because later we can move them to the
autogenerated code.

Yes!

+  // Decoarate the function name.
Typo

Okay.

+  if (Is64Bit && CC == CallingConv::X86_FastCall &&
+ !Subtarget->isTargetCygMing() && !Subtarget- >isTargetWindows() &&
+      (StackSize & 7) == 0)
and
+  if (!Is64Bit && CC == CallingConv::X86_FastCall &&
+ !Subtarget->isTargetCygMing() && !Subtarget- >isTargetWindows() &&
+      (NumBytes & 7) == 0)
+    NumBytes += 4;

The former is also a typo. It should definitely be !Is64Bit.

That's pretty interesting.

Indeed. I made some mechanical transformations where the rationale or invariants were unclear.

The source code was:
- if (!Subtarget->isTargetCygMing() && !Subtarget- >isTargetWindows()) {
-    // Make sure the instruction takes 8n+4 bytes to make sure the
start of the
- // arguments and the arguments after the retaddr has been pushed are
-    // aligned.
-    if ((NumBytes & 7) == 0)
-      NumBytes += 4;
-  }
-
Actually this is a hunk from the times, when fastcall and fastcc shared the same LowerFORMAL_ARGUMENTS call.
History tends to repeat itself. :)
The "funny" thing is that fastcall can be seen only on windows (32 bit!) targets, so the condition is twice bogus. Most probably the whole hunk should be just eliminated.

If you're sure, I'll happily delete the lot. But it doesn't look necessarily inert to me once the typo is fixed.

I think this should be sunken into GetAlignedArgumentStackSize if it remains, since it's always called something like this:

   unsigned NumBytes = CCInfo.getNextStackOffset();
   if (CC == CallingConv::Fast)
     NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);

+ // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned.
+  if (!Is64Bit && CC == CallingConv::X86_FastCall &&
+      !Subtarget->isTargetCygMing() && !Subtarget->isTargetWindows() &&
+      (NumBytes & 7) == 0)
+    NumBytes += 4;

Where GetAlignedArgumentStackSize is documented to…

/// GetAlignedArgumentStackSize - Make the stack size align e.g 16n + 12 aligned
/// for a 16 byte align requirement.

And is coded fairly generically, although I didn't dig deep enough to figure out whether GetAlignedArgumentStackSize would DTRT in this particular case. (getNextStackOffset won't; it's just an accumulator.) Ultimately, I think GetAlignedArgumentStackSize should do this bit's job, and the lot should be sunk into getNextStackOffset—but I was trying to be safe and incremental.


+  if (IsCalleePop(Op)) {
+    BytesToPopOnReturn  = StackSize; // Callee pops everything.
Maybe it will be better to make function return amount of bytes to pop and fold ArgsAreStructReturn() call there?

Maybe something like that. This logic is essentially duplicated in LowerCALL and LowerFORMAL_ARGUMENTS, except for the SDNode passed to IsStructReturn is of differing type. (IsCalleePop just happens to be looking at bits of FORMAL_ARGUMENTS or CALL nodes which are structurally identical; CallIsStructReturn and ArgsAreStructReturn don't have that luxury, though they could consult the SDNode's type.) The relevant passages:

  // Some CCs need callee pop.
  if (IsCalleePop(Op)) {
    BytesToPopOnReturn  = StackSize; // Callee pops everything.
    BytesCallerReserves = 0;
  } else {
    BytesToPopOnReturn  = 0; // Callee pops nothing.
// If this is an sret function, the return should pop the hidden pointer.
    if (!Is64Bit && ArgsAreStructReturn(Op))
      BytesToPopOnReturn = 4;
    BytesCallerReserves = StackSize;
  }
-----------------------------------------------------------------------------
  // Create the CALLSEQ_END node.
  unsigned NumBytesForCalleeToPush;
  if (IsCalleePop(Op))
    NumBytesForCalleeToPush = NumBytes;    // Callee pops everything
  else if (!Is64Bit && CallIsStructReturn(Op))
    // If this is is a call to a struct-return function, the callee
    // pops the hidden struct pointer, so we have to push it back.
    // This is common for Darwin/X86, Linux & Mingw32 targets.
    NumBytesForCalleeToPush = 4;
  else
    NumBytesForCalleeToPush = 0;  // Callee pops nothing.

+    if (IsTailCall || !Is64Bit ||
+        getTargetMachine().getCodeModel() != CodeModel::Large)
+      Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
getPointerTy());
I myself feel somehow inconvenient to have such condition here (mixing predicates of different sorts).

I don't like repeatedly consulting either PerformTailCallOpt/ IsTailCall or !Subtarget->is64Bit(). Rather, I'd prefer to have a table-driven system. I think that's a followup patch, though; this one is already too large.

Maybe it will be worth to keep 64 bit variant separate. I don't know. Evan?


The 64-bit code diverged only in a very few details.

— Gordon

_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to