Added features to dyninstAPI library, including the ability to delete
[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 #ifndef AST_HDR
43 #define AST_HDR
44
45 /*
46  * $Log: ast.h,v $
47  * Revision 1.25  1997/04/29 16:58:51  buck
48  * Added features to dyninstAPI library, including the ability to delete
49  * inserted snippets and the start of type checking.
50  *
51  * Revision 1.2  1997/04/09 17:20:14  buck
52  * Added getThreads calls to BPatch, support for deleting snippets,
53  * and the start of support for the type system.
54  *
55  * Revision 1.1.1.1  1997/04/01 20:25:00  buck
56  * Update Maryland repository with latest from Wisconsin.
57  *
58  * Revision 1.24  1997/03/18 19:44:08  buck
59  * first commit of dyninst library.  Also includes:
60  *      moving templates from paradynd to dyninstAPI
61  *      converting showError into a function (in showerror.C)
62  *      many ifdefs for BPATCH_LIBRARY in dyinstAPI/src.
63  *
64  * Revision 1.23  1997/03/14 15:58:13  lzheng
65  * Dealing with complier optimization related to the return value
66  *
67  * Revision 1.22  1997/02/26 23:42:50  mjrg
68  * First part on WindowsNT port: changes for compiling with Visual C++;
69  * moved unix specific code to unix.C
70  *
71  * Revision 1.21  1997/02/21 20:13:17  naim
72  * Moving files from paradynd to dyninstAPI + moving references to dataReqNode
73  * out of the ast class. The is the first pre-dyninstAPI commit! - naim
74  *
75  * Revision 1.20  1997/01/27 19:40:38  naim
76  * Part of the base instrumentation for supporting multithreaded applications
77  * (vectors of counter/timers) implemented for all current platforms +
78  * different bug fixes - naim
79  *
80  * Revision 1.19  1996/11/14 14:26:58  naim
81  * Changing AstNodes back to pointers to improve performance - naim
82  *
83  * Revision 1.18  1996/11/11 01:44:56  lzheng
84  * Moved the instructions which is used to caculate the observed cost
85  * from the miniTramps to baseTramp
86  *
87  * Revision 1.17  1996/10/31 08:36:11  tamches
88  * the shm-sampling commit; added noCost param to several fns
89  *
90  * Revision 1.16  1996/09/13 21:41:56  mjrg
91  * Implemented opcode ReturnVal for ast's to get the return value of functions.
92  * Added missing calls to free registers in Ast.generateCode and emitFuncCall.
93  * Removed architecture dependencies from inst.C.
94  * Changed code to allow base tramps of variable size.
95  *
96  * Revision 1.15  1996/08/20 19:06:29  lzheng
97  * Implementation of moving multiple instructions sequence
98  * and splitting the instrumentation into two phases
99  *
100  * Revision 1.14  1996/08/16 21:18:16  tamches
101  * updated copyright for release 1.1
102  *
103  * Revision 1.13  1996/04/26 20:04:32  lzheng
104  * Moved the defination of emitFuncCall from inst.h to here.
105  *
106  * Revision 1.12  1996/03/25 20:20:06  tamches
107  * the reduce-mem-leaks-in-paradynd commit
108  *
109  * Revision 1.11  1996/03/20 17:02:42  mjrg
110  * Added multiple arguments to calls.
111  * Instrument pvm_send instead of pvm_recv to get tags.
112  *
113  * Revision 1.10  1995/08/24 15:03:45  hollings
114  * AIX/SP-2 port (including option for split instruction/data heaps)
115  * Tracing of rexec (correctly spawns a paradynd if needed)
116  * Added rtinst function to read getrusage stats (can now be used in metrics)
117  * Critical Path
118  * Improved Error reporting in MDL sematic checks
119  * Fixed MDL Function call statement
120  * Fixed bugs in TK usage (strings passed where UID expected)
121  *
122  * Revision 1.9  1995/05/18  10:29:58  markc
123  * Added new opcode DataAddr
124  *
125  * Revision 1.8  1995/03/10  19:29:13  hollings
126  * Added code to include base tramp cost in first mini-tramp.
127  *
128  */
129
130 //
131 // Define a AST class for use in generating primitive and pred calls
132 //
133 //
134
135 #include <stdio.h>
136 #include "dyninstAPI/src/inst.h"
137 #include "util/h/Vector.h"
138 #include "util/h/Dictionary.h"
139 #include "util/h/String.h"
140
141 class BPatch_type;
142
143 // a register.
144 typedef int reg;
145
146 class registerSlot {
147  public:
148     int number;         // what register is it
149     bool inUse;         // free or in use.
150     bool needsSaving;   // been used since last rest
151     bool mustRestore;   // need to restore it before we are done.               
152     bool startsLive;    // starts life as a live register.
153 };
154
155 class registerSpace {
156     public:
157         registerSpace(int dCount, int *deads, int lCount, int *lives);
158         reg allocateRegister(char *insn, unsigned &base, bool noCost);
159         void freeRegister(int reg);
160         void resetSpace();
161         bool isFreeRegister(reg reg_number);
162         int getRegisterCount() { return numRegisters; }
163         registerSlot *getRegSlot(int i) { return (&registers[i]); }
164         bool readOnlyRegister(reg reg_number);
165         void keep_register(reg k);
166         void unkeep_register(reg k);
167         bool is_keep_register(reg k);
168     private:
169         int numRegisters;
170         int highWaterRegister;
171         registerSlot *registers;
172         vector<reg> keep_list;
173 };
174
175 class AstNode {
176     public:
177         enum nodeType { sequenceNode, opCodeNode, operandNode, callNode };
178         enum operandType { Constant, ConstantPtr, ConstantString,
179                            DataValue, DataPtr, 
180                            DataId, DataIndir, DataReg,
181                            Param, ReturnVal, DataAddr };
182
183         AstNode(); // mdl.C
184         AstNode(const string &func, AstNode *l, AstNode *r);
185         AstNode(const string &func, AstNode *l); // needed by inst.C
186         AstNode(operandType ot, void *arg);
187         AstNode(AstNode *l, AstNode *r);
188
189 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)  
190     public:     
191         bool astFlag;  
192         void sysFlag(instPoint *location);    
193
194         void optRetVal(AstNode *opt);
195 #endif
196
197     private:
198         AstNode(opCode); // like AstNode(opCode, const AstNode &, 
199                          //              const AstNode &)
200                          // but assumes "NULL" for both child ptrs
201     public:
202         AstNode(opCode, AstNode *left); 
203         // assumes "NULL" for right child ptr
204         // needed by inst.C and stuff in ast.C
205
206     public:
207         AstNode(operandType ot, AstNode *l);
208         AstNode(opCode ot, AstNode *l, AstNode *r);
209         AstNode(const string &func, vector<AstNode *> &ast_args);
210
211         AstNode(AstNode *src);
212         AstNode &operator=(const AstNode &src);
213
214        ~AstNode();
215
216         int generateTramp(process *proc, char *i, unsigned &base,
217                           int &trampCost, bool noCost);
218         reg generateCode(process *proc, registerSpace *rs, char *i, 
219                          unsigned &base, bool noCost);
220         reg generateCode_phase2(process *proc, registerSpace *rs, char *i, 
221                                 unsigned &base, bool noCost);
222
223         int cost() const;       // return the # of instruction times in the ast.
224         void print() const;
225         int referenceCount;     // Reference count for freeing memory
226         int useCount;           // Reference count for generating code
227         void setUseCount(void); // Set values for useCount
228         void cleanUseCount(void);
229         void printUseCount(void);
230         reg kept_register;      // Use when generating code for shared nodes
231         void updateOperandsRC(bool flag); // Update operand's referenceCount
232                                           // if "flag" is true, increments the
233                                           // counter, otherwise it decrements 
234                                           // the counter.
235         void printRC(void);
236     private:
237         nodeType type;
238         opCode op;                  // only for opCode nodes
239         string callee;              // only for call nodes
240         vector<AstNode *> operands; // only for call nodes
241         operandType oType;          // for operand nodes
242         void *oValue;               // operand value for operand nodes
243         const BPatch_type *bptype;  // type of corresponding BPatch_snippet
244         bool doTypeCheck;           // should operands be type checked
245
246         // These 2 vrbles must be pointers; otherwise, we'd have a recursive
247         // data structure with an infinite size.
248         // The only other option is to go with references, which would have
249         // to be initialized in the constructor and can't use NULL as a
250         // sentinel value...
251         AstNode *loperand;
252         AstNode *roperand;
253
254         int firstInsn;
255         int lastInsn;
256
257     public:
258         // Functions for getting and setting type decoration used by the
259         // dyninst API library
260 #ifdef BPATCH_LIBRARY
261         const BPatch_type *getType() { return bptype; };
262         void              setType(const BPatch_type *t) { bptype = t; }
263         void              setTypeChecking(bool x) { doTypeCheck = x; }
264         BPatch_type       *checkType();
265 #endif
266 };
267
268 AstNode *assignAst(AstNode *src);
269 void removeAst(AstNode *&ast);
270 void terminateAst(AstNode *&ast);
271 AstNode *createIf(AstNode *expression, AstNode *action);
272 AstNode *createCounter(const string &func, void *, AstNode *arg);
273 AstNode *createTimer(const string &func, void *, 
274                      vector<AstNode *> &arg_args);
275 unsigned emitFuncCall(opCode op, registerSpace *rs, char *i,unsigned &base, 
276                       const vector<AstNode *> &operands, const string &func,
277                       process *proc, bool noCost);
278
279 #endif