From be49526193c5d8856d0b3c2721dfa6a4c4010d6d Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Thu, 8 Nov 2001 04:47:06 +0000 Subject: [PATCH] Major overhaul of stack frame management. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1185 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstr.h | 120 ++++++++---- lib/CodeGen/InstrSelection/InstrForest.cpp | 9 + lib/CodeGen/InstrSelection/InstrSelection.cpp | 2 +- .../InstrSelection/InstrSelectionSupport.cpp | 4 +- lib/CodeGen/MachineInstr.cpp | 176 +++++++++++++++--- .../SparcV9/InstrSelection/InstrForest.cpp | 9 + .../SparcV9/InstrSelection/InstrSelection.cpp | 2 +- .../InstrSelection/InstrSelectionSupport.cpp | 4 +- 8 files changed, 265 insertions(+), 61 deletions(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index dc68904e3c1..ca8f1fb1ec9 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -20,12 +20,23 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/NonCopyable.h" #include "llvm/Target/MachineInstrInfo.h" +#include "llvm/Annotation.h" +#include "llvm/Method.h" #include #include +#include template class ValOpIterator; +//************************** External Constants ****************************/ + +const int INVALID_FRAME_OFFSET = MAXINT; + + +//*************************** External Classes *****************************/ + + //--------------------------------------------------------------------------- // class MachineOperand // @@ -506,64 +517,109 @@ public: //--------------------------------------------------------------------------- -class MachineCodeForMethod: public NonCopyable { + +class MachineCodeForMethod: public NonCopyable, private Annotation { private: - Method* method; + static AnnotationID AID; +private: + const Method* method; bool compiledAsLeaf; unsigned staticStackSize; unsigned automaticVarsSize; unsigned regSpillsSize; - unsigned optionalOutgoingArgsSize; + unsigned currentOptionalArgsSize; + unsigned maxOptionalArgsSize; + unsigned currentTmpValuesSize; hash_set constantsForConstPool; - hash_map offsetsFromFP; - hash_map offsetsFromSP; - - inline void incrementAutomaticVarsSize(int incr) - { automaticVarsSize+= incr; - staticStackSize += incr; } + hash_map offsets; + // hash_map offsetsFromSP; public: - /*ctor*/ MachineCodeForMethod(Method* _M) - : method(_M), compiledAsLeaf(false), staticStackSize(0), - automaticVarsSize(0), regSpillsSize(0), optionalOutgoingArgsSize(0) {} + /*ctor*/ MachineCodeForMethod(const Method* method, + const TargetMachine& target); - inline bool isCompiledAsLeafMethod() const { return compiledAsLeaf; } - inline unsigned getStaticStackSize() const { return staticStackSize; } - inline unsigned getAutomaticVarsSize() const { return automaticVarsSize; } - inline unsigned getRegSpillsSize() const { return regSpillsSize; } - inline unsigned getOptionalOutgoingArgsSize() const - { return optionalOutgoingArgsSize; } + // The next two methods are used to construct and to retrieve + // the MachineCodeForMethod object for the given method. + // construct() -- Allocates and initializes for a given method and target + // get() -- Returns a handle to the object. + // This should not be called before "construct()" + // for a given Method. + // + inline static MachineCodeForMethod& construct(const Method* method, + const TargetMachine& target) + { + assert(method->getAnnotation(MachineCodeForMethod::AID) == NULL && + "Object already exists for this method!"); + MachineCodeForMethod* mcInfo = new MachineCodeForMethod(method, target); + method->addAnnotation(mcInfo); + return *mcInfo; + } + + inline static MachineCodeForMethod& get(const Method* method) + { + MachineCodeForMethod* mc = (MachineCodeForMethod*) + method->getAnnotation(MachineCodeForMethod::AID); + assert(mc && "Call construct() method first to allocate the object"); + return *mc; + } + + // + // Accessors for global information about generated code for a method. + // + inline bool isCompiledAsLeafMethod() const { return compiledAsLeaf; } + inline unsigned getStaticStackSize() const { return staticStackSize; } + inline unsigned getAutomaticVarsSize() const { return automaticVarsSize; } + inline unsigned getRegSpillsSize() const { return regSpillsSize; } + inline unsigned getMaxOptionalArgsSize() const { return maxOptionalArgsSize;} + inline unsigned getCurrentOptionalArgsSize() const + { return currentOptionalArgsSize;} inline const hash_set& getConstantPoolValues() const {return constantsForConstPool;} + // + // Modifiers used during code generation + // + void initializeFrameLayout (const TargetMachine& target); + void addToConstantPool (const ConstPoolVal* constVal) { constantsForConstPool.insert(constVal); } inline void markAsLeafMethod() { compiledAsLeaf = true; } - inline void incrementStackSize(int incr) { staticStackSize += incr; } + int allocateLocalVar (const TargetMachine& target, + const Value* local); - inline void incrementRegSpillsSize(int incr) - { regSpillsSize+= incr; - staticStackSize += incr; } + int allocateSpilledValue (const TargetMachine& target, + const Type* type); - inline void incrementOptionalOutgoingArgsSize(int incr) - { optionalOutgoingArgsSize+= incr; - staticStackSize += incr; } + int allocateOptionalArg (const TargetMachine& target, + const Type* type); - void putLocalVarAtOffsetFromFP(const Value* local, - int offset, + void resetOptionalArgs (const TargetMachine& target); + + int pushTempValue (const TargetMachine& target, unsigned int size); - void putLocalVarAtOffsetFromSP(const Value* local, - int offset, - unsigned int size); + void popAllTempValues (const TargetMachine& target); - int getOffsetFromFP (const Value* local) const; + int getOffset (const Value* val) const; - int getOffsetFromSP (const Value* local) const; + // int getOffsetFromFP (const Value* val) const; void dump () const; + +private: + inline void incrementAutomaticVarsSize(int incr) { + automaticVarsSize+= incr; + staticStackSize += incr; + } + inline void incrementRegSpillsSize(int incr) { + regSpillsSize+= incr; + staticStackSize += incr; + } + inline void incrementCurrentOptionalArgsSize(int incr) { + currentOptionalArgsSize+= incr; // stack size already includes this! + } }; diff --git a/lib/CodeGen/InstrSelection/InstrForest.cpp b/lib/CodeGen/InstrSelection/InstrForest.cpp index 199ed6569be..d460bb77e23 100644 --- a/lib/CodeGen/InstrSelection/InstrForest.cpp +++ b/lib/CodeGen/InstrSelection/InstrForest.cpp @@ -80,6 +80,15 @@ InstructionNode::InstructionNode(Instruction* I) { opLabel = opLabel + 100; // load/getElem with index vector } + else if (opLabel == Instruction::And || + opLabel == Instruction::Or || + opLabel == Instruction::Xor || + opLabel == Instruction::Not) + { + // Distinguish bitwise operators from logical operators! + if (I->getType() != Type::BoolTy) + opLabel = opLabel + 100; // bitwise operator + } else if (opLabel == Instruction::Cast) { const Type *ITy = I->getType(); diff --git a/lib/CodeGen/InstrSelection/InstrSelection.cpp b/lib/CodeGen/InstrSelection/InstrSelection.cpp index abbd2f94f7e..fafe0234e34 100644 --- a/lib/CodeGen/InstrSelection/InstrSelection.cpp +++ b/lib/CodeGen/InstrSelection/InstrSelection.cpp @@ -130,7 +130,7 @@ SelectInstructionsForMethod(Method* method, TargetMachine &target) { cout << endl << "*** Machine instructions after INSTRUCTION SELECTION" << endl; - method->getMachineCode().dump(); + MachineCodeForMethod::get(method).dump(); } return false; diff --git a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp index 88fd4a41386..0a6d7d331d3 100644 --- a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp @@ -337,7 +337,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr, if (constantThatMustBeLoaded) { // register the value so it is emitted in the assembly - method->getMachineCode().addToConstantPool( + MachineCodeForMethod::get(method).addToConstantPool( cast(opValue)); } } @@ -372,7 +372,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr, if (isa(oldVal)) { // register the value so it is emitted in the assembly - method->getMachineCode().addToConstantPool( + MachineCodeForMethod::get(method).addToConstantPool( cast(oldVal)); } } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index b620fa4bfaa..46a80298403 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -14,10 +14,14 @@ #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/MachineFrameInfo.h" #include "llvm/Target/MachineRegInfo.h" #include "llvm/Method.h" +#include "llvm/iOther.h" #include "llvm/Instruction.h" +AnnotationID MachineCodeForMethod::AID( + AnnotationManager::getID("MachineCodeForMethodAnnotation")); //************************ Class Implementations **************************/ @@ -174,43 +178,169 @@ operator<<(ostream &os, const MachineOperand &mop) return os; } - -void -MachineCodeForMethod::putLocalVarAtOffsetFromFP(const Value* local, - int offset, - unsigned int size) +static unsigned int +ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method) { - offsetsFromFP[local] = offset; - incrementAutomaticVarsSize(size); + const MachineFrameInfo& frameInfo = target.getFrameInfo(); + + unsigned int maxSize = 0; + + for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end(); + I != E; ++I) + if ((*I)->getOpcode() == Instruction::Call) + { + CallInst* callInst = cast(*I); + unsigned int numOperands = callInst->getNumOperands() - 1; + unsigned int numExtra = numOperands + - frameInfo.getNumFixedOutgoingArgs(); + + unsigned int sizeForThisCall; + if (frameInfo.argsOnStackHaveFixedSize()) + { + int argSize = frameInfo.getSizeOfEachArgOnStack(); + sizeForThisCall = numExtra * (unsigned) argSize; + } + else + { + assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize"); + sizeForThisCall = 0; + for (unsigned i=0; i < numOperands; ++i) + sizeForThisCall += target.findOptimalStorageSize(callInst-> + getOperand(i)->getType()); + } + + if (maxSize < sizeForThisCall) + maxSize = sizeForThisCall; + } + + return maxSize; } -void -MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local, - int offset, - unsigned int size) +/*ctor*/ +MachineCodeForMethod::MachineCodeForMethod(const Method* _M, + const TargetMachine& target) + : Annotation(AID), + method(_M), compiledAsLeaf(false), staticStackSize(0), + automaticVarsSize(0), regSpillsSize(0), + currentOptionalArgsSize(0), maxOptionalArgsSize(0), + currentTmpValuesSize(0) { - offsetsFromSP[local] = offset; - incrementAutomaticVarsSize(size); + maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method); + staticStackSize = maxOptionalArgsSize + + target.getFrameInfo().getMinStackFrameSize(); } - int -MachineCodeForMethod::getOffsetFromFP(const Value* local) const +MachineCodeForMethod::allocateLocalVar(const TargetMachine& target, + const Value* val) { - hash_map::const_iterator pair = offsetsFromFP.find(local); - assert(pair != offsetsFromFP.end() && "Offset from FP unknown for Value"); - return (*pair).second; + // Check if we've allocated a stack slot for this value already + // + int offset = getOffset(val); + if (offset == INVALID_FRAME_OFFSET) + { + bool growUp; + int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this, + growUp); + offset = growUp? firstOffset + getAutomaticVarsSize() + : firstOffset - getAutomaticVarsSize(); + offsets[val] = offset; + + unsigned int size = target.findOptimalStorageSize(val->getType()); + incrementAutomaticVarsSize(size); + } + return offset; } - int -MachineCodeForMethod::getOffsetFromSP(const Value* local) const +MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target, + const Type* type) { - hash_map::const_iterator pair = offsetsFromSP.find(local); - assert(pair != offsetsFromSP.end() && "Offset from SP unknown for Value"); - return (*pair).second; + bool growUp; + int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); + int offset = growUp? firstOffset + getRegSpillsSize() + : firstOffset - getRegSpillsSize(); + + unsigned int size = target.findOptimalStorageSize(type); + incrementRegSpillsSize(size); + + return offset; } + +int +MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target, + const Type* type) +{ + const MachineFrameInfo& frameInfo = target.getFrameInfo(); + bool growUp; + int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp); + int offset = growUp? firstOffset + getCurrentOptionalArgsSize() + : firstOffset - getCurrentOptionalArgsSize(); + + int size = MAXINT; + if (frameInfo.argsOnStackHaveFixedSize()) + size = frameInfo.getSizeOfEachArgOnStack(); + else + { + assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets"); + size = target.findOptimalStorageSize(type); + } + + incrementCurrentOptionalArgsSize(size); + + return offset; +} + +void +MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target) +{ + currentOptionalArgsSize = 0; +} + +int +MachineCodeForMethod::pushTempValue(const TargetMachine& target, + unsigned int size) +{ + bool growUp; + int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); + int offset = growUp? firstTmpOffset + currentTmpValuesSize + : firstTmpOffset - currentTmpValuesSize; + currentTmpValuesSize += size; + return offset; +} + +void +MachineCodeForMethod::popAllTempValues(const TargetMachine& target) +{ + currentTmpValuesSize = 0; +} + + +// void +// MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local, +// int offset, +// unsigned int size) +// { +// offsetsFromSP[local] = offset; +// incrementAutomaticVarsSize(size); +// } +// + +int +MachineCodeForMethod::getOffset(const Value* val) const +{ + hash_map::const_iterator pair = offsets.find(val); + return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second; +} + + +// int +// MachineCodeForMethod::getOffsetFromSP(const Value* local) const +// { +// hash_map::const_iterator pair = offsetsFromSP.find(local); +// return (pair == offsetsFromSP.end())? INVALID_FRAME_OFFSET : (*pair).second; +// } void diff --git a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp index 199ed6569be..d460bb77e23 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp @@ -80,6 +80,15 @@ InstructionNode::InstructionNode(Instruction* I) { opLabel = opLabel + 100; // load/getElem with index vector } + else if (opLabel == Instruction::And || + opLabel == Instruction::Or || + opLabel == Instruction::Xor || + opLabel == Instruction::Not) + { + // Distinguish bitwise operators from logical operators! + if (I->getType() != Type::BoolTy) + opLabel = opLabel + 100; // bitwise operator + } else if (opLabel == Instruction::Cast) { const Type *ITy = I->getType(); diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp index abbd2f94f7e..fafe0234e34 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp @@ -130,7 +130,7 @@ SelectInstructionsForMethod(Method* method, TargetMachine &target) { cout << endl << "*** Machine instructions after INSTRUCTION SELECTION" << endl; - method->getMachineCode().dump(); + MachineCodeForMethod::get(method).dump(); } return false; diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp index 88fd4a41386..0a6d7d331d3 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp @@ -337,7 +337,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr, if (constantThatMustBeLoaded) { // register the value so it is emitted in the assembly - method->getMachineCode().addToConstantPool( + MachineCodeForMethod::get(method).addToConstantPool( cast(opValue)); } } @@ -372,7 +372,7 @@ FixConstantOperandsForInstr(Instruction* vmInstr, if (isa(oldVal)) { // register the value so it is emitted in the assembly - method->getMachineCode().addToConstantPool( + MachineCodeForMethod::get(method).addToConstantPool( cast(oldVal)); } }