Changes to work towards compatability with IBM's version of dyninst.
[dyninst.git] / dyninstAPI / src / ast.h
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: ast.h,v 1.47 2001/08/29 23:25:27 hollings Exp $
43
44 #ifndef AST_HDR
45 #define AST_HDR
46
47 //
48 // Define a AST class for use in generating primitive and pred calls
49 //
50
51 #include <stdio.h>
52 #include "common/h/Vector.h"
53 #include "common/h/Dictionary.h"
54 #include "common/h/String.h"
55 #include "common/h/Types.h"
56 #if defined(BPATCH_LIBRARY)
57 #include "dyninstAPI/h/BPatch_type.h"
58 #endif
59
60 class process;
61 class instPoint;
62 class function_base;
63
64
65 // a register number, e.g. [0,31]
66 // typedef int reg; // see new Register type in "common/h/Types.h"
67
68 typedef enum { plusOp,
69
70                minusOp,
71                timesOp,
72                divOp,
73                lessOp,
74                leOp,
75                greaterOp,
76                geOp,
77                eqOp,
78                neOp,
79                loadOp,           
80                loadConstOp,
81                loadFrameRelativeOp,
82                loadFrameAddr,
83                storeOp,
84                storeFrameRelativeOp,
85                ifOp,
86                whileOp,  // Simple control structures will be useful
87                doOp,     // Zhichen
88                callOp,
89                trampPreamble,
90                trampTrailer,
91                noOp,
92                orOp,
93                andOp,
94                getRetValOp,
95                getSysRetValOp,
96                getParamOp,
97                getSysParamOp,      
98                getAddrOp,       // return the address of the operand
99                loadIndirOp,
100                storeIndirOp,
101                saveRegOp,
102                updateCostOp,
103                funcJumpOp,        // Jump to function without linkage
104                branchOp} opCode;
105
106 class registerSlot {
107  public:
108     Register number;    // what register is it
109     bool inUse;         // free or in use.
110     bool needsSaving;   // been used since last rest
111     bool mustRestore;   // need to restore it before we are done.               
112     bool startsLive;    // starts life as a live register.
113 };
114
115 class registerSpace {
116     public:
117         registerSpace(const unsigned int dCount, Register *deads,
118                       const unsigned int lCount, Register *lives);
119         Register allocateRegister(char *insn, Address &base, bool noCost);
120         void freeRegister(Register k);
121         void resetSpace();
122         bool isFreeRegister(Register k);
123         u_int getRegisterCount() { return numRegisters; }
124         registerSlot *getRegSlot(Register k) { return (&registers[k]); }
125         bool readOnlyRegister(Register k);
126         void keep_register(Register k);
127         void unkeep_register(Register k);
128         bool is_keep_register(Register k);
129     private:
130         u_int numRegisters;
131         Register highWaterRegister;
132         registerSlot *registers;
133         vector<Register> keep_list;
134 };
135
136 class dataReqNode;
137 class AstNode {
138     public:
139         enum nodeType { sequenceNode, opCodeNode, operandNode, callNode };
140         enum operandType { Constant, ConstantPtr, ConstantString,
141 #if defined(MT_THREAD)
142                            OffsetConstant,      // add a OffsetConstant type for offset
143                                                 // generated for level or index:
144                                                 //   it is  MAX#THREADS * level * tSize  for level
145                                                 //     or                 index * tSize  for index
146 #endif
147                            DataValue, DataPtr,  // restore AstNode::DataValue and AstNode::DataPtr
148                            DataId, DataIndir, DataReg,
149                            Param, ReturnVal, DataAddr, FrameAddr,
150                            SharedData, PreviousStackFrameDataReg};
151
152         AstNode(); // mdl.C
153         AstNode(const string &func, AstNode *l, AstNode *r);
154         AstNode(const string &func, AstNode *l); // needed by inst.C
155         AstNode(operandType ot, void *arg);
156 #if defined(MT_THREAD)
157         AstNode(operandType ot, void *arg, bool isLev, unsigned v_level, unsigned v_index);
158 #endif
159         AstNode(AstNode *l, AstNode *r);
160
161         AstNode(opCode, AstNode *left); 
162         // assumes "NULL" for right child ptr
163         // needed by inst.C and stuff in ast.C
164
165         AstNode(operandType ot, AstNode *l);
166         AstNode(opCode ot, AstNode *l, AstNode *r, AstNode *e = NULL);
167         AstNode(const string &func, vector<AstNode *> &ast_args);
168         AstNode(function_base *func, vector<AstNode *> &ast_args);
169         AstNode(function_base *func); // FuncJump (for replaceFunction)
170
171         AstNode(AstNode *src);
172         AstNode &operator=(const AstNode &src);
173
174        ~AstNode();
175
176         Address generateTramp(process *proc, char *i, Address &base,
177                               int &trampCost, bool noCost);
178         Address generateCode(process *proc, registerSpace *rs, char *i, 
179                              Address &base, bool noCost, bool root);
180         Address generateCode_phase2(process *proc, registerSpace *rs, char *i, 
181                                     Address &base, bool noCost);
182
183         int cost() const;       // return the # of instruction times in the ast.
184         void print() const;
185         int referenceCount;     // Reference count for freeing memory
186         int useCount;           // Reference count for generating code
187         void setUseCount(void); // Set values for useCount
188         int getSize() { return size; };
189         void cleanUseCount(void);
190         bool checkUseCount(registerSpace*, bool&);
191         void printUseCount(void);
192         Register kept_register; // Use when generating code for shared nodes
193         void updateOperandsRC(bool flag); // Update operand's referenceCount
194                                           // if "flag" is true, increments the
195                                           // counter, otherwise it decrements 
196                                           // the counter.
197         void printRC(void);
198         bool findFuncInAst(string func) ;
199         void replaceFuncInAst(function_base *func1, function_base *func2);
200         void replaceFuncInAst(function_base *func1, function_base *func2, vector<AstNode *> &ast_args, int index=0);
201         bool accessesParam(void);         // Does this AST access "Param"
202
203 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)  
204         bool astFlag;  
205         void sysFlag(instPoint *location);    
206
207         void optRetVal(AstNode *opt);
208 #endif
209
210         // only function that's defined in metric.C (only used in metri.C)
211         bool condMatch(AstNode* a,
212                        vector<dataReqNode*> &data_tuple1,
213                        vector<dataReqNode*> &data_tuple2,
214                        vector<dataReqNode*> datareqs1,
215                        vector<dataReqNode*> datareqs2);
216
217     private:
218         AstNode(opCode); // like AstNode(opCode, const AstNode &, 
219                          //              const AstNode &)
220                          // but assumes "NULL" for both child ptrs
221         nodeType type;
222         opCode op;                  // only for opCode nodes
223         string callee;              // only for call nodes
224         function_base *calleefunc;  // only for call nodes
225         vector<AstNode *> operands; // only for call nodes
226         operandType oType;          // for operand nodes
227         void *oValue;               // operand value for operand nodes
228 #if defined(MT_THREAD)              // for OffsetConstant type for offset
229         bool isLevel;               // true  if lvlOrIdx is level
230                                     // false if lvlOrIdex is idex
231         unsigned lvl;               // if level:  MAX#THREADS * level * tSize
232         unsigned idx;               // if index:                index * tSize
233                                     // lvl AND idx together identify a variable
234 #endif
235 #ifdef BPATCH_LIBRARY
236         const BPatch_type *bptype;  // type of corresponding BPatch_snippet
237         bool doTypeCheck;           // should operands be type checked
238 #endif
239         int size;                   // size of the operations (in bytes)
240
241         // These 2 vrbles must be pointers; otherwise, we'd have a recursive
242         // data structure with an infinite size.
243         // The only other option is to go with references, which would have
244         // to be initialized in the constructor and can't use NULL as a
245         // sentinel value...
246         AstNode *loperand;
247         AstNode *roperand;
248         AstNode *eoperand;
249
250     public:
251         // Functions for getting and setting type decoration used by the
252         // dyninst API library
253 #ifdef BPATCH_LIBRARY
254         const BPatch_type *getType() { return bptype; };
255         void              setType(const BPatch_type *t) { 
256                                 bptype = t; 
257                                 size = t->getSize(); }
258         void              setTypeChecking(bool x) { doTypeCheck = x; }
259         BPatch_type       *checkType();
260 #endif
261 };
262
263 AstNode *assignAst(AstNode *src);
264 void removeAst(AstNode *&ast);
265 void terminateAst(AstNode *&ast);
266 AstNode *createIf(AstNode *expression, AstNode *action);
267 #if defined(MT_THREAD)
268 AstNode *createCounter(const string &func, void *, void *, AstNode *arg);
269 AstNode *createTimer(const string &func, void *, void *, 
270                      vector<AstNode *> &arg_args);
271 AstNode *computeAddress(void *level, int type);
272 AstNode *addIndexToAddress(AstNode *addr, void *index, int type);
273 AstNode *computeTheAddress(void *level, void *index, int type);
274 #else
275 AstNode *createCounter(const string &func, void *, AstNode *arg);
276 AstNode *createTimer(const string &func, void *, 
277                      vector<AstNode *> &arg_args);
278 #endif
279 Register emitFuncCall(opCode op, registerSpace *rs, char *i, Address &base, 
280                       const vector<AstNode *> &operands, const string &func,
281                       process *proc, bool noCost, const function_base *funcbase);
282 void emitLoadPreviousStackFrameRegister(Address register_num,
283                                         Register dest,
284                                         char *insn,
285                                         Address &base,
286                                         int size,
287                                         bool noCost);
288 void emitFuncJump(opCode op, char *i, Address &base,
289                   const function_base *func, process *proc);
290
291 #endif /* AST_HDR */