00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_CODEGEN_FRAME_HDR_GUARD
00010 #define COMMA_CODEGEN_FRAME_HDR_GUARD
00011 
00012 #include "SRInfo.h"
00013 
00014 #include "llvm/ADT/DenseMap.h"
00015 #include "llvm/ADT/ilist.h"
00016 #include "llvm/ADT/ilist_node.h"
00017 #include "llvm/Support/IRBuilder.h"
00018 
00019 namespace comma {
00020 
00021 class CodeGenRoutine;
00022 
00023 namespace activation {
00024 
00025 enum Tag {
00026     Slot,
00027     Bounds,
00028     Length,
00029 };
00030 
00031 class Property : public llvm::ilist_node<Property> {
00032 public:
00033     Property() : kind(Slot), value(0) { }
00034 
00035     Property(Tag kind, llvm::Value *value)
00036         : kind(kind), value(value) { }
00037 
00038     Tag getKind() const { return kind; }
00039 
00040     llvm::Value *getValue() { return value; }
00041 
00042     static bool classof(const Property *prop) { return true; }
00043 
00044 private:
00045     Tag kind;
00046     llvm::Value *value;
00047 };
00048 
00049 }; 
00050 
00051 class SRFrame {
00052 
00053 public:
00054     SRFrame(SRInfo *routineInfo,
00055             CodeGenRoutine &CGR, llvm::IRBuilder<> &Builder);
00056 
00057     ~SRFrame();
00058 
00060     SRInfo *getSRInfo() { return SRI; }
00061 
00063     SubroutineDecl *getDeclaration() { return SRI->getDeclaration(); }
00064 
00066     llvm::Function *getLLVMFunction() { return SRI->getLLVMFunction(); }
00067 
00070     llvm::IRBuilder<> &getIRBuilder() { return Builder; }
00071 
00073     llvm::BasicBlock *makeBasicBlock(const std::string &name = "",
00074                                      llvm::BasicBlock *insertBefore = 0);
00075 
00077 
00078 
00079     void pushFrame(llvm::BasicBlock *associatedBB);
00080 
00082     void popFrame();
00083 
00085     void stacksave();
00086 
00088     void addLandingPad();
00090 
00092     bool hasLandingPad();
00093 
00096     llvm::BasicBlock *getLandingPad();
00097 
00099     void removeLandingPad();
00100 
00102 
00103     llvm::Value *createTemp(const llvm::Type *type);
00104 
00105     void associate(const ValueDecl *decl, activation::Tag tag,
00106                    llvm::Value *slot);
00107 
00108     llvm::Value *lookup(const ValueDecl *decl, activation::Tag tag);
00109 
00110     llvm::Value *createEntry(const ValueDecl *decl, activation::Tag tag,
00111                              const llvm::Type *type) {
00112         llvm::Value *slot = createTemp(type);
00113         associate(decl, tag, slot);
00114         return slot;
00115     }
00117 
00119 
00120     void associate(const PrimaryType *type, activation::Tag tag,
00121                    llvm::Value *value);
00122 
00123     llvm::Value *lookup(const PrimaryType *type, activation::Tag tag);
00125 
00126     void emitReturn();
00127 
00128     llvm::Value *getReturnValue() { return returnValue; }
00129 
00130     llvm::Value *getImplicitContext() { return implicitContext; }
00131 
00132     void emitPrologue(llvm::BasicBlock *bodyBB);
00133     void emitEpilogue();
00134 
00135 private:
00138     class ActivationEntry {
00139 
00140     public:
00141         ActivationEntry() : plist() { }
00142 
00143         activation::Property *find(activation::Tag tag);
00144 
00145         void add(activation::Property *prop) { plist.push_front(prop); }
00146 
00147     private:
00148         ActivationEntry(const ActivationEntry &); 
00149         void operator=(const ActivationEntry &);  
00150 
00151         llvm::iplist<activation::Property> plist;
00152     };
00153 
00154     class Subframe {
00155 
00156     public:
00157         Subframe(SRFrame *context, Subframe *parent,
00158                  llvm::BasicBlock *entryBB);
00159         ~Subframe();
00160 
00162         bool hasParent() const { return parent != 0; }
00163 
00166         Subframe *getParent() { return parent; }
00167 
00170         void emitStacksave();
00171 
00174         void emitStackrestore();
00175 
00177         void addLandingPad();
00178 
00180         void removeLandingPad() { landingPad = 0; }
00181 
00185         llvm::BasicBlock *getLandingPad() { return landingPad; }
00186 
00188         llvm::BasicBlock *getEntryBB() { return entryBB; }
00189 
00190     private:
00192         SRFrame *SRF;
00193 
00196         Subframe *parent;
00197 
00200         llvm::Value *restorePtr;
00201 
00203         llvm::BasicBlock *landingPad;
00204 
00206         llvm::BasicBlock *entryBB;
00207     };
00208 
00211     SRInfo *SRI;
00212 
00214     llvm::IRBuilder<> &Builder;
00215 
00217     llvm::BasicBlock *allocaBB;
00218 
00220     llvm::BasicBlock *returnBB;
00221 
00223     Subframe *currentSubframe;
00224 
00227     llvm::Value *returnValue;
00228 
00230     llvm::Value *implicitContext;
00231 
00232     
00233     typedef llvm::DenseMap<const Ast*, ActivationEntry*> EntryMap;
00234     EntryMap entryTable;
00235 
00239     void injectSubroutineArgs(CodeGenRoutine &CGR);
00240 };
00241 
00242 } 
00243 
00244 #endif