[llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp IA64ISelLowering.h IA64ISelDAGToDAG.cpp

Duraid Madina duraid at octopus.com.au
Thu Dec 22 05:29:35 PST 2005



Changes in directory llvm/lib/Target/IA64:

IA64ISelLowering.cpp updated: 1.7 -> 1.8
IA64ISelLowering.h updated: 1.2 -> 1.3
IA64ISelDAGToDAG.cpp updated: 1.15 -> 1.16
---
Log message:

this is a hack, which may or may not hang around. In short:

whimper out of doing things the Right Way, and hack up a generic
'BRCALL' instruction, that gets generated when calls are lowered.
This gets selected by hand in the DAG isel, where it gets turned
into real (i.e. in tablegen) br.call instructions.

BUG: this dies on void calls, but seems to work otherwise?



---
Diffs of the changes:  (+112 -27)

 IA64ISelDAGToDAG.cpp |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 IA64ISelLowering.cpp |   65 ++++++++++++++++++++++++++++++-------------------
 IA64ISelLowering.h   |    7 +++--
 3 files changed, 112 insertions(+), 27 deletions(-)


Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp
diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.7 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.8
--- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.7	Thu Dec 22 00:39:57 2005
+++ llvm/lib/Target/IA64/IA64ISelLowering.cpp	Thu Dec 22 07:29:14 2005
@@ -291,6 +291,7 @@
 
   SDOperand StackPtr, NullSV;
   std::vector<SDOperand> Stores;
+  std::vector<SDOperand> Converts;
   std::vector<SDOperand> RegValuesToPass;
   unsigned ArgOffset = 16;
   
@@ -298,7 +299,7 @@
     {
       SDOperand Val = Args[i].first;
       MVT::ValueType ObjectVT = Val.getValueType();
-      SDOperand ValToStore;
+      SDOperand ValToStore, ValToConvert;
       unsigned ObjSize=8;
       switch (ObjectVT) {
       default: assert(0 && "unexpected argument type!");
@@ -330,6 +331,9 @@
           ValToStore = Val;
         } else {
           RegValuesToPass.push_back(Val);
+	  if(1 /* TODO: if(calling external or varadic function)*/ ) {
+	    ValToConvert = Val; // additionally pass this FP value as an int
+	  }
         }
         break;
       }
@@ -344,6 +348,10 @@
         Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                      ValToStore, PtrOff, NullSV));
       }
+
+      if(ValToConvert.Val) {
+	Converts.push_back(DAG.getNode(IA64ISD::GETFD, MVT::i64, ValToConvert)); 
+      }
       ArgOffset += ObjSize;
     }
 
@@ -379,6 +387,17 @@
   // mapped 1:1 and the FP args into regs F8-F15 "lazily"
   // TODO: for performance, we should only copy FP args into int regs when we
   // know this is required (i.e. for varardic or external (unknown) functions)
+
+  // first to the FP->(integer representation) conversions, these are
+  // free-floating
+  unsigned seenConverts = 0;
+  for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
+    if(MVT::isFloatingPoint(RegValuesToPass[i].getValueType())) {
+      Chain = DAG.getCopyToReg(Chain, IntArgRegs[i], Converts[seenConverts++]);
+    }
+  }
+
+  // next copy args into the usual places
   unsigned usedFPArgs = 0;
   for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
     Chain = DAG.getCopyToReg(Chain,
@@ -386,42 +405,34 @@
                                           IntArgRegs[i] : FPArgRegs[usedFPArgs++],
       RegValuesToPass[i], InFlag);
     InFlag = Chain.getValue(1);
-
-    //FIXME: for performance, only do the following when required
-    
-    // if we have just copied an FP arg, copy its in-memory representation
-    // to the appropriate integer register
-    if(MVT::isFloatingPoint(RegValuesToPass[i].getValueType())) {
-      std::vector<MVT::ValueType> GETFDRetTypes;
-      std::vector<SDOperand> GETFDOperands;
-      GETFDRetTypes.push_back(MVT::i64);
-      GETFDRetTypes.push_back(MVT::Flag);
-      GETFDOperands.push_back(RegValuesToPass[i]);
-      GETFDOperands.push_back(Chain);
-      GETFDOperands.push_back(InFlag);
-      
-      Chain = DAG.getNode(IA64ISD::GETFD, GETFDRetTypes, GETFDOperands);
-      Chain = DAG.getCopyToReg(Chain, IntArgRegs[i], Chain.getValue(0), Chain.getValue(1)); // ...thrice!
-      InFlag = Chain.getValue(1);
-    }
   }
 
-  std::vector<MVT::ValueType> RetVals;
-  RetVals.push_back(MVT::Other);
-  RetVals.push_back(MVT::Flag);
-
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
-  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+/*
+  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i64);
+  }
+*/
 
   std::vector<MVT::ValueType> NodeTys;
+  std::vector<SDOperand> CallOperands;
   NodeTys.push_back(MVT::Other);   // Returns a chain
   NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
+  CallOperands.push_back(Chain);
+  CallOperands.push_back(Callee);
+
+  // emit the call itself
   if (InFlag.Val)
