Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / ast.h
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: ast.h,v 1.107 2008/05/12 22:12:47 giri Exp $
33
34 #ifndef AST_HDR
35 #define AST_HDR
36
37 //
38 // Define a AST class for use in generating primitive and pred calls
39 //
40
41 #include <stdio.h>
42 #include <string>
43 #include "common/h/Vector.h"
44 #include "common/h/Dictionary.h"
45 #include "common/h/Types.h"
46
47 // The great experiment: boost shared_ptr libraries
48 #include <dyn_detail/boost/shared_ptr.hpp>
49 #include "BPatch_type.h"
50
51 class process;
52 class AddressSpace;
53 class instPoint;
54 class int_function;
55 class int_variable;
56
57 class codeGen;
58 class codeRange;
59 class instruction;
60 class BPatch_instruction; // Memory, etc. are at BPatch. Might want to move 'em.
61 //class BPatch_type;
62 class image_variable;
63
64 // a register number, e.g. [0,31]
65 // typedef int reg; // see new Register type in "common/h/Types.h"
66
67 #include "opcode.h"
68
69 // Register retention mechanism...
70 // If we've already calculated a result, then we want to reuse it if it's
71 // still available. This means it was calculated along a path that reaches the
72 // current point (not inside a conditional) and the register hasn't been
73 // reused. We handle this so:
74 //
75 // 1) Iterate over the AST tree and see if any node is reached more than once;
76 // if so, mark it as potentially being worth keeping around. We can do this
77 // because we use pointers; a better approach would be a comparison operator.
78 // 2) Start generation at "level 0". 
79 // 3) When a conditional AST is reached, generate each child at level+1.
80 // 4) When the AST is reached during code generation, and doesn't have a register:
81 // 4a) Allocate a register for it;
82 // 4b) Enter that register, the AST node, and the current level in the global table.
83 // 5) If it does have a register, reuse it. 
84 // 6) When the conditionally executed branch is finished, clean all entries in
85 // the table with that level value (undoing all kept registers along that
86 // path).
87 // 7) If we need a register, the register allocator (registerSpace) can forcibly
88 // undo this optimization and grab a register. Grab the register from the AstNode
89 // with the lowest usage count.
90
91 class AstNode;
92 typedef dyn_detail::boost::shared_ptr<AstNode> AstNodePtr;
93 class AstMiniTrampNode;
94 typedef dyn_detail::boost::shared_ptr<AstMiniTrampNode> AstMiniTrampNodePtr;
95
96 class registerSpace;
97
98 class regTracker_t {
99 public:
100         class commonExpressionTracker {
101         public:
102                 Register keptRegister;  
103                 int keptLevel;
104                 commonExpressionTracker() : keptRegister(REG_NULL), keptLevel(-1) {};
105         };
106
107         int condLevel;
108         
109         static unsigned astHash(AstNode * const &ast);
110
111         regTracker_t() : condLevel(0), tracker(astHash) {};
112
113         dictionary_hash<AstNode *, commonExpressionTracker> tracker;
114
115         void addKeptRegister(codeGen &gen, AstNode *n, Register reg);
116         void removeKeptRegister(codeGen &gen, AstNode *n);
117         Register hasKeptRegister(AstNode *n);
118         bool stealKeptRegister(Register reg); 
119
120         void reset();
121
122         void increaseConditionalLevel();
123         void decreaseAndClean(codeGen &gen);
124         void cleanKeptRegisters(int level);
125
126         void debugPrint();
127 };
128
129 class dataReqNode;
130 class AstNode {
131  public:
132    enum nodeType { sequenceNode_t, opCodeNode_t, operandNode_t, callNode_t };
133    enum operandType { Constant, 
134                       ConstantString,
135                       DataReg,
136                       DataIndir,
137                       Param,
138                       ReturnVal, 
139                       DataAddr,  // Used to represent a variable in memory
140                       FrameAddr, // Calculate FP 
141                       RegOffset, // Calculate *reg + offset; oValue is reg, loperand->oValue is offset. 
142                       //PreviousStackFrameDataReg,
143                       //RegValue, // A possibly spilled, possibly saved register.
144                       // Both the above are now: origRegister 
145                       origRegister,
146                       variableAddr,
147                       variableValue,
148                       undefOperandType };
149
150    enum memoryType {
151       EffectiveAddr,
152       BytesAccessed };
153
154    AstNode(); // mdl.C
155
156    // Factory methods....
157    static AstNodePtr nullNode();
158
159    static AstNodePtr labelNode(std::string &label);
160
161    static AstNodePtr operandNode(operandType ot, void *arg);
162    static AstNodePtr operandNode(operandType ot, AstNodePtr ast);
163    static AstNodePtr operandNode(operandType ot, const image_variable* iv);
164
165    static AstNodePtr memoryNode(memoryType ot, int which);
166
167    static AstNodePtr sequenceNode(pdvector<AstNodePtr > &sequence);
168         
169    static AstNodePtr variableNode(std::vector<AstNodePtr>&ast_wrappers_, std::vector<std::pair<Offset, Offset> > *ranges = NULL);
170
171    static AstNodePtr operatorNode(opCode ot, 
172                                   AstNodePtr l = AstNodePtr(), 
173                                   AstNodePtr r = AstNodePtr(), 
174                                   AstNodePtr e = AstNodePtr());
175
176    static AstNodePtr funcCallNode(const std::string &func, pdvector<AstNodePtr > &args, AddressSpace *addrSpace = NULL);
177    static AstNodePtr funcCallNode(int_function *func, pdvector<AstNodePtr > &args);
178    static AstNodePtr funcCallNode(int_function *func); // Special case for function call replacement.
179    static AstNodePtr funcCallNode(Address addr, pdvector<AstNodePtr > &args); // For when you absolutely need
180    // to jump somewhere.
181
182    static AstNodePtr funcReplacementNode(int_function *func);
183
184    static AstNodePtr insnNode(BPatch_instruction *insn);
185
186    // Acquire the thread index value - a 0...n labelling of threads.
187    static AstNodePtr threadIndexNode();
188
189    // TODO...
190    // Needs some way of marking what to save and restore... should be a registerSpace, really
191
192 #if 0
193    static AstNodePtr saveStateNode();
194    static AstNodePtr restoreStateNode();
195    static AstNodePtr trampGuardNode();
196 #endif
197
198    static AstNodePtr miniTrampNode(AstNodePtr tramp);
199
200    static AstNodePtr originalAddrNode();
201    static AstNodePtr actualAddrNode();
202    static AstNodePtr dynamicTargetNode();
203  
204    AstNode(AstNodePtr src);
205    //virtual AstNode &operator=(const AstNode &src);
206         
207    virtual ~AstNode();
208         
209    virtual bool generateCode(codeGen &gen, 
210                              bool noCost, 
211                              Address &retAddr,
212                              Register &retReg);
213
214    // Can't use default references....
215    virtual bool generateCode(codeGen &gen, 
216                              bool noCost);
217
218    // Can't use default references....
219    virtual bool generateCode(codeGen &gen, 
220                              bool noCost, 
221                              Register &retReg) { 
222       Address unused = ADDR_NULL;
223       return generateCode(gen, noCost,  unused, retReg);
224    }
225
226    // I don't know if there is an overload between address and register...
227    // so we'll toss in two different return types.
228    virtual bool generateCode_phase2(codeGen &gen,
229                                     bool noCost,
230                                     Address &retAddr,
231                                     Register &retReg);
232
233    // Perform whatever pre-processing steps are necessary.
234    virtual bool initRegisters(codeGen &gen);
235         
236    // Select the appropriate Variable AST as part of pre-processing
237    // steps before code generation.
238    virtual void setVariableAST(codeGen &) {}
239
240    unsigned getTreeSize();
241
242    bool decRefCount();
243
244    bool previousComputationValid(Register &reg,
245                                  codeGen &gen);
246    // Remove any kept register at a greater level than
247    // that provided (AKA that had been calculated within
248    // a conditional statement)
249    void cleanRegTracker(regTracker_t *tracker, int level);
250
251    virtual AstNodePtr operand() const { return AstNodePtr(); }
252
253    virtual bool containsFuncCall() const = 0;
254    virtual bool containsFuncJump() const = 0;
255    virtual bool usesAppRegister() const = 0;
256
257    enum CostStyleType { Min, Avg, Max };
258    int minCost() const {  return costHelper(Min);  }
259    int avgCost() const {  return costHelper(Avg);  }
260    int maxCost() const {  return costHelper(Max);  }
261
262         // return the # of instruction times in the ast.
263         virtual int costHelper(enum CostStyleType) const { return 0; }; 
264
265    int referenceCount;     // Reference count for freeing memory
266    int useCount;           // Reference count for generating code
267    void setUseCount(); // Set values for useCount
268    int getSize() { return size; };
269    void cleanUseCount(void);
270    bool checkUseCount(registerSpace*, bool&);
271    void printUseCount(void);
272         
273         void debugPrint(unsigned level = 0);
274         // Occasionally, we do not call .generateCode_phase2 for the
275         // referenced node, but generate code by hand. This routine decrements
276         // its use count properly
277         void decUseCount(codeGen &gen);
278
279         // Our children may have incorrect useCounts (most likely they 
280         // assume that we will not bother them again, which is wrong)
281         void fixChildrenCounts();
282
283         // Check if the node can be kept at all. Some nodes (e.g., storeOp)
284         // can not be cached
285         virtual bool canBeKept() const = 0;
286
287         // Allocate a register and make it available for sharing if our
288    // node is shared
289         Register allocateAndKeep(codeGen &gen, bool noCost);
290
291    // If someone needs to take this guy away.
292    bool stealRegister(Register reg);
293
294         // Check to see if path1 is a subpath of path2
295         bool subpath(const pdvector<AstNode*> &path1, 
296                 const pdvector<AstNode*> &path2) const;
297
298         // Return all children of this node ([lre]operand, ..., operands[])
299         virtual void getChildren(pdvector<AstNodePtr> &); 
300
301    void printRC(void);
302         virtual bool accessesParam(void);
303
304         virtual void setOValue(void *) { assert(0); }
305         virtual const void *getOValue() const { assert(0); return NULL; }
306         virtual const image_variable* getOVar() const {
307       return NULL;
308         }
309         
310         virtual void emitVariableStore(opCode, Register, Register, codeGen&, 
311                                   bool, registerSpace*, 
312                                   int, const instPoint*, AddressSpace*)
313         {
314       assert(!"Never call this on anything but an operand");
315         }
316         virtual void emitVariableLoad(opCode, Register, Register, codeGen&, 
317                                  bool, registerSpace*, 
318                                  int, const instPoint*, AddressSpace*)
319         {
320       assert(!"Never call this on anything but an operand");
321         }
322         // only function that's defined in metric.C (only used in metri.C)
323         bool condMatch(AstNode* a,
324                   pdvector<dataReqNode*> &data_tuple1,
325                   pdvector<dataReqNode*> &data_tuple2,
326                   pdvector<dataReqNode*> datareqs1,
327                   pdvector<dataReqNode*> datareqs2);
328
329
330         // DEBUG
331    virtual operandType getoType() const { return undefOperandType; }
332
333    virtual void setConstFunc(bool) {};
334
335  protected:
336         BPatch_type *bptype;  // type of corresponding BPatch_snippet
337         bool doTypeCheck;           // should operands be type checked
338         int size;                   // size of the operations (in bytes)
339
340
341  public:
342         // Functions for getting and setting type decoration used by the
343         // dyninst API library
344         //AstNode(operandType ot, int which); // for memory access
345         BPatch_type *getType();
346         void              setType(BPatch_type *t);
347         void              setTypeChecking(bool x) { doTypeCheck = x; }
348         virtual BPatch_type       *checkType();
349
350  private:
351    static AstNodePtr originalAddrNode_;
352    static AstNodePtr actualAddrNode_;
353    static AstNodePtr dynamicTargetNode_;
354 };
355
356
357 class AstNullNode : public AstNode {
358  public:
359     AstNullNode() : AstNode() {};
360     virtual bool containsFuncCall() const;
361     virtual bool containsFuncJump() const;
362     virtual bool usesAppRegister() const;
363
364     bool canBeKept() const { return true; }
365  private:
366     virtual bool generateCode_phase2(codeGen &gen,
367                                      bool noCost,
368                                      Address &retAddr,
369                                      Register &retReg);
370 };
371
372 class AstLabelNode : public AstNode {
373  public:
374     AstLabelNode(std::string &label) : AstNode(), label_(label), generatedAddr_(0) {};
375     virtual bool containsFuncCall() const;
376     virtual bool containsFuncJump() const;
377     virtual bool usesAppRegister() const;
378
379         bool canBeKept() const { return true; }
380  private:
381     virtual bool generateCode_phase2(codeGen &gen,
382                                      bool noCost,
383                                      Address &retAddr,
384                                      Register &retReg);
385     std::string label_;
386     Address generatedAddr_;
387 };
388
389 class AstOperatorNode : public AstNode {
390  public:
391     AstOperatorNode(opCode opC, AstNodePtr l, AstNodePtr r = AstNodePtr(), AstNodePtr e = AstNodePtr());
392     
393     ~AstOperatorNode() {
394         //printf("at ~AstOperatorode()\n");
395         //debugPrint();
396     }
397
398     virtual int costHelper(enum CostStyleType costStyle) const; 
399
400     virtual BPatch_type   *checkType();
401     virtual bool accessesParam(void);         // Does this AST access "Param"
402
403     virtual bool canBeKept() const;
404
405     virtual void getChildren(pdvector<AstNodePtr> &children);
406     virtual bool containsFuncCall() const;
407     virtual bool containsFuncJump() const;
408     virtual bool usesAppRegister() const;
409
410
411     // We override initRegisters in the case of writing to an original register.
412     virtual bool initRegisters(codeGen &gen);
413     
414     virtual void setVariableAST(codeGen &gen);
415
416  private:
417
418     virtual bool generateCode_phase2(codeGen &gen,
419                                      bool noCost,
420                                      Address &retAddr,
421                                      Register &retReg);
422
423     bool generateOptimizedAssignment(codeGen &gen, bool noCost);
424
425     AstOperatorNode() {};
426     opCode op;
427     AstNodePtr loperand;
428     AstNodePtr roperand;
429     AstNodePtr eoperand;
430 };
431
432
433 class AstOperandNode : public AstNode {
434     friend class AstOperatorNode; // ARGH
435  public:
436     // Direct operand
437     AstOperandNode(operandType ot, void *arg);
438
439     // And an indirect (say, a load)
440     AstOperandNode(operandType ot, AstNodePtr l);
441
442     AstOperandNode(operandType ot, const image_variable* iv);
443     
444     ~AstOperandNode() {
445         //printf("at ~AstOperandNode()\n");
446         //debugPrint();
447         if (oType == ConstantString) free((char *)oValue);
448     }
449         
450     // Arguably, the previous should be an operation...
451     // however, they're kinda endemic.
452
453     virtual operandType getoType() const { return oType; };
454
455     virtual void setOValue(void *o) { oValue = o; }
456     virtual const void *getOValue() const { return oValue; };
457     virtual const image_variable* getOVar() const 
458     {
459       return oVar;
460     }
461     
462
463     virtual AstNodePtr operand() const { return operand_; }
464
465     virtual int costHelper(enum CostStyleType costStyle) const; 
466         
467     virtual BPatch_type   *checkType();
468
469     virtual bool accessesParam(void) { return (oType == Param); };
470     virtual bool canBeKept() const;
471         
472     virtual void getChildren(pdvector<AstNodePtr> &children);
473     
474     virtual void setVariableAST(codeGen &gen);
475
476     virtual bool containsFuncCall() const;
477     virtual bool containsFuncJump() const;
478     virtual bool usesAppRegister() const;
479
480     virtual void emitVariableStore(opCode op, Register src1, Register src2, codeGen& gen, 
481                            bool noCost, registerSpace* rs, 
482                            int size, const instPoint* point, AddressSpace* as);
483     virtual void emitVariableLoad(opCode op, Register src2, Register dest, codeGen& gen, 
484                           bool noCost, registerSpace* rs, 
485                           int size, const instPoint* point, AddressSpace* as);
486         
487  private:
488     virtual bool generateCode_phase2(codeGen &gen,
489                                      bool noCost,
490                                      Address &retAddr,
491                                      Register &retReg);
492     int_variable* lookUpVar(AddressSpace* as);
493     
494     AstOperandNode() {};
495
496     operandType oType;
497     void *oValue;
498     const image_variable* oVar;
499     AstNodePtr operand_;
500 };
501
502
503 class AstCallNode : public AstNode {
504  public:
505     AstCallNode(int_function *func, pdvector<AstNodePtr>&args);
506     AstCallNode(const std::string &str, pdvector<AstNodePtr>&args);
507     AstCallNode(Address addr, pdvector<AstNodePtr> &args);
508     AstCallNode(int_function *func);
509     
510     ~AstCallNode() {}
511
512     virtual int costHelper(enum CostStyleType costStyle) const; 
513         
514     virtual BPatch_type   *checkType();
515     virtual bool accessesParam(); 
516     virtual bool canBeKept() const;
517
518     virtual void getChildren(pdvector<AstNodePtr> &children);
519     virtual void setVariableAST(codeGen &gen);
520     virtual bool containsFuncCall() const; 
521     virtual bool containsFuncJump() const;
522     virtual bool usesAppRegister() const;
523
524
525     void setConstFunc(bool val) { constFunc_ = val; }
526
527     virtual bool initRegisters(codeGen &gen);
528
529  private:
530     virtual bool generateCode_phase2(codeGen &gen,
531                                      bool noCost,
532                                      Address &retAddr,
533                                      Register &retReg);
534
535     AstCallNode() {};
536     // Sometimes we just don't have enough information...
537     const std::string func_name_;
538     Address func_addr_;
539     
540     int_function *func_;
541     pdvector<AstNodePtr> args_;
542
543     bool callReplace_; // Node is intended for function call replacement
544     bool constFunc_;  // True if the output depends solely on 
545     // input parameters, or can otherwise be guaranteed to not change
546     // if executed multiple times in the same sequence - AKA 
547     // "can be kept".
548 };
549
550 class AstReplacementNode : public AstNode {
551  public:
552     AstReplacementNode(int_function *rep) :
553         AstNode(),
554         replacement(rep) {};
555
556     virtual bool canBeKept() const;
557     virtual bool containsFuncCall() const;
558     virtual bool containsFuncJump() const;
559     virtual bool usesAppRegister() const;
560
561
562  private:
563     virtual bool generateCode_phase2(codeGen &gen,
564                                      bool noCost,
565                                      Address &retAddr,
566                                      Register &retReg);
567
568     int_function *replacement;
569     AstReplacementNode() {};
570 };
571
572
573 class AstSequenceNode : public AstNode {
574  public:
575     AstSequenceNode(pdvector<AstNodePtr> &sequence);
576
577     ~AstSequenceNode() {}
578
579     virtual int costHelper(enum CostStyleType costStyle) const; 
580
581     virtual BPatch_type   *checkType();
582     virtual bool accessesParam();
583     virtual bool canBeKept() const;
584
585     virtual void getChildren(pdvector<AstNodePtr> &children);
586     virtual void setVariableAST(codeGen &gen);
587     virtual bool containsFuncCall() const;
588     virtual bool containsFuncJump() const;
589     virtual bool usesAppRegister() const;
590
591
592  private:
593     virtual bool generateCode_phase2(codeGen &gen,
594                                      bool noCost,
595                                      Address &retAddr,
596                                      Register &retReg);
597
598     AstSequenceNode() {};
599     pdvector<AstNodePtr> sequence_;
600 };
601
602 class AstVariableNode : public AstNode {
603   public:
604     AstVariableNode(std::vector<AstNodePtr>&ast_wrappers, std::vector<std::pair<Offset, Offset> >*ranges);
605
606     ~AstVariableNode() {}
607
608     virtual int costHelper(enum CostStyleType costStyle) const; 
609
610     virtual BPatch_type   *checkType() { return getType(); }
611     virtual bool accessesParam();
612     virtual bool canBeKept() const;
613     virtual operandType getoType() const { return ast_wrappers_[index]->getoType(); };
614     virtual AstNodePtr operand() const { return ast_wrappers_[index]->operand(); }
615     virtual const void *getOValue() const { return ast_wrappers_[index]->getOValue(); };
616
617     virtual void setVariableAST(codeGen &gen);
618     virtual void getChildren(pdvector<AstNodePtr> &children);
619     virtual bool containsFuncCall() const;
620     virtual bool containsFuncJump() const;
621     virtual bool usesAppRegister() const;
622
623
624  private:
625     virtual bool generateCode_phase2(codeGen &gen,
626                                      bool noCost,
627                                      Address &retAddr,
628                                      Register &retReg);
629
630     AstVariableNode() {};
631     std::vector<AstNodePtr>ast_wrappers_;
632     std::vector<std::pair<Offset, Offset> > *ranges_;
633     unsigned index;
634
635 };
636
637 class instruction;
638
639 class AstInsnNode : public AstNode {
640  public: 
641     AstInsnNode(instruction *insn, Address addr);
642
643     // Template methods...
644     virtual bool overrideBranchTarget(AstNodePtr) { return false; }
645     virtual bool overrideLoadAddr(AstNodePtr) { return false; }
646     virtual bool overrideStoreAddr(AstNodePtr) { return false; }
647
648         bool canBeKept() const { return false; }
649    virtual bool containsFuncCall() const;
650    virtual bool containsFuncJump() const;
651    virtual bool usesAppRegister() const;
652
653  protected:
654     virtual bool generateCode_phase2(codeGen &gen,
655                                      bool noCost,
656                                      Address &retAddr,
657                                      Register &retReg);
658
659     AstInsnNode() {};
660     instruction *insn_;
661     Address origAddr_; // The instruction class should wrap an address, but _wow_
662     // reengineering
663 };
664
665 class AstInsnBranchNode : public AstInsnNode {
666  public:
667     AstInsnBranchNode(instruction *insn, Address addr) : AstInsnNode(insn, addr), target_() {};
668
669     virtual bool overrideBranchTarget(AstNodePtr t) { target_ = t; return true; }
670     virtual bool containsFuncCall() const;
671     virtual bool containsFuncJump() const;
672     virtual bool usesAppRegister() const;
673
674     virtual void setVariableAST(codeGen &gen);
675     
676  protected:
677     virtual bool generateCode_phase2(codeGen &gen,
678                                      bool noCost,
679                                      Address &retAddr,
680                                      Register &retReg);
681     
682     AstNodePtr target_;
683 };
684
685 class AstInsnMemoryNode : public AstInsnNode {
686  public:
687     AstInsnMemoryNode(instruction *insn, Address addr) : AstInsnNode(insn, addr), load_(), store_() {};
688     
689     virtual bool overrideLoadAddr(AstNodePtr l) { load_ = l; return true; }
690     virtual bool overrideStoreAddr(AstNodePtr s) { store_ = s; return true; }
691     virtual bool containsFuncCall() const;
692     virtual bool containsFuncJump() const;
693     virtual bool usesAppRegister() const;
694
695     virtual void setVariableAST(codeGen &gen);
696
697  protected:
698     virtual bool generateCode_phase2(codeGen &gen,
699                                      bool noCost,
700                                      Address &retAddr,
701                                      Register &retReg);
702     
703     AstNodePtr load_;
704     AstNodePtr store_;
705 };
706
707
708 class AstMiniTrampNode : public AstNode {
709  public:
710     AstMiniTrampNode(AstNodePtr ast) {
711        if (ast != AstNodePtr())
712           ast->referenceCount++;
713        ast_ = ast;
714     }
715
716     Address generateTramp(codeGen &gen, 
717                           int &trampCost, 
718                           bool noCost);
719             
720     virtual ~AstMiniTrampNode() {}    
721
722     virtual bool accessesParam(void) { return ast_->accessesParam(); } 
723
724     virtual void getChildren(pdvector<AstNodePtr> &children);
725     virtual void setVariableAST(codeGen &gen);
726
727     virtual bool containsFuncCall() const;
728     virtual bool containsFuncJump() const;
729     virtual bool usesAppRegister() const;
730
731     bool canBeKept() const;
732
733     AstNodePtr getAST() { return ast_; }
734  private:
735     AstMiniTrampNode() {};
736
737     bool inline_;
738     AstNodePtr ast_;
739 };
740
741 class AstMemoryNode : public AstNode {
742  public:
743     AstMemoryNode(memoryType mem, unsigned which);
744         bool canBeKept() const;
745    virtual bool containsFuncCall() const;
746    virtual bool containsFuncJump() const;
747    virtual bool usesAppRegister() const;
748
749  private:
750     virtual bool generateCode_phase2(codeGen &gen,
751                                      bool noCost,
752                                      Address &retAddr,
753                                      Register &retReg);
754     
755     AstMemoryNode() {};
756     memoryType mem_;
757     unsigned which_;
758 };
759
760 class AstOriginalAddrNode : public AstNode {
761  public:
762     AstOriginalAddrNode() {};
763
764     virtual ~AstOriginalAddrNode() {};
765
766     virtual BPatch_type *checkType() { return getType(); };
767     virtual bool canBeKept() const { return true; }
768     virtual bool containsFuncCall() const;
769     virtual bool containsFuncJump() const;
770     virtual bool usesAppRegister() const;
771
772  private:
773     virtual bool generateCode_phase2(codeGen &gen,
774                                      bool noCost,
775                                      Address &retAddr,
776                                      Register &retReg);
777 };
778
779 class AstActualAddrNode : public AstNode {
780  public:
781     AstActualAddrNode() {};
782
783     virtual ~AstActualAddrNode() {};
784
785     virtual BPatch_type *checkType() { return getType(); };
786     virtual bool canBeKept() const { return false; }
787     virtual bool containsFuncCall() const;
788     virtual bool containsFuncJump() const;
789     virtual bool usesAppRegister() const;
790
791  private:
792     virtual bool generateCode_phase2(codeGen &gen,
793                                      bool noCost,
794                                      Address &retAddr,
795                                      Register &retReg);
796 };
797
798 class AstDynamicTargetNode : public AstNode {
799  public:
800     AstDynamicTargetNode() {};
801
802     virtual ~AstDynamicTargetNode() {};
803
804     virtual BPatch_type *checkType() { return getType(); };
805     virtual bool canBeKept() const { return false; }
806     virtual bool containsFuncCall() const;
807     virtual bool containsFuncJump() const;
808     virtual bool usesAppRegister() const;
809
810  private:
811     virtual bool generateCode_phase2(codeGen &gen,
812                                      bool noCost,
813                                      Address &retAddr,
814                                      Register &retReg);
815 };
816
817 void emitLoadPreviousStackFrameRegister(Address register_num,
818                                         Register dest,
819                                         codeGen &gen,
820                                         int size,
821                                         bool noCost);
822 void emitStorePreviousStackFrameRegister(Address register_num,
823                                          Register src,
824                                          codeGen &gen,
825                                          int size,
826                                          bool noCost);
827 void emitFuncJump(opCode op, codeGen &gen,
828                   int_function *func, AddressSpace *addrSpace,
829                   const instPoint *loc, bool noCost);
830
831
832 #endif /* AST_HDR */