X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9TargetMachine.cpp;h=28b9734361c159ab7aaefdc83c7390dfd4e9fe34;hb=d344242f2e1e4a2ca272ee140a991141eedaa279;hp=aac247adf71b3633d4e169f6b26eaa7356b69d8c;hpb=9db43184ca8639764f4da431fdbd022a9b02c344;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9TargetMachine.cpp b/lib/Target/SparcV9/SparcV9TargetMachine.cpp index aac247adf71..28b9734361c 100644 --- a/lib/Target/SparcV9/SparcV9TargetMachine.cpp +++ b/lib/Target/SparcV9/SparcV9TargetMachine.cpp @@ -1,23 +1,17 @@ -// $Id$ -//*************************************************************************** -// File: -// Sparc.cpp -// -// Purpose: -// -// History: -// 7/15/01 - Vikram Adve - Created -//**************************************************************************/ - +//===-- Sparc.cpp - General implementation file for the Sparc Target ------===// +// +// This file contains the code for the Sparc Target that does not fit in any of +// the other files in this directory. +// +//===----------------------------------------------------------------------===// #include "SparcInternals.h" #include "llvm/Target/Sparc.h" -#include "llvm/CodeGen/InstrScheduling.h" -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/CodeGen/PhyRegAlloc.h" -#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h" -#include "llvm/Method.h" - +#include "llvm/Function.h" +#include "llvm/BasicBlock.h" +#include "llvm/CodeGen/MachineCodeForMethod.h" +#include +using std::cerr; // Build the MachineInstruction Description Array... const MachineInstrDescriptor SparcMachineInstrDesc[] = { @@ -32,199 +26,69 @@ const MachineInstrDescriptor SparcMachineInstrDesc[] = { // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface) //---------------------------------------------------------------------------- -// TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); } -//---------------------------------------------------------------------------- -// Entry point for register allocation for a module -//---------------------------------------------------------------------------- - -void AllocateRegisters(Method *M, TargetMachine &target) -{ - - if ( (M)->isExternal() ) // don't process prototypes - return; - - if( DEBUG_RA ) { - cerr << endl << "******************** Method "<< (M)->getName(); - cerr << " ********************" <getMachineCode().incrementStackSize(minFrameSize); -} - -//--------------------------------------------------------------------------- -// Function InsertPrologCode -// Function InsertEpilogCode -// Function InsertPrologEpilog -// -// Insert prolog code at the unique method entry point. -// Insert epilog code at each method exit point. -// InsertPrologEpilog invokes these only if the method is not compiled -// with the leaf method optimization. -//--------------------------------------------------------------------------- - -static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR]; - -static void -InsertPrologCode(Method* method, TargetMachine& target) -{ - BasicBlock* entryBB = method->getEntryNode(); - unsigned N = GetInstructionsForProlog(entryBB, target, minstrVec); - assert(N <= MAX_INSTR_PER_VMINSTR); - if (N > 0) - { - MachineCodeForBasicBlock& bbMvec = entryBB->getMachineInstrVec(); - bbMvec.insert(bbMvec.begin(), minstrVec, minstrVec+N); - } -} - - -static void -InsertEpilogCode(Method* method, TargetMachine& target) -{ - for (Method::iterator I=method->begin(), E=method->end(); I != E; ++I) - if ((*I)->getTerminator()->getOpcode() == Instruction::Ret) - { - BasicBlock* exitBB = *I; - unsigned N = GetInstructionsForEpilog(exitBB, target, minstrVec); - - MachineCodeForBasicBlock& bbMvec = exitBB->getMachineInstrVec(); - MachineCodeForVMInstr& termMvec = - exitBB->getTerminator()->getMachineInstrVec(); - - // Remove the NOPs in the delay slots of the return instruction - const MachineInstrInfo& mii = target.getInstrInfo(); - unsigned numNOPs = 0; - while (termMvec.back()->getOpCode() == NOP) - { - assert( termMvec.back() == bbMvec.back()); - termMvec.pop_back(); - bbMvec.pop_back(); - ++numNOPs; - } - assert(termMvec.back() == bbMvec.back()); - - // Check that we found the right number of NOPs and have the right - // number of instructions to replace them. - unsigned ndelays = mii.getNumDelaySlots(termMvec.back()->getOpCode()); - assert(numNOPs == ndelays && "Missing NOPs in delay slots?"); - assert(N == ndelays && "Cannot use epilog code for delay slots?"); - - // Append the epilog code to the end of the basic block. - bbMvec.push_back(minstrVec[0]); - } -} - - -// Insert SAVE/RESTORE instructions for the method -static void -InsertPrologEpilog(Method *method, TargetMachine &target) -{ - MachineCodeForMethod& mcodeInfo = method->getMachineCode(); - if (mcodeInfo.isCompiledAsLeafMethod()) - return; // nothing to do - - InsertPrologCode(method, target); - InsertEpilogCode(method, target); -} - - -//--------------------------------------------------------------------------- -// class UltraSparcSchedInfo -// -// Purpose: -// Scheduling information for the UltraSPARC. -// Primarily just initializes machine-dependent parameters in -// class MachineSchedInfo. -//--------------------------------------------------------------------------- - -/*ctor*/ -UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii) - : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES, - mii, - SparcRUsageDesc, - SparcInstrUsageDeltas, - SparcInstrIssueDeltas, - sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta), - sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta)) -{ - maxNumIssueTotal = 4; - longestIssueConflict = 0; // computed from issuesGaps[] - - branchMispredictPenalty = 4; // 4 for SPARC IIi - branchTargetUnknownPenalty = 2; // 2 for SPARC IIi - l1DCacheMissPenalty = 8; // 7 or 9 for SPARC IIi - l1ICacheMissPenalty = 8; // ? for SPARC IIi - - inOrderLoads = true; // true for SPARC IIi - inOrderIssue = true; // true for SPARC IIi - inOrderExec = false; // false for most architectures - inOrderRetire= true; // true for most architectures - - // must be called after above parameters are initialized. - this->initializeResources(); -} - -void -UltraSparcSchedInfo::initializeResources() -{ - // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps - MachineSchedInfo::initializeResources(); - - // Machine-dependent fixups go here. None for now. -} - //--------------------------------------------------------------------------- // class UltraSparcFrameInfo // // Purpose: // Interface to stack frame layout info for the UltraSPARC. -// Note that there is no machine-independent interface to this information +// Starting offsets for each area of the stack frame are aligned at +// a multiple of getStackFrameSizeAlignment(). //--------------------------------------------------------------------------- int -UltraSparcFrameInfo::getFirstAutomaticVarOffsetFromFP (const Method* method) +UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& , + bool& pos) const { - return StaticStackAreaOffsetFromFP; + pos = false; // static stack area grows downwards + return StaticAreaOffsetFromFP; } int -UltraSparcFrameInfo::getRegSpillAreaOffsetFromFP(const Method* method) +UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo, + bool& pos) const { - unsigned int autoVarsSize = method->getMachineCode().getAutomaticVarsSize(); - return StaticStackAreaOffsetFromFP + autoVarsSize; + mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added + + pos = false; // static stack area grows downwards + unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize(); + return StaticAreaOffsetFromFP - autoVarsSize; } int -UltraSparcFrameInfo::getFrameSizeBelowDynamicArea(const Method* method) +UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo, + bool& pos) const { - unsigned int optArgsSize = - method->getMachineCode().getOptionalOutgoingArgsSize(); - return optArgsSize + FirstOptionalOutgoingArgOffsetFromSP; + mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added + mcInfo.freezeSpillsArea(); // ensure no more spill slots are added + + pos = false; // static stack area grows downwards + unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize(); + unsigned int spillAreaSize = mcInfo.getRegSpillsSize(); + int offset = autoVarsSize + spillAreaSize; + return StaticAreaOffsetFromFP - offset; } +int +UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo, + bool& pos) const +{ + // Dynamic stack area grows downwards starting at top of opt-args area. + // The opt-args, required-args, and register-save areas are empty except + // during calls and traps, so they are shifted downwards on each + // 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; +} //--------------------------------------------------------------------------- @@ -240,54 +104,15 @@ UltraSparcFrameInfo::getFrameSizeBelowDynamicArea(const Method* method) UltraSparc::UltraSparc() : TargetMachine("UltraSparc-Native"), - instrInfo(), - schedInfo(&instrInfo), - regInfo( this ), - frameInfo() + instrInfo(*this), + schedInfo(*this), + regInfo(*this), + frameInfo(*this), + cacheInfo(*this), + optInfo(*this) { optSizeForSubWordData = 4; minMemOpWordSize = 8; maxAtomicMemOpWordSize = 8; } - -void -ApplyPeepholeOptimizations(Method *method, TargetMachine &target) -{ - return; - - // OptimizeLeafProcedures(); - // DeleteFallThroughBranches(); - // RemoveChainedBranches(); // should be folded with previous - // RemoveRedundantOps(); // operations with %g0, NOP, etc. -} - - - -bool -UltraSparc::compileMethod(Method *M) -{ - InitializeFrameLayout(M, *this); // initialize the required area of - // the stack frame - if (SelectInstructionsForMethod(M, *this)) - { - cerr << "Instruction selection failed for method " << M->getName() - << "\n\n"; - return true; - } - - if (ScheduleInstructionsWithSSA(M, *this)) - { - cerr << "Instruction scheduling before allocation failed for method " - << M->getName() << "\n\n"; - return true; - } - - AllocateRegisters(M, *this); // allocate registers - - ApplyPeepholeOptimizations(M, *this); // machine-dependent peephole opts - - InsertPrologEpilog(M, *this); - - return false; -}