+    CallOperands.push_back(InFlag);
+
+/* out with the old...
     Chain = SDOperand(DAG.getCall(NodeTys, Chain, Callee, InFlag), 0);
   else
     Chain = SDOperand(DAG.getCall(NodeTys, Chain, Callee), 0);
+*/
+  // to make way for a hack:
+  Chain = DAG.getNode(IA64ISD::BRCALL, NodeTys, CallOperands);
   InFlag = Chain.getValue(1);
 
   // restore the GP, SP and RP after the call  
@@ -431,7 +442,11 @@
   InFlag = Chain.getValue(1);
   Chain = DAG.getCopyToReg(Chain, IA64::rp, RPBeforeCall, InFlag);
   InFlag = Chain.getValue(1);
-  
+ 
+  std::vector<MVT::ValueType> RetVals;
+  RetVals.push_back(MVT::Other);
+  RetVals.push_back(MVT::Flag);
+ 
   MVT::ValueType RetTyVT = getValueType(RetTy);
   SDOperand RetVal;
   if (RetTyVT != MVT::isVoid) {


Index: llvm/lib/Target/IA64/IA64ISelLowering.h
diff -u llvm/lib/Target/IA64/IA64ISelLowering.h:1.2 llvm/lib/Target/IA64/IA64ISelLowering.h:1.3
--- llvm/lib/Target/IA64/IA64ISelLowering.h:1.2	Thu Dec 22 00:41:39 2005
+++ llvm/lib/Target/IA64/IA64ISelLowering.h	Thu Dec 22 07:29:14 2005
@@ -38,10 +38,13 @@
       /// operand, producing an f64 value containing the integer representation
       /// of that FP value.
       FCTIDZ, FCTIWZ,
-      
+
       /// GETFD - the getf.d instruction takes a floating point operand and
       /// returns its 64-bit memory representation as an i64
-      GETFD
+      GETFD,
+
+      // TODO: explain this hack
+      BRCALL
     };
   }  
   


Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp
diff -u llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.15 llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.16
--- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.15	Thu Dec 22 01:14:45 2005
+++ llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp	Thu Dec 22 07:29:14 2005
@@ -342,6 +342,73 @@
   default: break;
 
   case ISD::Register: return Op; // XXX: this is a hack, tblgen one day?
+ 
+  case IA64ISD::BRCALL: { // XXX: this is also a hack!
+    SDOperand Chain = Select(N->getOperand(0));
+    SDOperand InFlag;  // Null incoming flag value.
+
+    if(N->getNumOperands()==3) // we have an incoming chain, callee and flag
+      InFlag = Select(N->getOperand(2));
+
+    unsigned CallOpcode;
+    SDOperand CallOperand;
+    std::vector<MVT::ValueType> TypeOperands;
+    
+    // if we can call directly, do so
+    if (GlobalAddressSDNode *GASD =
+      dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
+      CallOpcode = IA64::BRCALL_IPREL_GA;
+      CallOperand = CurDAG->getTargetGlobalAddress(GASD->getGlobal(), MVT::i64);
+    } else if (ExternalSymbolSDNode *ESSDN = // FIXME: we currently NEED this
+		                         // case for correctness, to avoid
+					 // "non-pic code with imm reloc.n
+					 // against dynamic symbol" errors
+             dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
+    CallOpcode = IA64::BRCALL_IPREL_ES;
+    CallOperand = N->getOperand(1);
+  } else {
+    // otherwise we need to load the function descriptor,
+    // load the branch target (function)'s entry point and GP,
+    // branch (call) then restore the GP
+    SDOperand FnDescriptor = Select(N->getOperand(1));
+   
+    // load the branch target's entry point [mem] and 
+    // GP value [mem+8]
+    SDOperand targetEntryPoint=CurDAG->getTargetNode(IA64::LD8, MVT::i64,
+		    FnDescriptor);
+    Chain = targetEntryPoint.getValue(1);
+    SDOperand targetGPAddr=CurDAG->getTargetNode(IA64::ADDS, MVT::i64, 
+		    FnDescriptor, CurDAG->getConstant(8, MVT::i64));
+    Chain = targetGPAddr.getValue(1);
+    SDOperand targetGP=CurDAG->getTargetNode(IA64::LD8, MVT::i64,
+		    targetGPAddr);
+    Chain = targetGP.getValue(1);
+
+    Chain = CurDAG->getCopyToReg(Chain, IA64::r1, targetGP, InFlag);
+    InFlag = Chain.getValue(1);
+    Chain = CurDAG->getCopyToReg(Chain, IA64::B6, targetEntryPoint, InFlag); // FLAG these?
+    InFlag = Chain.getValue(1);
+    
+    CallOperand = CurDAG->getRegister(IA64::B6, MVT::i64);
+    CallOpcode = IA64::BRCALL_INDIRECT;
+  }
+ 
+   // Finally, once everything is setup, emit the call itself
+   if(InFlag.Val)
+     Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, CallOperand, Chain, InFlag);
+   else // there might be no arguments
+     Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, CallOperand, Chain);
+   InFlag = Chain.getValue(1);
+
+   std::vector<SDOperand> CallResults;
+
+   CallResults.push_back(Chain);
+   CallResults.push_back(InFlag);
+
+   for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
+     CodeGenMap[Op.getValue(i)] = CallResults[i];
+   return CallResults[Op.ResNo];
+  }
   
   case IA64ISD::GETFD: {
     SDOperand Input = Select(N->getOperand(0));






More information about the llvm-commits mailing list