llvm.org GIT mirror llvm / f2868ce
Code pulled out of MAchineInstr.(h|cpp) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1660 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 18 years ago
6 changed file(s) with 677 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===-- llvm/CodeGen/MachineCodeForInstruction.h -----------------*- C++ -*--=//
1 //
2 // Representation of the sequence of machine instructions created
3 // for a single VM instruction. Additionally records information
4 // about hidden and implicit values used by the machine instructions:
5 // about hidden values used by the machine instructions:
6 //
7 // "Temporary values" are intermediate values used in the machine
8 // instruction sequence, but not in the VM instruction
9 // Note that such values should be treated as pure SSA values with
10 // no interpretation of their operands (i.e., as a TmpInstruction
11 // object which actually represents such a value).
12 //
13 // (2) "Implicit uses" are values used in the VM instruction but not in
14 // the machine instruction sequence
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_CODEGEN_MACHINECODE_FOR_INSTRUCTION_H
19 #define LLVM_CODEGEN_MACHINECODE_FOR_INSTRUCTION_H
20
21 #include "llvm/Annotation.h"
22 #include
23 class MachineInstr;
24 class Instruction;
25 class Value;
26
27 class MachineCodeForInstruction
28 : public Annotation, public std::vector {
29 std::vector tempVec; // used by m/c instr but not VM instr
30
31 public:
32 MachineCodeForInstruction();
33 ~MachineCodeForInstruction();
34
35 static MachineCodeForInstruction &get(const Instruction *I);
36 static void destroy(const Instruction *I);
37
38 const std::vector &getTempValues() const { return tempVec; }
39 std::vector &getTempValues() { return tempVec; }
40
41 inline MachineCodeForInstruction &addTemp(Value *tmp) {
42 tempVec.push_back(tmp);
43 return *this;
44 }
45 };
46
47 #endif
0 //===-- llvm/CodeGen/MachineCodeForMethod.h ----------------------*- C++ -*--=//
1 //
2 // Purpose:
3 // Collect native machine code information for a method.
4 // This allows target-specific information about the generated code
5 // to be stored with each method.
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_CODEGEN_MACHINECODEFORMETHOD_H
9 #define LLVM_CODEGEN_MACHINECODEFORMETHOD_H
10
11 #include "llvm/Annotation.h"
12 #include "Support/NonCopyable.h"
13 #include "Support/HashExtras.h"
14 #include
15 class Value;
16 class Method;
17 class Constant;
18 class Type;
19 class TargetMachine;
20
21
22 class MachineCodeForMethod : private Annotation {
23 const Method* method;
24 bool compiledAsLeaf;
25 unsigned staticStackSize;
26 unsigned automaticVarsSize;
27 unsigned regSpillsSize;
28 unsigned currentOptionalArgsSize;
29 unsigned maxOptionalArgsSize;
30 unsigned currentTmpValuesSize;
31 std::hash_set constantsForConstPool;
32 std::hash_map offsets;
33 // hash_map offsetsFromSP;
34
35 public:
36 /*ctor*/ MachineCodeForMethod(const Method* method,
37 const TargetMachine& target);
38
39 // The next two methods are used to construct and to retrieve
40 // the MachineCodeForMethod object for the given method.
41 // construct() -- Allocates and initializes for a given method and target
42 // get() -- Returns a handle to the object.
43 // This should not be called before "construct()"
44 // for a given Method.
45 //
46 static MachineCodeForMethod& construct(const Method *method,
47 const TargetMachine &target);
48 static void destruct(const Method *M);
49 static MachineCodeForMethod& get(const Method* method);
50
51 //
52 // Accessors for global information about generated code for a method.
53 //
54 inline bool isCompiledAsLeafMethod() const { return compiledAsLeaf; }
55 inline unsigned getStaticStackSize() const { return staticStackSize; }
56 inline unsigned getAutomaticVarsSize() const { return automaticVarsSize; }
57 inline unsigned getRegSpillsSize() const { return regSpillsSize; }
58 inline unsigned getMaxOptionalArgsSize() const { return maxOptionalArgsSize;}
59 inline unsigned getCurrentOptionalArgsSize() const
60 { return currentOptionalArgsSize;}
61 inline const std::hash_set&
62 getConstantPoolValues() const {return constantsForConstPool;}
63
64 //
65 // Modifiers used during code generation
66 //
67 void initializeFrameLayout (const TargetMachine& target);
68
69 void addToConstantPool (const Constant* constVal)
70 { constantsForConstPool.insert(constVal); }
71
72 inline void markAsLeafMethod() { compiledAsLeaf = true; }
73
74 int allocateLocalVar (const TargetMachine& target,
75 const Value* local,
76 unsigned int size = 0);
77
78 int allocateSpilledValue (const TargetMachine& target,
79 const Type* type);
80
81 int allocateOptionalArg (const TargetMachine& target,
82 const Type* type);
83
84 void resetOptionalArgs (const TargetMachine& target);
85
86 int pushTempValue (const TargetMachine& target,
87 unsigned int size);
88
89 void popAllTempValues (const TargetMachine& target);
90
91 int getOffset (const Value* val) const;
92
93 // int getOffsetFromFP (const Value* val) const;
94
95 void dump () const;
96
97 private:
98 inline void incrementAutomaticVarsSize(int incr) {
99 automaticVarsSize+= incr;
100 staticStackSize += incr;
101 }
102 inline void incrementRegSpillsSize(int incr) {
103 regSpillsSize+= incr;
104 staticStackSize += incr;
105 }
106 inline void incrementCurrentOptionalArgsSize(int incr) {
107 currentOptionalArgsSize+= incr; // stack size already includes this!
108 }
109 };
110
111 #endif
0 //===-- llvm/CodeGen/MachineCodeForMethod.h ----------------------*- C++ -*--=//
1 //
2 // Purpose:
3 // Collect native machine code information for a method.
4 // This allows target-specific information about the generated code
5 // to be stored with each method.
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_CODEGEN_MACHINECODEFORMETHOD_H
9 #define LLVM_CODEGEN_MACHINECODEFORMETHOD_H
10
11 #include "llvm/Annotation.h"
12 #include "Support/NonCopyable.h"
13 #include "Support/HashExtras.h"
14 #include
15 class Value;
16 class Method;
17 class Constant;
18 class Type;
19 class TargetMachine;
20
21
22 class MachineCodeForMethod : private Annotation {
23 const Method* method;
24 bool compiledAsLeaf;
25 unsigned staticStackSize;
26 unsigned automaticVarsSize;
27 unsigned regSpillsSize;
28 unsigned currentOptionalArgsSize;
29 unsigned maxOptionalArgsSize;
30 unsigned currentTmpValuesSize;
31 std::hash_set constantsForConstPool;
32 std::hash_map offsets;
33 // hash_map offsetsFromSP;
34
35 public:
36 /*ctor*/ MachineCodeForMethod(const Method* method,
37 const TargetMachine& target);
38
39 // The next two methods are used to construct and to retrieve
40 // the MachineCodeForMethod object for the given method.
41 // construct() -- Allocates and initializes for a given method and target
42 // get() -- Returns a handle to the object.
43 // This should not be called before "construct()"
44 // for a given Method.
45 //
46 static MachineCodeForMethod& construct(const Method *method,
47 const TargetMachine &target);
48 static void destruct(const Method *M);
49 static MachineCodeForMethod& get(const Method* method);
50
51 //
52 // Accessors for global information about generated code for a method.
53 //
54 inline bool isCompiledAsLeafMethod() const { return compiledAsLeaf; }
55 inline unsigned getStaticStackSize() const { return staticStackSize; }
56 inline unsigned getAutomaticVarsSize() const { return automaticVarsSize; }
57 inline unsigned getRegSpillsSize() const { return regSpillsSize; }
58 inline unsigned getMaxOptionalArgsSize() const { return maxOptionalArgsSize;}
59 inline unsigned getCurrentOptionalArgsSize() const
60 { return currentOptionalArgsSize;}
61 inline const std::hash_set&
62 getConstantPoolValues() const {return constantsForConstPool;}
63
64 //
65 // Modifiers used during code generation
66 //
67 void initializeFrameLayout (const TargetMachine& target);
68
69 void addToConstantPool (const Constant* constVal)
70 { constantsForConstPool.insert(constVal); }
71
72 inline void markAsLeafMethod() { compiledAsLeaf = true; }
73
74 int allocateLocalVar (const TargetMachine& target,
75 const Value* local,
76 unsigned int size = 0);
77
78 int allocateSpilledValue (const TargetMachine& target,
79 const Type* type);
80
81 int allocateOptionalArg (const TargetMachine& target,
82 const Type* type);
83
84 void resetOptionalArgs (const TargetMachine& target);
85
86 int pushTempValue (const TargetMachine& target,
87 unsigned int size);
88
89 void popAllTempValues (const TargetMachine& target);
90
91 int getOffset (const Value* val) const;
92
93 // int getOffsetFromFP (const Value* val) const;
94
95 void dump () const;
96
97 private:
98 inline void incrementAutomaticVarsSize(int incr) {
99 automaticVarsSize+= incr;
100 staticStackSize += incr;
101 }
102 inline void incrementRegSpillsSize(int incr) {
103 regSpillsSize+= incr;
104 staticStackSize += incr;
105 }
106 inline void incrementCurrentOptionalArgsSize(int incr) {
107 currentOptionalArgsSize+= incr; // stack size already includes this!
108 }
109 };
110
111 #endif
0 //===-- MachineCodeForInstruction.cpp -------------------------------------===//
1 //
2 // Representation of the sequence of machine instructions created
3 // for a single VM instruction. Additionally records information
4 // about hidden and implicit values used by the machine instructions:
5 // about hidden values used by the machine instructions:
6 //
7 // "Temporary values" are intermediate values used in the machine
8 // instruction sequence, but not in the VM instruction
9 // Note that such values should be treated as pure SSA values with
10 // no interpretation of their operands (i.e., as a TmpInstruction
11 // object which actually represents such a value).
12 //
13 // (2) "Implicit uses" are values used in the VM instruction but not in
14 // the machine instruction sequence
15 //
16 //===----------------------------------------------------------------------===//
17
18 #include "llvm/CodeGen/MachineCodeForInstruction.h"
19 #include "llvm/CodeGen/MachineInstr.h"
20 #include "llvm/Instruction.h"
21
22 static AnnotationID MCFI_AID(
23 AnnotationManager::getID("CodeGen::MachineCodeForInstruction"));
24
25 static Annotation *CreateMCFI(AnnotationID AID, const Annotable *, void *) {
26 assert(AID == MCFI_AID);
27 return new MachineCodeForInstruction(); // Invoke constructor!
28 }
29
30 // Register the annotation with the annotation factory
31 static struct Initializer {
32 Initializer() {
33 AnnotationManager::registerAnnotationFactory(MCFI_AID, &CreateMCFI);
34 }
35 } RegisterAID;
36
37 MachineCodeForInstruction &MachineCodeForInstruction::get(const Instruction *I){
38 return *(MachineCodeForInstruction*)I->getOrCreateAnnotation(MCFI_AID);
39 }
40
41 void MachineCodeForInstruction::destroy(const Instruction *I) {
42 I->deleteAnnotation(MCFI_AID);
43 }
44
45
46 MachineCodeForInstruction::MachineCodeForInstruction() : Annotation(MCFI_AID) {}
47
48 MachineCodeForInstruction::~MachineCodeForInstruction() {
49 // Free the Value objects created to hold intermediate values
50 for (unsigned i=0, N=tempVec.size(); i < N; i++)
51 delete tempVec[i];
52
53 // Free the MachineInstr objects allocated, if any.
54 for (unsigned i=0, N = size(); i < N; i++)
55 delete (*this)[i];
56 }
0 //===-- MachineCodeForMethod.cpp --------------------------------------------=//
1 //
2 // Purpose:
3 // Collect native machine code information for a method.
4 // This allows target-specific information about the generated code
5 // to be stored with each method.
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/CodeGen/MachineCodeForMethod.h"
9 #include "llvm/CodeGen/MachineInstr.h" // For debug output
10 #include "llvm/Target/TargetMachine.h"
11 #include "llvm/Target/MachineFrameInfo.h"
12 #include "llvm/Target/MachineCacheInfo.h"
13 #include "llvm/Method.h"
14 #include "llvm/iOther.h"
15 #include
16
17 const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits::max();
18
19 static AnnotationID MCFM_AID(
20 AnnotationManager::getID("CodeGen::MachineCodeForMethod"));
21
22 // The next two methods are used to construct and to retrieve
23 // the MachineCodeForMethod object for the given method.
24 // construct() -- Allocates and initializes for a given method and target
25 // get() -- Returns a handle to the object.
26 // This should not be called before "construct()"
27 // for a given Method.
28 //
29 MachineCodeForMethod &MachineCodeForMethod::construct(const Method *M,
30 const TargetMachine &Tar){
31 assert(M->getAnnotation(MCFM_AID) == 0 &&
32 "Object already exists for this method!");
33 MachineCodeForMethod* mcInfo = new MachineCodeForMethod(M, Tar);
34 M->addAnnotation(mcInfo);
35 return *mcInfo;
36 }
37
38 void MachineCodeForMethod::destruct(const Method *M) {
39 bool Deleted = M->deleteAnnotation(MCFM_AID);
40 assert(Deleted && "Machine code did not exist for method!");
41 }
42
43
44 MachineCodeForMethod &MachineCodeForMethod::get(const Method* method) {
45 MachineCodeForMethod* mc = (MachineCodeForMethod*)
46 method->getAnnotation(MCFM_AID);
47 assert(mc && "Call construct() method first to allocate the object");
48 return *mc;
49 }
50
51 static unsigned
52 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
53 {
54 const MachineFrameInfo& frameInfo = target.getFrameInfo();
55
56 unsigned int maxSize = 0;
57
58 for (Method::const_inst_iterator I=method->inst_begin(),E=method->inst_end();
59 I != E; ++I)
60 if ((*I)->getOpcode() == Instruction::Call)
61 {
62 CallInst* callInst = cast(*I);
63 unsigned int numOperands = callInst->getNumOperands() - 1;
64 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
65 if (numExtra <= 0)
66 continue;
67
68 unsigned int sizeForThisCall;
69 if (frameInfo.argsOnStackHaveFixedSize())
70 {
71 int argSize = frameInfo.getSizeOfEachArgOnStack();
72 sizeForThisCall = numExtra * (unsigned) argSize;
73 }
74 else
75 {
76 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
77 sizeForThisCall = 0;
78 for (unsigned i=0; i < numOperands; ++i)
79 sizeForThisCall += target.findOptimalStorageSize(callInst->
80 getOperand(i)->getType());
81 }
82
83 if (maxSize < sizeForThisCall)
84 maxSize = sizeForThisCall;
85 }
86
87 return maxSize;
88 }
89
90 // Align data larger than one L1 cache line on L1 cache line boundaries.
91 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
92 //
93 // THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
94 // SHOULD BE USED DIRECTLY THERE
95 //
96 inline unsigned int
97 SizeToAlignment(unsigned int size, const TargetMachine& target)
98 {
99 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
100 if (size > (unsigned) cacheLineSize / 2)
101 return cacheLineSize;
102 else
103 for (unsigned sz=1; /*no condition*/; sz *= 2)
104 if (sz >= size)
105 return sz;
106 }
107
108
109
110 /*ctor*/
111 MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
112 const TargetMachine& target)
113 : Annotation(MCFM_AID),
114 method(_M), compiledAsLeaf(false), staticStackSize(0),
115 automaticVarsSize(0), regSpillsSize(0),
116 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
117 currentTmpValuesSize(0)
118 {
119 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
120 staticStackSize = maxOptionalArgsSize +
121 target.getFrameInfo().getMinStackFrameSize();
122 }
123
124 int
125 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
126 const Value* val,
127 unsigned int size)
128 {
129 // Check if we've allocated a stack slot for this value already
130 //
131 int offset = getOffset(val);
132 if (offset == INVALID_FRAME_OFFSET)
133 {
134 bool growUp;
135 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
136 growUp);
137 unsigned char align;
138 if (size == 0)
139 {
140 size = target.findOptimalStorageSize(val->getType());
141 // align = target.DataLayout.getTypeAlignment(val->getType());
142 }
143
144 align = SizeToAlignment(size, target);
145
146 offset = getAutomaticVarsSize();
147 if (! growUp)
148 offset += size;
149
150 if (unsigned int mod = offset % align)
151 {
152 offset += align - mod;
153 size += align - mod;
154 }
155
156 offset = growUp? firstOffset + offset
157 : firstOffset - offset;
158
159 offsets[val] = offset;
160
161 incrementAutomaticVarsSize(size);
162 }
163 return offset;
164 }
165
166 int
167 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
168 const Type* type)
169 {
170 unsigned int size = target.findOptimalStorageSize(type);
171 unsigned char align = target.DataLayout.getTypeAlignment(type);
172
173 bool growUp;
174 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
175
176 int offset = getRegSpillsSize();
177 if (! growUp)
178 offset += size;
179
180 if (unsigned int mod = offset % align)
181 {
182 offset += align - mod;
183 size += align - mod;
184 }
185
186 offset = growUp? firstOffset + offset
187 : firstOffset - offset;
188
189 incrementRegSpillsSize(size);
190
191 return offset;
192 }
193
194 int
195 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
196 const Type* type)
197 {
198 const MachineFrameInfo& frameInfo = target.getFrameInfo();
199
200 int size = INT_MAX;
201 if (frameInfo.argsOnStackHaveFixedSize())
202 size = frameInfo.getSizeOfEachArgOnStack();
203 else
204 {
205 size = target.findOptimalStorageSize(type);
206 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
207 }
208 unsigned char align = target.DataLayout.getTypeAlignment(type);
209
210 bool growUp;
211 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
212
213 int offset = getCurrentOptionalArgsSize();
214 if (! growUp)
215 offset += size;
216
217 if (unsigned int mod = offset % align)
218 {
219 offset += align - mod;
220 size += align - mod;
221 }
222
223 offset = growUp? firstOffset + offset
224 : firstOffset - offset;
225
226 incrementCurrentOptionalArgsSize(size);
227
228 return offset;
229 }
230
231 void
232 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
233 {
234 currentOptionalArgsSize = 0;
235 }
236
237 int
238 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
239 unsigned int size)
240 {
241 // Compute a power-of-2 alignment according to the possible sizes,
242 // but not greater than the alignment of the largest type we support
243 // (currently a double word -- see class TargetData).
244 unsigned char align = 1;
245 for (; align < size && align < target.DataLayout.getDoubleAlignment();
246 align = 2*align)
247 ;
248
249 bool growUp;
250 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
251
252 int offset = currentTmpValuesSize;
253 if (! growUp)
254 offset += size;
255
256 if (unsigned int mod = offset % align)
257 {
258 offset += align - mod;
259 size += align - mod;
260 }
261
262 offset = growUp ? firstTmpOffset + offset : firstTmpOffset - offset;
263
264 currentTmpValuesSize += size;
265 return offset;
266 }
267
268 void
269 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
270 {
271 currentTmpValuesSize = 0;
272 }
273
274 int
275 MachineCodeForMethod::getOffset(const Value* val) const
276 {
277 std::hash_map::const_iterator pair = offsets.find(val);
278 return (pair == offsets.end())? INVALID_FRAME_OFFSET : pair->second;
279 }
280
281 void
282 MachineCodeForMethod::dump() const
283 {
284 cerr << "\n" << method->getReturnType()
285 << " \"" << method->getName() << "\"\n";
286
287 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
288 {
289 BasicBlock* bb = *BI;
290 cerr << "\n"
291 << (bb->hasName()? bb->getName() : "Label")
292 << " (" << bb << ")" << ":\n";
293
294 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
295 for (unsigned i=0; i < mvec.size(); i++)
296 cerr << "\t" << *mvec[i];
297 }
298 cerr << "\nEnd method \"" << method->getName() << "\"\n\n";
299 }
0 //===-- llvm/CodeGen/MachineCodeForInstruction.h -----------------*- C++ -*--=//
1 //
2 // Representation of the sequence of machine instructions created
3 // for a single VM instruction. Additionally records information
4 // about hidden and implicit values used by the machine instructions:
5 // about hidden values used by the machine instructions:
6 //
7 // "Temporary values" are intermediate values used in the machine
8 // instruction sequence, but not in the VM instruction
9 // Note that such values should be treated as pure SSA values with
10 // no interpretation of their operands (i.e., as a TmpInstruction
11 // object which actually represents such a value).
12 //
13 // (2) "Implicit uses" are values used in the VM instruction but not in
14 // the machine instruction sequence
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_CODEGEN_MACHINECODE_FOR_INSTRUCTION_H
19 #define LLVM_CODEGEN_MACHINECODE_FOR_INSTRUCTION_H
20
21 #include "llvm/Annotation.h"
22 #include
23 class MachineInstr;
24 class Instruction;
25 class Value;
26
27 class MachineCodeForInstruction
28 : public Annotation, public std::vector {
29 std::vector tempVec; // used by m/c instr but not VM instr
30
31 public:
32 MachineCodeForInstruction();
33 ~MachineCodeForInstruction();
34
35 static MachineCodeForInstruction &get(const Instruction *I);
36 static void destroy(const Instruction *I);
37
38 const std::vector &getTempValues() const { return tempVec; }
39 std::vector &getTempValues() { return tempVec; }
40
41 inline MachineCodeForInstruction &addTemp(Value *tmp) {
42 tempVec.push_back(tmp);
43 return *this;
44 }
45 };
46
47 #endif