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