[llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.cpp SparcInternals.h PrologEpilogCodeInserter.cpp

vadve at cs.uiuc.edu vadve at cs.uiuc.edu
Mon Sep 16 10:46:01 PDT 2002


Changes in directory llvm/lib/Target/Sparc:

Sparc.cpp updated: 1.44 -> 1.45
SparcInternals.h updated: 1.62 -> 1.63
PrologEpilogCodeInserter.cpp updated: 1.12 -> 1.13

---
Log message:

Move all the code that creates code generation passes from Sparc.cpp to
TargetMachine.cpp, since it is entirely machine-independent.
Also, add options to disable optional back-end passes (preselection and
instr. scheduling).


---
Diffs of the changes:

Index: llvm/lib/Target/Sparc/Sparc.cpp
diff -u llvm/lib/Target/Sparc/Sparc.cpp:1.44 llvm/lib/Target/Sparc/Sparc.cpp:1.45
--- llvm/lib/Target/Sparc/Sparc.cpp:1.44	Tue Aug 27 11:45:17 2002
+++ llvm/lib/Target/Sparc/Sparc.cpp	Mon Sep 16 10:39:26 2002
@@ -7,16 +7,9 @@
 
 #include "SparcInternals.h"
 #include "llvm/Target/Sparc.h"
-#include "llvm/CodeGen/InstrScheduling.h"
-#include "llvm/CodeGen/InstrSelection.h"
-#include "llvm/CodeGen/MachineCodeForInstruction.h"
-#include "llvm/CodeGen/MachineCodeForMethod.h"
-#include "llvm/CodeGen/RegisterAllocation.h"
-#include "llvm/Reoptimizer/Mapping/MappingInfo.h" 
-#include "llvm/Reoptimizer/Mapping/FInfo.h" 
 #include "llvm/Function.h"
 #include "llvm/BasicBlock.h"
-#include "llvm/PassManager.h"
+#include "llvm/CodeGen/MachineCodeForMethod.h"
 #include <iostream>
 using std::cerr;
 
@@ -90,6 +83,8 @@
   // dynamic-size alloca.
   pos = false;
   unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
+  if (int extra = optArgsSize % getStackFrameSizeAlignment())
+    optArgsSize += (getStackFrameSizeAlignment() - extra);
   int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
   assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
   return offset;
@@ -118,86 +113,5 @@
   optSizeForSubWordData = 4;
   minMemOpWordSize = 8; 
   maxAtomicMemOpWordSize = 8;
-}
-
-
-
-//===---------------------------------------------------------------------===//
-// GenerateCodeForTarget Pass
-// 
-// Native code generation for a specified target.
-//===---------------------------------------------------------------------===//
-
-class ConstructMachineCodeForFunction : public FunctionPass {
-  TargetMachine &Target;
-public:
-  inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
-
-  const char *getPassName() const {
-    return "Sparc ConstructMachineCodeForFunction";
-  }
-
-  bool runOnFunction(Function &F) {
-    MachineCodeForMethod::construct(&F, Target);
-    return false;
-  }
-};
-
-struct FreeMachineCodeForFunction : public FunctionPass {
-  const char *getPassName() const { return "Sparc FreeMachineCodeForFunction"; }
-
-  static void freeMachineCode(Instruction &I) {
-    MachineCodeForInstruction::destroy(&I);
-  }
-  
-  bool runOnFunction(Function &F) {
-    for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
-      for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
-        MachineCodeForInstruction::get(I).dropAllReferences();
-    
-    for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
-      for_each(FI->begin(), FI->end(), freeMachineCode);
-    
-    return false;
-  }
-};
-
-// addPassesToEmitAssembly - This method controls the entire code generation
-// process for the ultra sparc.
-//
-void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
-  // Construct and initialize the MachineCodeForMethod object for this fn.
-  PM.add(new ConstructMachineCodeForFunction(*this));
-
-  PM.add(createInstructionSelectionPass(*this));
-
-  PM.add(createInstructionSchedulingWithSSAPass(*this));
-
-  PM.add(getRegisterAllocator(*this));
-  
-  //PM.add(new OptimizeLeafProcedures());
-  //PM.add(new DeleteFallThroughBranches());
-  //PM.add(new RemoveChainedBranches());    // should be folded with previous
-  //PM.add(new RemoveRedundantOps());       // operations with %g0, NOP, etc.
-  
-  PM.add(createPrologEpilogCodeInserter(*this));
-
-  PM.add(MappingInfoForFunction(Out));  
-
-  // Output assembly language to the .s file.  Assembly emission is split into
-  // two parts: Function output and Global value output.  This is because
-  // function output is pipelined with all of the rest of code generation stuff,
-  // allowing machine code representations for functions to be free'd after the
-  // function has been emitted.
-  //
-  PM.add(getFunctionAsmPrinterPass(PM, Out));
-  PM.add(new FreeMachineCodeForFunction());  // Free stuff no longer needed
- 
-  // Emit Module level assembly after all of the functions have been processed.
-  PM.add(getModuleAsmPrinterPass(PM, Out));
-
-  // Emit bytecode to the sparc assembly file into its special section next
-  PM.add(getEmitBytecodeToAsmPass(Out));
-  PM.add(getFunctionInfo(Out)); 
 }
 


