00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00013 
00014 
00015 #ifndef COMMA_CODEGEN_BOUNDSEMITTER_HDR_GUARD
00016 #define COMMA_CODEGEN_BOUNDSEMITTER_HDR_GUARD
00017 
00018 #include "comma/ast/AstBase.h"
00019 
00020 #include "llvm/Support/IRBuilder.h"
00021 
00022 namespace comma {
00023 
00024 class CodeGen;
00025 class CodeGenRoutine;
00026 class CodeGenTypes;
00027 class Range;
00028 
00038 class BoundsEmitter {
00039 
00040 public:
00041     BoundsEmitter(CodeGenRoutine &CGR);
00042 
00047     typedef std::pair<llvm::Value*, llvm::Value*> LUPair;
00048 
00054     const llvm::StructType *getType(const ArrayType *arrTy);
00055 
00057     static llvm::Value *getLowerBound(llvm::IRBuilder<> &Builder,
00058                                       llvm::Value *bounds, unsigned index) {
00059         llvm::Value *res;
00060         index = 2 * index;
00061         if (llvm::isa<llvm::PointerType>(bounds->getType())) {
00062             res = Builder.CreateConstInBoundsGEP2_32(bounds, 0, index);
00063             res = Builder.CreateLoad(res);
00064         }
00065         else
00066             res = Builder.CreateExtractValue(bounds, index);
00067         return res;
00068     }
00069 
00071     static llvm::Value *getUpperBound(llvm::IRBuilder<> &Builder,
00072                                       llvm::Value *bounds, unsigned index) {
00073         llvm::Value *res;
00074         index = 2 * index + 1;
00075         if (llvm::isa<llvm::PointerType>(bounds->getType())) {
00076             res = Builder.CreateConstInBoundsGEP2_32(bounds, 0, index);
00077             res = Builder.CreateLoad(res);
00078         }
00079         else
00080             res = Builder.CreateExtractValue(bounds, index);
00081         return res;
00082     }
00083 
00086     static LUPair getBounds(llvm::IRBuilder<> &Builder, llvm::Value *bounds,
00087                             unsigned index) {
00088         std::pair<llvm::Value*, llvm::Value*> res;
00089         res.first = getLowerBound(Builder, bounds, index);
00090         res.second = getUpperBound(Builder, bounds, index);
00091         return res;
00092     }
00093 
00101     llvm::Value *synthScalarBounds(llvm::IRBuilder<> &Builder,
00102                                    const DiscreteType *type);
00103 
00111     LUPair getScalarBounds(llvm::IRBuilder<> &Builder,
00112                            const DiscreteType *type);
00113 
00116     llvm::Value *getLowerBound(llvm::IRBuilder<> &Builder,
00117                                const DiscreteType *type);
00118 
00121     llvm::Value *getUpperBound(llvm::IRBuilder<> &Builder,
00122                                const DiscreteType *type);
00123 
00125     llvm::Value *getLowerBound(llvm::IRBuilder<> &Builder, const Range *range);
00126 
00128     llvm::Value *getUpperBound(llvm::IRBuilder<> &Builder, const Range *range);
00129 
00131     llvm::Value *synthRange(llvm::IRBuilder<> &Builder, const Range *range);
00132 
00136     llvm::Value *synthRange(llvm::IRBuilder<> &Builder,
00137                             llvm::Value *lower, llvm::Value *upper);
00138 
00140     LUPair getRange(llvm::IRBuilder<> &Builder, const Range *range);
00141 
00146     llvm::Value *computeBoundLength(llvm::IRBuilder<> &Builder,
00147                                     llvm::Value *bounds, unsigned index);
00148 
00152     llvm::Value *computeTotalBoundLength(llvm::IRBuilder<> &Builder,
00153                                          llvm::Value *bounds);
00154 
00157     llvm::Value *computeIsNull(llvm::IRBuilder<> &Builder,
00158                                llvm::Value *bounds, unsigned index);
00159 
00161     llvm::Value *synthArrayBounds(llvm::IRBuilder<> &Builder, ArrayType *arrTy);
00162 
00166     llvm::Constant *synthStaticArrayBounds(llvm::IRBuilder<> &Builder,
00167                                            ArrayType *arrTy);
00168 
00174     llvm::Value *synthAggregateBounds(llvm::IRBuilder<> &Builder,
00175                                       AggregateExpr *agg,
00176                                       llvm::Value *dst = 0);
00177 
00178 private:
00179     CodeGenRoutine &CGR;        
00180     CodeGen &CG;                
00181     CodeGenTypes &CGT;          
00182 };
00183 
00184 } 
00185 
00186 #endif