When opcodes like ADD were split into reg. and immed. versions (ADDi and ADDr),
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9PreSelection.cpp
index 012956220c65d86ff2bfb9df10d54511560be9bb..6f17b52b0a033989bb9758e4887d57efcb4e6902 100644 (file)
@@ -1,4 +1,11 @@
 //===- PreSelection.cpp - Specialize LLVM code for target machine ---------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This file defines the PreSelection pass which specializes LLVM code for a
 // target machine, while remaining in legal portable LLVM form and
@@ -8,9 +15,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/PreSelection.h"
+#include "SparcInternals.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/MachineInstrInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Module.h"
 #include "llvm/iOther.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Pass.h"
-#include "llvm/Annotation.h"
 #include "Support/CommandLine.h"
-#include "Support/NonCopyable.h"
 #include <algorithm>
-using namespace std;
 
 namespace {
   //===--------------------------------------------------------------------===//
@@ -55,15 +59,16 @@ namespace {
   // A single GlobalVariable is created for each constant in the pool
   // representing the memory for that constant.  
   // 
-  static AnnotationID CPFM_AID(
+  AnnotationID CPFM_AID(
                  AnnotationManager::getID("CodeGen::ConstantPoolForModule"));
 
-  class ConstantPoolForModule: private Annotation, public NonCopyable {
+  class ConstantPoolForModule : private Annotation {
     Module* myModule;
     std::map<const Constant*, GlobalVariable*> gvars;
     std::map<const Constant*, GlobalVariable*> origGVars;
     ConstantPoolForModule(Module* M);   // called only by annotation builder
-    ConstantPoolForModule();            // do not implement
+    ConstantPoolForModule();                      // DO NOT IMPLEMENT
+    void operator=(const ConstantPoolForModule&); // DO NOT IMPLEMENT
   public:
     static ConstantPoolForModule& get(Module* M) {
       ConstantPoolForModule* cpool =
@@ -90,7 +95,8 @@ namespace {
             GV = PI->second;            // put in map
           else
             {
-              GV = new GlobalVariable(CV->getType(), true,true,CV); //put in map
+              GV = new GlobalVariable(CV->getType(), true, //put in map
+                                      GlobalValue::InternalLinkage, CV);
               myModule->getGlobalList().push_back(GV); // GV owned by module now
             }
         }
@@ -110,12 +116,11 @@ namespace {
 
   //===--------------------------------------------------------------------===//
   // PreSelection Pass - Specialize LLVM code for the current target machine.
-  // This was and will be a basicblock pass, but make it a FunctionPass until
-  // BasicBlockPass ::doFinalization(Function&) is available.
   // 
   class PreSelection : public BasicBlockPass, public InstVisitor<PreSelection>
   {
     const TargetMachine &target;
+    const TargetInstrInfo &instrInfo;
     Function* function;
 
     GlobalVariable* getGlobalForConstant(Constant* CV) {
@@ -124,7 +129,8 @@ namespace {
     }
 
   public:
-    PreSelection (const TargetMachine &T): target(T), function(NULL) {}
+    PreSelection (const TargetMachine &T):
+      target(T), instrInfo(T.getInstrInfo()), function(NULL) {}
 
     // runOnBasicBlock - apply this pass to each BB
     bool runOnBasicBlock(BasicBlock &BB) {
@@ -135,30 +141,34 @@ namespace {
 
     bool doFinalization(Function &F) {
       if (PreSelectDebugLevel >= PreSelect_PrintOutput)
-        cerr << "\n\n*** LLVM code after pre-selection for function "
-             << F.getName() << ":\n\n" << F;
+        std::cerr << "\n\n*** LLVM code after pre-selection for function "
+                  << F.getName() << ":\n\n" << F;
       return false;
     }
 
     // These methods do the actual work of specializing code
     void visitInstruction(Instruction &I);   // common work for every instr. 
     void visitGetElementPtrInst(GetElementPtrInst &I);
-    void visitLoadInst(LoadInst &I);
-    void visitCastInst(CastInst &I);
-    void visitStoreInst(StoreInst &I);
+    void visitCallInst(CallInst &I);
 
     // Helper functions for visiting operands of every instruction
-    void visitOperands(Instruction &I);    // work on all operands of instr.
-    void visitOneOperand(Instruction &I, Constant* CV, unsigned opNum,
-                         Instruction& insertBefore); // iworks on one operand
+    // 
+    // visitOperands() works on every operand in [firstOp, lastOp-1].
+    // If lastOp==0, lastOp defaults to #operands or #incoming Phi values.
+    // 
+    // visitOneOperand() does all the work for one operand.
+    // 
+    void visitOperands(Instruction &I, int firstOp=0, int lastOp=0);
+    void visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
+                         Instruction& insertBefore);
   };
-}  // end anonymous namespace
 
+  // Register the pass...
+  RegisterOpt<PreSelection> X("preselect",
+                              "Specialize LLVM code for a target machine",
+                              createPreSelectionPass);
+}  // end anonymous namespace
 
-// Register the pass...
-static RegisterOpt<PreSelection> X("preselect",
-                                   "Specialize LLVM code for a target machine",
-                                   createPreSelectionPass);
 
 //------------------------------------------------------------------------------
 // Helper functions used by methods of class PreSelection
@@ -171,7 +181,7 @@ static GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction& insertBefore)
   if (isa<ConstantPointerRef>(ptr))
     ptr = cast<ConstantPointerRef>(ptr)->getValue();
 
-  return (isa<GlobalValue>(ptr))
+  return (isa<GlobalVariable>(ptr))
     ? new GetElementPtrInst(ptr,
                     std::vector<Value*>(1, ConstantSInt::get(Type::LongTy, 0U)),
                     "addrOfGlobal", &insertBefore)
@@ -231,99 +241,52 @@ static Instruction* DecomposeConstantExpr(ConstantExpr* CE,
 //------------------------------------------------------------------------------
 // Instruction visitor methods to perform instruction-specific operations
 //------------------------------------------------------------------------------
-
-// Common work for *all* instructions.  This needs to be called explicitly
-// by other visit<InstructionType> functions.
 inline void
-PreSelection::visitInstruction(Instruction &I)
-{ 
-  visitOperands(I);              // Perform operand transformations
-}
-
-
-// GetElementPtr instructions: check if pointer is a global
-void
-PreSelection::visitGetElementPtrInst(GetElementPtrInst &I)
-{ 
-  // Check for a global and put its address into a register before this instr
-  if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
-    I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
-
-  // Decompose multidimensional array references
-  DecomposeArrayRef(&I);
-
-  // Perform other transformations common to all instructions
-  visitInstruction(I);
-}
-
-
-// Load instructions: check if pointer is a global
-void
-PreSelection::visitLoadInst(LoadInst &I)
-{ 
-  // Check for a global and put its address into a register before this instr
-  if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
-    I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
-
-  // Perform other transformations common to all instructions
-  visitInstruction(I);
-}
-
-
-// Store instructions: check if pointer is a global
-void
-PreSelection::visitStoreInst(StoreInst &I)
-{ 
-  // Check for a global and put its address into a register before this instr
-  if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
-    I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
-
-  // Perform other transformations common to all instructions
-  visitInstruction(I);
-}
+PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
+                              Instruction& insertBefore)
+{
+  assert(&insertBefore != NULL && "Must have instruction to insert before.");
 
+  if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) {
+    I.setOperand(opNum, gep);           // replace global operand
+    return;                             // nothing more to do for this op.
+  }
 
-// Cast instructions:
-// -- check if argument is a global
-// -- make multi-step casts explicit:
-//    -- float/double to uint32_t:
-//         If target does not have a float-to-unsigned instruction, we
-//         need to convert to uint64_t and then to uint32_t, or we may
-//         overflow the signed int representation for legal uint32_t
-//         values.  Expand this without checking target.
-// 
-void
-PreSelection::visitCastInst(CastInst &I)
-{ 
-  CastInst* castI = NULL;
+  Constant* CV  = dyn_cast<Constant>(Op);
+  if (CV == NULL)
+    return;
 
-  // Check for a global and put its address into a register before this instr
-  if (GetElementPtrInst* gep = getGlobalAddr(I.getOperand(0), I))
-    {
-      I.setOperand(0, gep);             // replace pointer operand
+  if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
+    { // load-time constant: factor it out so we optimize as best we can
+      Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore);
+      I.setOperand(opNum, computeConst); // replace expr operand with result
+    }
+  else if (instrInfo.ConstantTypeMustBeLoaded(CV))
+    { // load address of constant into a register, then load the constant
+      GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV),
+                                             insertBefore);
+      LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore);
+      I.setOperand(opNum, ldI);        // replace operand with copy in v.reg.
     }
-  else if (I.getType() == Type::UIntTy &&
-           I.getOperand(0)->getType()->isFloatingPoint())
-    { // insert a cast-fp-to-long before I, and then replace the operand of I
-      castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I);
-      I.setOperand(0, castI);           // replace fp operand with long
+  else if (instrInfo.ConstantMayNotFitInImmedField(CV, &I))
+    { // put the constant into a virtual register using a cast
+      CastInst* castI = new CastInst(CV, CV->getType(), "copyConst",
+                                     &insertBefore);
+      I.setOperand(opNum, castI);      // replace operand with copy in v.reg.
     }
-
-  // Perform other transformations common to all instructions
-  visitInstruction(I);
-  if (castI)
-    visitInstruction(*castI);
 }
 
-
 // visitOperands() transforms individual operands of all instructions:
 // -- Load "large" int constants into a virtual register.  What is large
 //    depends on the type of instruction and on the target architecture.
 // -- For any constants that cannot be put in an immediate field,
 //    load address into virtual register first, and then load the constant.
 // 
-void
-PreSelection::visitOperands(Instruction &I)
+// firstOp and lastOp can be used to skip leading and trailing operands.
+// If lastOp is 0, it defaults to #operands or #incoming Phi values.
+//  
+inline void
+PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp)
 {
   // For any instruction other than PHI, copies go just before the instr.
   // For a PHI, operand copies must be before the terminator of the
@@ -332,39 +295,61 @@ PreSelection::visitOperands(Instruction &I)
   // 
   if (PHINode* phi = dyn_cast<PHINode>(&I))
     {
-      for (unsigned i=0, N=phi->getNumIncomingValues(); i < N; ++i)
-        if (Constant* CV = dyn_cast<Constant>(phi->getIncomingValue(i)))
-          this->visitOneOperand(I, CV, phi->getOperandNumForIncomingValue(i),
-                                * phi->getIncomingBlock(i)->getTerminator());
+      if (lastOp == 0)
+        lastOp = phi->getNumIncomingValues();
+      for (unsigned i=firstOp, N=lastOp; i < N; ++i)
+        this->visitOneOperand(I, phi->getIncomingValue(i),
+                              phi->getOperandNumForIncomingValue(i),
+                              * phi->getIncomingBlock(i)->getTerminator());
     }
   else
-    for (unsigned i=0, N=I.getNumOperands(); i < N; ++i)
-      if (Constant* CV = dyn_cast<Constant>(I.getOperand(i)))
-        this->visitOneOperand(I, CV, i, I);
+    {
+      if (lastOp == 0)
+        lastOp = I.getNumOperands();
+      for (unsigned i=firstOp, N=lastOp; i < N; ++i)
+        this->visitOneOperand(I, I.getOperand(i), i, I);
+    }
 }
 
+
+
+// Common work for *all* instructions.  This needs to be called explicitly
+// by other visit<InstructionType> functions.
+inline void
+PreSelection::visitInstruction(Instruction &I)
+{ 
+  visitOperands(I);              // Perform operand transformations
+}
+
+
+// GetElementPtr instructions: check if pointer is a global
 void
-PreSelection::visitOneOperand(Instruction &I, Constant* CV, unsigned opNum,
-                              Instruction& insertBefore)
+PreSelection::visitGetElementPtrInst(GetElementPtrInst &I)
+{ 
+  Instruction* curI = &I;
+
+  // Decompose multidimensional array references
+  if (I.getNumIndices() >= 2) {
+    // DecomposeArrayRef() replaces I and deletes it, if successful,
+    // so remember predecessor in order to find the replacement instruction.
+    // Also remember the basic block in case there is no predecessor.
+    Instruction* prevI = I.getPrev();
+    BasicBlock* bb = I.getParent();
+    if (DecomposeArrayRef(&I))
+      // first instr. replacing I
+      curI = cast<GetElementPtrInst>(prevI? prevI->getNext() : &bb->front());
+  }
+
+  // Perform other transformations common to all instructions
+  visitInstruction(*curI);
+}
+
+
+void
+PreSelection::visitCallInst(CallInst &I)
 {
-  if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
-    { // load-time constant: factor it out so we optimize as best we can
-      Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore);
-      I.setOperand(opNum, computeConst); // replace expr operand with result
-    }
-  else if (target.getInstrInfo().ConstantTypeMustBeLoaded(CV))
-    { // load address of constant into a register, then load the constant
-      GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV),
-                                             insertBefore);
-      LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore);
-      I.setOperand(opNum, ldI);        // replace operand with copy in v.reg.
-    }
-  else if (target.getInstrInfo().ConstantMayNotFitInImmedField(CV, &I))
-    { // put the constant into a virtual register using a cast
-      CastInst* castI = new CastInst(CV, CV->getType(), "copyConst",
-                                     &insertBefore);
-      I.setOperand(opNum, castI);      // replace operand with copy in v.reg.
-    }
+  // Tell visitOperands to ignore the function name if this is a direct call.
+  visitOperands(I, (/*firstOp=*/ I.getCalledFunction()? 1 : 0));
 }