Index: llvm/lib/Target/Sparc/SparcInternals.h
diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.62 llvm/lib/Target/Sparc/SparcInternals.h:1.63
--- llvm/lib/Target/Sparc/SparcInternals.h:1.62	Thu Sep  5 13:34:31 2002
+++ llvm/lib/Target/Sparc/SparcInternals.h	Mon Sep 16 10:39:26 2002
@@ -21,8 +21,6 @@
 class PhyRegAlloc;
 class Pass;
 
-Pass *createPrologEpilogCodeInserter(TargetMachine &TM);
-
 // OpCodeMask definitions for the Sparc V9
 // 
 const OpCodeMask	Immed		= 0x00002000; // immed or reg operand?
@@ -88,7 +86,7 @@
 
   //
   // All immediate constants are in position 1 except the
-  // store instructions.
+  // store instructions and SETxx.
   // 
   virtual int getImmedConstantPos(MachineOpCode opCode) const {
     bool ignore;
@@ -96,7 +94,11 @@
       {
         assert(! this->isStore((MachineOpCode) STB - 1)); // 1st  store opcode
         assert(! this->isStore((MachineOpCode) STXFSR+1));// last store opcode
-        return (opCode >= STB && opCode <= STXFSR)? 2 : 1;
+        if (opCode==SETSW || opCode==SETUW || opCode==SETX || opCode==SETHI)
+          return 0;
+        if (opCode >= STB && opCode <= STXFSR)
+          return 2;
+        return 1;
       }
     else
       return -1;
@@ -114,6 +116,13 @@
   }
 
   //-------------------------------------------------------------------------
+  // Queries about representation of LLVM quantities (e.g., constants)
+  //-------------------------------------------------------------------------
+
+  virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
+                                             const Instruction* I) const;
+
+  //-------------------------------------------------------------------------
   // Code generation support for creating individual machine instructions
   //-------------------------------------------------------------------------
   
@@ -538,13 +547,22 @@
   UltraSparcFrameInfo(const TargetMachine &tgt) : MachineFrameInfo(tgt) {}
   
 public:
+  // These methods provide constant parameters of the frame layout.
+  // 
   int  getStackFrameSizeAlignment() const { return StackFrameSizeAlignment;}
   int  getMinStackFrameSize()       const { return MinStackFrameSize; }
   int  getNumFixedOutgoingArgs()    const { return NumFixedOutgoingArgs; }
   int  getSizeOfEachArgOnStack()    const { return SizeOfEachArgOnStack; }
   bool argsOnStackHaveFixedSize()   const { return true; }
 
-  //
+  // This method adjusts a stack offset to meet alignment rules of target.
+  // The fixed OFFSET (0x7ff) must be subtracted and the result aligned.
+  virtual int  adjustAlignment                  (int unalignedOffset,
+                                                 bool growUp,
+                                                 unsigned int align) const {
+    return unalignedOffset + (growUp? +1:-1)*((unalignedOffset-OFFSET) % align);
+  }
+
   // These methods compute offsets using the frame contents for a
   // particular function.  The frame contents are obtained from the
   // MachineCodeInfoForMethod object for the given function.
@@ -601,15 +619,58 @@
   }
   
 private:
