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