+  /*----------------------------------------------------------------------
+    This diagram shows the stack frame layout used by llc on Sparc V9.
+    Note that only the location of automatic variables, spill area,
+    temporary storage, and dynamically allocated stack area are chosen
+    by us.  The rest conform to the Sparc V9 ABI.
+    All stack addresses are offset by OFFSET = 0x7ff (2047).
+
+    Alignment assumpteions and other invariants:
+    (1) %sp+OFFSET and %fp+OFFSET are always aligned on 16-byte boundary
+    (2) Variables in automatic, spill, temporary, or dynamic regions
+        are aligned according to their size as in all memory accesses.
+    (3) Everything below the dynamically allocated stack area is only used
+        during a call to another function, so it is never needed when
+        the current function is active.  This is why space can be allocated
+        dynamically by incrementing %sp any time within the function.
+    
+    STACK FRAME LAYOUT:
+
+       ...
+       %fp+OFFSET+176      Optional extra incoming arguments# 1..N
+       %fp+OFFSET+168      Incoming argument #6
+       ...                 ...
+       %fp+OFFSET+128      Incoming argument #1
+       ...                 ...
+    ---%fp+OFFSET-0--------Bottom of caller's stack frame--------------------
+       %fp+OFFSET-8        Automatic variables <-- ****TOP OF STACK FRAME****
+                           Spill area
+                           Temporary storage
+       ...
+
+       %sp+OFFSET+176+8N   Bottom of dynamically allocated stack area
+       %sp+OFFSET+168+8N   Optional extra outgoing argument# N
+       ...                 ...
+       %sp+OFFSET+176      Optional extra outgoing argument# 1
+       %sp+OFFSET+168      Outgoing argument #6
+       ...                 ...
+       %sp+OFFSET+128      Outgoing argument #1
+       %sp+OFFSET+120      Save area for %i7
+       ...                 ...
+       %sp+OFFSET+0        Save area for %l0 <-- ****BOTTOM OF STACK FRAME****
+
+   *----------------------------------------------------------------------*/
+
   // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
   static const int OFFSET                                  = (int) 0x7ff;
   static const int StackFrameSizeAlignment                 =  16;
   static const int MinStackFrameSize                       = 176;
   static const int NumFixedOutgoingArgs                    =   6;
   static const int SizeOfEachArgOnStack                    =   8;
-  static const int StaticAreaOffsetFromFP                  =  0 + OFFSET;
   static const int FirstIncomingArgOffsetFromFP            = 128 + OFFSET;
   static const int FirstOptionalIncomingArgOffsetFromFP    = 176 + OFFSET;
+  static const int StaticAreaOffsetFromFP                  =   0 + OFFSET;
   static const int FirstOutgoingArgOffsetFromSP            = 128 + OFFSET;
   static const int FirstOptionalOutgoingArgOffsetFromSP    = 176 + OFFSET;
 };
@@ -655,16 +716,17 @@
   virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
   virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
 
-  //
-  // addPassesToEmitAssembly - Add passes to the specified pass manager to get
-  // assembly langage code emited.  For sparc, we have to do ...
-  //
-  virtual void addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
+  // getPrologEpilogCodeInserter - Inserts prolog/epilog code.
+  virtual Pass* getPrologEpilogInsertionPass();
 
-private:
-  Pass *getFunctionAsmPrinterPass(PassManager &PM, std::ostream &Out);
-  Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out);
-  Pass *getEmitBytecodeToAsmPass(std::ostream &Out);
+  // getFunctionAsmPrinterPass - Writes out machine code for a single function
+  virtual Pass* getFunctionAsmPrinterPass(std::ostream &Out);
+
+  // getModuleAsmPrinterPass - Writes generated machine code to assembly file.
+  virtual Pass* getModuleAsmPrinterPass(std::ostream &Out);
+
+  // getEmitBytecodeToAsmPass - Emits final LLVM bytecode to assembly file.
+  virtual Pass* getEmitBytecodeToAsmPass(std::ostream &Out);
 };
 
 #endif


Index: llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
diff -u llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.12 llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.13
--- llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.12	Mon Aug 12 16:25:04 2002
+++ llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp	Mon Sep 16 10:39:26 2002
@@ -162,6 +162,6 @@
   }
 }
 
-Pass *createPrologEpilogCodeInserter(TargetMachine &TM) {
-  return new InsertPrologEpilogCode(TM);
+Pass* UltraSparc::getPrologEpilogInsertionPass() {
+  return new InsertPrologEpilogCode(*this);
 }





More information about the llvm-commits mailing list