diff --git a/dmd/expression.c b/dmd/expression.c index c5735c69..39e8e850 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -887,6 +887,10 @@ Expression::Expression(Loc loc, enum TOK op, int size) this->op = op; this->size = size; type = NULL; + +#if IN_LLVM + cachedLvalue = NULL; +#endif } Expression *Expression::syntaxCopy() diff --git a/dmd/expression.h b/dmd/expression.h index 077381c3..ad7287a5 100644 --- a/dmd/expression.h +++ b/dmd/expression.h @@ -46,10 +46,10 @@ struct OverloadSet; enum TOK; +#if IN_DMD // Back end struct IRState; -#if IN_DMD struct dt_t; struct elem; struct Symbol; // back end symbol @@ -60,11 +60,9 @@ union tree_node; typedef union tree_node elem; #endif #if IN_LLVM +struct IRState; struct DValue; -typedef DValue elem; - -namespace llvm -{ +namespace llvm { class Constant; class ConstantInt; } @@ -160,13 +158,18 @@ struct Expression : Object virtual void buildArrayIdent(OutBuffer *buf, Expressions *arguments); virtual Expression *buildArrayLoop(Arguments *fparams); +#if IN_DMD // Back end virtual elem *toElem(IRState *irs); -#if IN_DMD virtual dt_t **toDt(dt_t **pdt); -#elif IN_LLVM - // LDC +#endif + +#if IN_LLVM + virtual DValue* toElem(IRState* irs); virtual llvm::Constant *toConstElem(IRState *irs); + virtual void cacheLvalue(IRState* irs); + + llvm::Value* cachedLvalue; #endif }; @@ -191,12 +194,12 @@ struct IntegerExp : Expression void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); Expression *toLvalue(Scope *sc, Expression *e); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -219,12 +222,12 @@ struct RealExp : Expression int isBool(int result); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -250,12 +253,12 @@ struct ComplexExp : Expression #ifdef _DH OutBuffer hexp; #endif - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -305,7 +308,13 @@ struct ThisExp : Expression Expression *doInline(InlineDoState *ids); //Expression *inlineScan(InlineScanState *iss); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct SuperExp : ThisExp @@ -332,12 +341,12 @@ struct NullExp : Expression MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); Expression *interpret(InterState *istate); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -365,12 +374,12 @@ struct StringExp : Expression unsigned charAt(size_t i); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -392,11 +401,17 @@ struct TupleExp : Expression Expression *optimize(int result); Expression *interpret(InterState *istate); Expression *castTo(Scope *sc, Type *t); +#if IN_DMD elem *toElem(IRState *irs); +#endif int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct ArrayLiteralExp : Expression @@ -409,7 +424,6 @@ struct ArrayLiteralExp : Expression Expression *syntaxCopy(); Expression *semantic(Scope *sc); int isBool(int result); - elem *toElem(IRState *irs); int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); @@ -418,16 +432,18 @@ struct ArrayLiteralExp : Expression Expression *interpret(InterState *istate); MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); -#if IN_DMD - dt_t **toDt(dt_t **pdt); -#elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); -#endif int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); + +#if IN_DMD + elem *toElem(IRState *irs); + dt_t **toDt(dt_t **pdt); +#elif IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; struct AssocArrayLiteralExp : Expression @@ -440,7 +456,9 @@ struct AssocArrayLiteralExp : Expression Expression *syntaxCopy(); Expression *semantic(Scope *sc); int isBool(int result); +#if IN_DMD elem *toElem(IRState *irs); +#endif int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); @@ -453,9 +471,10 @@ struct AssocArrayLiteralExp : Expression int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); + #if IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); #endif }; @@ -477,25 +496,25 @@ struct StructLiteralExp : Expression Expression *semantic(Scope *sc); Expression *getField(Type *type, unsigned offset); int getFieldIndex(Type *type, unsigned offset); - elem *toElem(IRState *irs); int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); void scanForNestedRef(Scope *sc); Expression *optimize(int result); Expression *interpret(InterState *istate); -#if IN_DMD - dt_t **toDt(dt_t **pdt); -#elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); -#endif Expression *toLvalue(Scope *sc, Expression *e); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); - + +#if IN_DMD + elem *toElem(IRState *irs); + dt_t **toDt(dt_t **pdt); +#elif IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; struct TypeDotIdExp : Expression @@ -506,7 +525,13 @@ struct TypeDotIdExp : Expression Expression *syntaxCopy(); Expression *semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct TypeExp : Expression @@ -516,7 +541,13 @@ struct TypeExp : Expression Expression *semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Expression *optimize(int result); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct ScopeExp : Expression @@ -526,8 +557,14 @@ struct ScopeExp : Expression ScopeExp(Loc loc, ScopeDsymbol *sds); Expression *syntaxCopy(); Expression *semantic(Scope *sc); +#if IN_DMD elem *toElem(IRState *irs); +#endif void toCBuffer(OutBuffer *buf, HdrGenState *hgs); + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct TemplateExp : Expression @@ -556,7 +593,9 @@ struct NewExp : Expression Type *newtype, Expressions *arguments); Expression *syntaxCopy(); Expression *semantic(Scope *sc); +#if IN_DMD elem *toElem(IRState *irs); +#endif int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void scanForNestedRef(Scope *sc); @@ -564,6 +603,10 @@ struct NewExp : Expression //int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); //Expression *inlineScan(InlineScanState *iss); + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct NewAnonClassExp : Expression @@ -601,10 +644,14 @@ struct SymOffExp : Expression Expression *castTo(Scope *sc, Type *t); void scanForNestedRef(Scope *sc); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); #endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; // Variable @@ -624,18 +671,21 @@ struct VarExp : Expression void checkEscape(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); - elem *toElem(IRState *irs); #if IN_DMD + elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); -#elif IN_LLVM - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); #endif void scanForNestedRef(Scope *sc); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); //Expression *inlineScan(InlineScanState *iss); + +#if IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); + void cacheLvalue(IRState* irs); +#endif }; #if DMDV2 @@ -663,14 +713,18 @@ struct FuncExp : Expression void scanForNestedRef(Scope *sc); char *toChars(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif int inlineCost(InlineCostState *ics); //Expression *doInline(InlineDoState *ids); //Expression *inlineScan(InlineScanState *iss); - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); +#if IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; // Declaration of a symbol @@ -685,12 +739,18 @@ struct DeclarationExp : Expression Expression *interpret(InterState *istate); int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif void scanForNestedRef(Scope *sc); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct TypeidExp : Expression @@ -723,7 +783,13 @@ struct HaltExp : Expression void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int checkSideEffect(int flag); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct IsExp : Expression @@ -796,7 +862,9 @@ struct BinExp : Expression Expression *op_overload(Scope *sc); +#if IN_DMD elem *toElemBin(IRState *irs, int op); +#endif }; struct BinAssignExp : BinExp @@ -836,7 +904,13 @@ struct AssertExp : UnaExp Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct DotIdExp : UnaExp @@ -869,7 +943,14 @@ struct DotVarExp : UnaExp Expression *interpret(InterState *istate); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void dump(int indent); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); + void cacheLvalue(IRState* irs); +#endif }; struct DotTemplateInstanceExp : UnaExp @@ -895,7 +976,13 @@ struct DelegateExp : UnaExp void dump(int indent); int inlineCost(InlineCostState *ics); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct DotTypeExp : UnaExp @@ -905,7 +992,13 @@ struct DotTypeExp : UnaExp DotTypeExp(Loc loc, Expression *e, Dsymbol *sym); Expression *semantic(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct CallExp : UnaExp @@ -924,25 +1017,36 @@ struct CallExp : UnaExp int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void dump(int indent); +#if IN_DMD elem *toElem(IRState *irs); +#endif void scanForNestedRef(Scope *sc); Expression *toLvalue(Scope *sc, Expression *e); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct AddrExp : UnaExp { AddrExp(Loc loc, Expression *e); Expression *semantic(Scope *sc); +#if IN_DMD elem *toElem(IRState *irs); +#endif MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); Expression *optimize(int result); - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); + +#if IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; struct PtrExp : UnaExp @@ -952,9 +1056,16 @@ struct PtrExp : UnaExp Expression *semantic(Scope *sc); Expression *toLvalue(Scope *sc, Expression *e); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif Expression *optimize(int result); Expression *interpret(InterState *istate); + +#if IN_LLVM + DValue* toElem(IRState* irs); + void cacheLvalue(IRState* irs); +#endif }; struct NegExp : UnaExp @@ -969,7 +1080,13 @@ struct NegExp : UnaExp // For operator overloading Identifier *opId(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct UAddExp : UnaExp @@ -993,7 +1110,13 @@ struct ComExp : UnaExp // For operator overloading Identifier *opId(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct NotExp : UnaExp @@ -1003,7 +1126,13 @@ struct NotExp : UnaExp Expression *optimize(int result); Expression *interpret(InterState *istate); int isBit(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct BoolExp : UnaExp @@ -1013,7 +1142,13 @@ struct BoolExp : UnaExp Expression *optimize(int result); Expression *interpret(InterState *istate); int isBit(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct DeleteExp : UnaExp @@ -1023,7 +1158,13 @@ struct DeleteExp : UnaExp Expression *checkToBoolean(); int checkSideEffect(int flag); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct CastExp : UnaExp @@ -1039,13 +1180,17 @@ struct CastExp : UnaExp int checkSideEffect(int flag); void checkEscape(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif // For operator overloading Identifier *opId(); - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); +#if IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; @@ -1065,7 +1210,9 @@ struct SliceExp : UnaExp Expression *optimize(int result); Expression *interpret(InterState *istate); void dump(int indent); +#if IN_DMD elem *toElem(IRState *irs); +#endif void scanForNestedRef(Scope *sc); void buildArrayIdent(OutBuffer *buf, Expressions *arguments); Expression *buildArrayLoop(Arguments *fparams); @@ -1074,8 +1221,10 @@ struct SliceExp : UnaExp Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); +#if IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); +#endif }; struct ArrayLengthExp : UnaExp @@ -1085,7 +1234,13 @@ struct ArrayLengthExp : UnaExp Expression *optimize(int result); Expression *interpret(InterState *istate); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; // e1[a0,a1,a2,a3,...] @@ -1128,7 +1283,13 @@ struct CommaExp : BinExp int checkSideEffect(int flag); Expression *optimize(int result); Expression *interpret(InterState *istate); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct IndexExp : BinExp @@ -1146,9 +1307,13 @@ struct IndexExp : BinExp Expression *doInline(InlineDoState *ids); void scanForNestedRef(Scope *sc); +#if IN_DMD elem *toElem(IRState *irs); - // LDC - virtual llvm::Constant *toConstElem(IRState *irs); +#elif IN_LLVM + DValue* toElem(IRState* irs); + llvm::Constant *toConstElem(IRState *irs); + void cacheLvalue(IRState* irs); +#endif }; /* For both i++ and i-- @@ -1160,7 +1325,13 @@ struct PostExp : BinExp Expression *interpret(InterState *istate); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Identifier *opId(); // For operator overloading +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct AssignExp : BinExp @@ -1173,9 +1344,23 @@ struct AssignExp : BinExp Identifier *opId(); // For operator overloading void buildArrayIdent(OutBuffer *buf, Expressions *arguments); Expression *buildArrayLoop(Arguments *fparams); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; +#if IN_DMD +#define ASSIGNEXP_TOELEM elem *toElem(IRState *irs); +#elif IN_LLVM +#define ASSIGNEXP_TOELEM DValue* toElem(IRState *irs); +#else +#define ASSIGNEXP_TOELEM +#endif + #define ASSIGNEXP(op) \ struct op##AssignExp : BinExp \ { \ @@ -1187,7 +1372,7 @@ struct op##AssignExp : BinExp \ \ Identifier *opId(); /* For operator overloading */ \ \ - elem *toElem(IRState *irs); \ + ASSIGNEXP_TOELEM \ }; #define X(a) a @@ -1210,6 +1395,7 @@ ASSIGNEXP(Cat) #undef X #undef ASSIGNEXP +#undef ASSIGNEXP_TOELEM struct AddExp : BinExp { @@ -1225,7 +1411,13 @@ struct AddExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct MinExp : BinExp @@ -1241,7 +1433,13 @@ struct MinExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct CatExp : BinExp @@ -1255,7 +1453,13 @@ struct CatExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct MulExp : BinExp @@ -1272,7 +1476,13 @@ struct MulExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct DivExp : BinExp @@ -1288,7 +1498,13 @@ struct DivExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct ModExp : BinExp @@ -1304,7 +1520,13 @@ struct ModExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct ShlExp : BinExp @@ -1318,7 +1540,13 @@ struct ShlExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct ShrExp : BinExp @@ -1332,7 +1560,13 @@ struct ShrExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct UshrExp : BinExp @@ -1346,7 +1580,13 @@ struct UshrExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct AndExp : BinExp @@ -1363,7 +1603,13 @@ struct AndExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct OrExp : BinExp @@ -1380,7 +1626,13 @@ struct OrExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct XorExp : BinExp @@ -1397,7 +1649,13 @@ struct XorExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct OrOrExp : BinExp @@ -1409,7 +1667,13 @@ struct OrOrExp : BinExp Expression *optimize(int result); Expression *interpret(InterState *istate); int checkSideEffect(int flag); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct AndAndExp : BinExp @@ -1421,7 +1685,13 @@ struct AndAndExp : BinExp Expression *optimize(int result); Expression *interpret(InterState *istate); int checkSideEffect(int flag); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct CmpExp : BinExp @@ -1436,7 +1706,13 @@ struct CmpExp : BinExp int isCommutative(); Identifier *opId(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct InExp : BinExp @@ -1449,13 +1725,25 @@ struct InExp : BinExp Identifier *opId(); Identifier *opId_r(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct RemoveExp : BinExp { RemoveExp(Loc loc, Expression *e1, Expression *e2); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; // == and != @@ -1472,7 +1760,13 @@ struct EqualExp : BinExp int isCommutative(); Identifier *opId(); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; // === and !=== @@ -1484,7 +1778,13 @@ struct IdentityExp : BinExp int isBit(); Expression *optimize(int result); Expression *interpret(InterState *istate); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; /****************************************************************/ @@ -1512,7 +1812,13 @@ struct CondExp : BinExp Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); +#if IN_DMD elem *toElem(IRState *irs); +#endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; #if DMDV2 @@ -1557,8 +1863,12 @@ struct GEPExp : UnaExp void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Expression *toLvalue(Scope *sc, Expression *e); +#if IN_DMD elem *toElem(IRState *irs); +#elif IN_LLVM + DValue* toElem(IRState* irs); llvm::Constant *toConstElem(IRState *irs); +#endif }; #endif diff --git a/gen/complex.cpp b/gen/complex.cpp index b1bca2bd..08c46f63 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -429,16 +429,7 @@ DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to) } LLValue* pair = DtoAggrPair(DtoType(_to), re, im); - DValue* rval = new DImValue(_to, pair); - - // if the value we're casting is not a lvalue, the cast value can't be either - if (!val->isLVal()) { - return rval; - } - - // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. - // so we need to maintain the storage - return new DLRValue(val, rval); + return new DImValue(_to, pair); } else if (to->isimaginary()) { // FIXME: this loads both values, even when we only need one diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index dffb57d0..a00dfcb3 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -78,15 +78,3 @@ LLValue* DConstValue::getRVal() ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// - -Type*& DLRValue::getLType() -{ - if (DLRValue* lr = lvalue->isLRValue()) - { - return lr->getLType(); - } - else - { - return lvalue->getType(); - } -} diff --git a/gen/dvalue.h b/gen/dvalue.h index 4bbaf0e0..eb29094d 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -29,7 +29,6 @@ struct DVarValue; struct DFieldValue; struct DFuncValue; struct DSliceValue; -struct DLRValue; // base class for d-values struct DValue : Object @@ -48,7 +47,6 @@ struct DValue : Object virtual DFieldValue* isField() { return NULL; } virtual DSliceValue* isSlice() { return NULL; } virtual DFuncValue* isFunc() { return NULL; } - virtual DLRValue* isLRValue() { return NULL; } protected: DValue() {} @@ -147,25 +145,4 @@ struct DFuncValue : DValue virtual DFuncValue* isFunc() { return this; } }; -// l-value and r-value pair d-value -struct DLRValue : DValue -{ - DValue* lvalue; - DValue* rvalue; - - DLRValue(DValue* lval, DValue* rval) { - lvalue = lval; - rvalue = rval; - } - - virtual bool isLVal() { return true; } - virtual LLValue* getLVal() { return lvalue->isLVal() ? lvalue->getLVal() : lvalue->getRVal(); } - virtual LLValue* getRVal() { return rvalue->getRVal(); } - - Type*& getLType(); - Type*& getRType() { return rvalue->getType(); } - virtual Type*& getType() { return getRType(); } - virtual DLRValue* isLRValue() { return this; } -}; - #endif // LDC_GEN_DVALUE_H diff --git a/gen/functions.cpp b/gen/functions.cpp index 9c6395d4..d228f377 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -940,7 +940,7 @@ DValue* DtoArgument(Argument* fnarg, Expression* argexp) // ref/out arg if (fnarg && (fnarg->storageClass & (STCref | STCout))) { - if (arg->isVar() || arg->isLRValue()) + if (arg->isVar()) arg = new DImValue(argexp->type, arg->getLVal()); else arg = new DImValue(argexp->type, arg->getRVal()); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 8484a35b..b913404e 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -472,15 +472,9 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) DtoStore(r, l); } else if (t->iscomplex()) { - LLValue* dst; - if (DLRValue* lr = lhs->isLRValue()) { - dst = lr->getLVal(); - rhs = DtoCastComplex(loc, rhs, lr->getLType()); - } - else { - dst = lhs->getLVal(); - } - DtoStore(rhs->getRVal(), dst); + LLValue* dst = lhs->getLVal(); + LLValue* src = DtoCast(loc, rhs, lhs->getType())->getRVal(); + DtoStore(src, dst); } else { LLValue* l = lhs->getLVal(); @@ -489,14 +483,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; const LLType* lit = l->getType()->getContainedType(0); if (r->getType() != lit) { - // handle lvalue cast assignments - if (DLRValue* lr = lhs->isLRValue()) { - Logger::println("lvalue cast!"); - r = DtoCast(loc, rhs, lr->getLType())->getRVal(); - } - else { - r = DtoCast(loc, rhs, lhs->getType())->getRVal(); - } + r = DtoCast(loc, rhs, lhs->getType())->getRVal(); if (Logger::enabled()) Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; assert(r->getType() == l->getType()->getContainedType(0)); @@ -723,7 +710,13 @@ DValue* DtoCastDelegate(Loc& loc, DValue* val, Type* to) DValue* DtoCast(Loc& loc, DValue* val, Type* to) { Type* fromtype = val->getType()->toBasetype(); + Type* totype = to->toBasetype(); + if (fromtype->equals(totype)) + return val; + Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); + LOG_SCOPE; + if (fromtype->isintegral()) { return DtoCastInt(loc, val, to); } @@ -864,78 +857,6 @@ void DtoResolveDsymbol(Dsymbol* dsym) ////////////////////////////////////////////////////////////////////////////////////////// -void DtoDeclareDsymbol(Dsymbol* dsym) -{ - DtoResolveDsymbol(dsym); - - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoDeclareStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoDeclareClass(cd); - } - else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { - DtoDeclareFunction(fd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoDeclareTypeInfo(fd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoDeclareDsymbol"); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoConstInitDsymbol(Dsymbol* dsym) -{ - DtoDeclareDsymbol(dsym); - - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoConstInitStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoConstInitClass(cd); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoConstInitTypeInfo(fd); - } - else if (VarDeclaration* vd = dsym->isVarDeclaration()) { - DtoConstInitGlobal(vd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoConstInitDsymbol"); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -void DtoDefineDsymbol(Dsymbol* dsym) -{ - DtoConstInitDsymbol(dsym); - - if (StructDeclaration* sd = dsym->isStructDeclaration()) { - DtoDefineStruct(sd); - } - else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { - DtoDefineClass(cd); - } - else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { - Type::sir->addFunctionBody(fd->ir.irFunc); - } - else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) { - DtoDefineTypeInfo(fd); - } - else { - error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); - assert(0 && "unsupported dsymbol for DtoDefineDsymbol"); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - void DtoConstInitGlobal(VarDeclaration* vd) { vd->codegen(Type::sir); diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 536c8908..ea2f76f1 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -52,27 +52,29 @@ void DtoGoto(Loc loc, Identifier* target); // the scope created by the 'target' statement. void DtoEnclosingHandlers(Loc loc, Statement* target); -// enters a critical section +/// Enters a critical section. void DtoEnterCritical(LLValue* g); -// leaves a critical section +/// leaves a critical section. void DtoLeaveCritical(LLValue* g); -// enters a monitor lock +/// Enters a monitor lock. void DtoEnterMonitor(LLValue* v); -// leaves a monitor lock +/// Leaves a monitor lock. void DtoLeaveMonitor(LLValue* v); // nested variable and context helpers -// gets the context value for a call to a nested function or newing a class, with arbitrary nesting +/// Gets the context value for a call to a nested function or newing a nested +/// class with arbitrary nesting. LLValue* DtoNestedContext(Loc loc, Dsymbol* sym); -// gets the dvalue of a nested variable with arbitrary nesting + +/// Gets the DValue of a nested variable with arbitrary nesting. DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd); // basic operations void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs); -// create a null dvalue +/// Create a null DValue. DValue* DtoNullValue(Type* t); // casts @@ -88,11 +90,11 @@ DValue* DtoPaintType(Loc& loc, DValue* val, Type* to); // is template instance check, returns module where instantiated TemplateInstance* DtoIsTemplateInstance(Dsymbol* s); -// these are all basically drivers for the codegeneration called by the main loop +/// Generate code for the symbol. +/// Dispatches as appropriate. void DtoResolveDsymbol(Dsymbol* dsym); -void DtoDeclareDsymbol(Dsymbol* dsym); -void DtoDefineDsymbol(Dsymbol* dsym); -void DtoConstInitDsymbol(Dsymbol* dsym); + +/// Generates the constant initializer for a global variable. void DtoConstInitGlobal(VarDeclaration* vd); // declaration inside a declarationexp @@ -122,16 +124,16 @@ DValue* DtoBinRem(Type* resulttype, DValue* lhs, DValue* rhs); // target stuff void findDefaultTarget(); -// fixup an overloaded intrinsic name string +/// Fixup an overloaded intrinsic name string. void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, std::string& name); -// return true if the symbol should be defined in the current module, not just declared +/// Returns true if the symbol should be defined in the current module, not just declared. bool mustDefineSymbol(Dsymbol* s); -// returns true if the symbol needs template linkage, or just external +/// Returns true if the symbol needs template linkage, or just external. bool needsTemplateLinkage(Dsymbol* s); -// returns true if there is any unaligned type inside the aggregate +/// Returns true if there is any unaligned type inside the aggregate. bool hasUnalignedFields(Type* t); //////////////////////////////////////////// diff --git a/gen/structs.cpp b/gen/structs.cpp index b8fdc9d5..6fe7907b 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -487,6 +487,12 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) return val; } +////////////////////////////////////////////////////////////////////////////////////////// + +static void DtoDeclareStruct(StructDeclaration* sd); +static void DtoConstInitStruct(StructDeclaration* sd); +static void DtoDefineStruct(StructDeclaration* sd); + void DtoResolveStruct(StructDeclaration* sd) { // don't do anything if already been here @@ -584,7 +590,7 @@ void DtoResolveStruct(StructDeclaration* sd) ////////////////////////////////////////////////////////////////////////////////////////// -void DtoDeclareStruct(StructDeclaration* sd) +static void DtoDeclareStruct(StructDeclaration* sd) { DtoResolveStruct(sd); @@ -603,7 +609,7 @@ void DtoDeclareStruct(StructDeclaration* sd) ////////////////////////////////////////////////////////////////////////////////////////// -void DtoConstInitStruct(StructDeclaration* sd) +static void DtoConstInitStruct(StructDeclaration* sd) { DtoDeclareStruct(sd); @@ -654,7 +660,7 @@ void DtoConstInitStruct(StructDeclaration* sd) ////////////////////////////////////////////////////////////////////////////////////////// -void DtoDefineStruct(StructDeclaration* sd) +static void DtoDefineStruct(StructDeclaration* sd) { DtoConstInitStruct(sd); diff --git a/gen/structs.h b/gen/structs.h index f45230cf..9297d00a 100644 --- a/gen/structs.h +++ b/gen/structs.h @@ -3,35 +3,19 @@ struct StructInitializer; -LLConstant* DtoConstStructInitializer(StructInitializer* si); -std::vector DtoStructLiteralValues(const StructDeclaration* sd, const std::vector& inits); - -/** - * Resolves the llvm type for a struct - */ +/// Generate code for the struct. void DtoResolveStruct(StructDeclaration* sd); -/** - * Provides the llvm declaration for a struct - */ -void DtoDeclareStruct(StructDeclaration* sd); +/// Build constant struct initializer. +LLConstant* DtoConstStructInitializer(StructInitializer* si); -/** - * Constructs the constant default initializer a struct - */ -void DtoConstInitStruct(StructDeclaration* sd); +/// Build values for a struct literal. +std::vector DtoStructLiteralValues(const StructDeclaration* sd, const std::vector& inits); -/** - * Provides the llvm definition for a struct - */ -void DtoDefineStruct(StructDeclaration* sd); - -/** - * Returns a boolean=true if the two structs are equal - */ +/// Returns a boolean=true if the two structs are equal. LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs); -// index a struct one level +/// index a struct one level LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd); #endif diff --git a/gen/toir.cpp b/gen/toir.cpp index 3e4ad2d2..df76f6c3 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -41,6 +41,14 @@ ////////////////////////////////////////////////////////////////////////////////////////// +void Expression::cacheLvalue(IRState* irs) +{ + error("expression %s does not mask any l-value", toChars()); + fatal(); +} + +////////////////////////////////////////////////////////////////////////////////////////// + DValue* DeclarationExp::toElem(IRState* p) { Logger::print("DeclarationExp::toElem: %s | T=%s\n", toChars(), type->toChars()); @@ -51,13 +59,27 @@ DValue* DeclarationExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// +void VarExp::cacheLvalue(IRState* p) +{ + Logger::println("Caching l-value of %s", toChars()); + LOG_SCOPE; + cachedLvalue = toElem(p)->getLVal(); +} + DValue* VarExp::toElem(IRState* p) { - Logger::print("VarExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("VarExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(var); + if (cachedLvalue) + { + LLValue* V = cachedLvalue; + cachedLvalue = NULL; + return new DVarValue(type, V); + } + if (VarDeclaration* vd = var->isVarDeclaration()) { Logger::println("VarDeclaration ' %s ' of type ' %s '", vd->toChars(), vd->type->toChars()); @@ -204,7 +226,7 @@ DValue* VarExp::toElem(IRState* p) LLConstant* VarExp::toConstElem(IRState* p) { - Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("VarExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration()) @@ -244,7 +266,7 @@ LLConstant* VarExp::toConstElem(IRState* p) DValue* IntegerExp::toElem(IRState* p) { - Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("IntegerExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; LLConstant* c = toConstElem(p); return new DConstValue(type, c); @@ -254,7 +276,7 @@ DValue* IntegerExp::toElem(IRState* p) LLConstant* IntegerExp::toConstElem(IRState* p) { - Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("IntegerExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; const LLType* t = DtoType(type); if (isaPointer(t)) { @@ -274,7 +296,7 @@ LLConstant* IntegerExp::toConstElem(IRState* p) DValue* RealExp::toElem(IRState* p) { - Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("RealExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; LLConstant* c = toConstElem(p); return new DConstValue(type, c); @@ -284,7 +306,7 @@ DValue* RealExp::toElem(IRState* p) LLConstant* RealExp::toConstElem(IRState* p) { - Logger::print("RealExp::toConstElem: %s | %s | %LX\n", toChars(), type->toChars(), value); + Logger::print("RealExp::toConstElem: %s @ %s | %LX\n", toChars(), type->toChars(), value); LOG_SCOPE; Type* t = type->toBasetype(); return DtoConstFP(t, value); @@ -322,7 +344,7 @@ LLConstant* NullExp::toConstElem(IRState* p) DValue* ComplexExp::toElem(IRState* p) { - Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); + Logger::print("ComplexExp::toElem(): %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; LLConstant* c = toConstElem(p); LLValue* res; @@ -350,7 +372,7 @@ DValue* ComplexExp::toElem(IRState* p) LLConstant* ComplexExp::toConstElem(IRState* p) { - Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars()); + Logger::print("ComplexExp::toConstElem(): %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; return DtoConstComplex(type, value.re, value.im); } @@ -359,7 +381,7 @@ LLConstant* ComplexExp::toConstElem(IRState* p) DValue* StringExp::toElem(IRState* p) { - Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("StringExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; Type* dtype = type->toBasetype(); @@ -426,7 +448,7 @@ DValue* StringExp::toElem(IRState* p) LLConstant* StringExp::toConstElem(IRState* p) { - Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("StringExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; Type* t = type->toBasetype(); @@ -524,9 +546,54 @@ DValue* AssignExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// +/// Finds the proper lvalue for a binassign expressions. +/// Makes sure the given LHS expression is only evaluated once. +static Expression* findLvalue(IRState* irs, Expression* exp) +{ + Expression* e = exp; + + // skip past any casts + while(e->op == TOKcast) + e = ((CastExp*)e)->e1; + + // cache lvalue and return + e->cacheLvalue(irs); + return e; +} + +#define BIN_ASSIGN(X) \ +DValue* X##AssignExp::toElem(IRState* p) \ +{ \ + Logger::print(#X"AssignExp::toElem: %s @ %s\n", toChars(), type->toChars()); \ + LOG_SCOPE; \ + X##Exp e3(loc, e1, e2); \ + e3.type = e1->type; \ + DValue* dst = findLvalue(p, e1)->toElem(p); \ + DValue* res = e3.toElem(p); \ + DValue* stval = DtoCast(loc, res, dst->getType()); \ + DtoAssign(loc, dst, stval); \ + return DtoCast(loc, res, type); \ +} + +BIN_ASSIGN(Add) +BIN_ASSIGN(Min) +BIN_ASSIGN(Mul) +BIN_ASSIGN(Div) +BIN_ASSIGN(Mod) +BIN_ASSIGN(And) +BIN_ASSIGN(Or) +BIN_ASSIGN(Xor) +BIN_ASSIGN(Shl) +BIN_ASSIGN(Shr) +BIN_ASSIGN(Ushr) + +#undef BIN_ASSIGN + +////////////////////////////////////////////////////////////////////////////////////////// + DValue* AddExp::toElem(IRState* p) { - Logger::print("AddExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("AddExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -565,40 +632,9 @@ DValue* AddExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* AddAssignExp::toElem(IRState* p) -{ - Logger::print("AddAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - - DValue* l = e1->toElem(p); - DValue* r = e2->toElem(p); - - Type* t = type->toBasetype(); - - DValue* res; - if (e1->type->toBasetype()->ty == Tpointer) { - LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); - res = new DImValue(type, gep); - } - else if (t->iscomplex()) { - res = DtoComplexAdd(loc, e1->type, l, r); - } - else { - res = DtoBinAdd(l,r); - } - DtoAssign(loc, l, res); - - if (res->getType() != type) - res = DtoCast(loc, res, type); - - return res; -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* MinExp::toElem(IRState* p) { - Logger::print("MinExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("MinExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -635,46 +671,9 @@ DValue* MinExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* MinAssignExp::toElem(IRState* p) -{ - Logger::print("MinAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - - DValue* l = e1->toElem(p); - DValue* r = e2->toElem(p); - - Type* t = type->toBasetype(); - - DValue* res; - if (e1->type->toBasetype()->ty == Tpointer) { - Logger::println("ptr"); - LLValue* tmp = r->getRVal(); - LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false); - tmp = llvm::BinaryOperator::CreateSub(zero,tmp,"tmp",p->scopebb()); - tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb()); - res = new DImValue(type, tmp); - } - else if (t->iscomplex()) { - Logger::println("complex"); - res = DtoComplexSub(loc, type, l, r); - } - else { - Logger::println("basic"); - res = DtoBinSub(l,r); - } - DtoAssign(loc, l, res); - - if (res->getType() != type) - res = DtoCast(loc, res, type); - - return res; -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* MulExp::toElem(IRState* p) { - Logger::print("MulExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("MulExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -689,34 +688,9 @@ DValue* MulExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* MulAssignExp::toElem(IRState* p) -{ - Logger::print("MulAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - - DValue* l = e1->toElem(p); - DValue* r = e2->toElem(p); - - DValue* res; - if (type->iscomplex()) { - res = DtoComplexMul(loc, type, l, r); - } - else { - res = DtoBinMul(l->getType(), l, r); - } - DtoAssign(loc, l, res); - - if (res->getType() != type) - res = DtoCast(loc, res, type); - - return res; -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* DivExp::toElem(IRState* p) { - Logger::print("DivExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("DivExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -731,34 +705,9 @@ DValue* DivExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DivAssignExp::toElem(IRState* p) -{ - Logger::print("DivAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - - DValue* l = e1->toElem(p); - DValue* r = e2->toElem(p); - - DValue* res; - if (type->iscomplex()) { - res = DtoComplexDiv(loc, type, l, r); - } - else { - res = DtoBinDiv(l->getType(), l, r); - } - DtoAssign(loc, l, res); - - if (res->getType() != type) - res = DtoCast(loc, res, type); - - return res; -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* ModExp::toElem(IRState* p) { - Logger::print("ModExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ModExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -769,28 +718,9 @@ DValue* ModExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* ModAssignExp::toElem(IRState* p) -{ - Logger::print("ModAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - - DValue* l = e1->toElem(p); - DValue* r = e2->toElem(p); - - DValue* res = DtoBinRem(l->getType(), l, r); - DtoAssign(loc, l, res); - - if (res->getType() != type) - res = DtoCast(loc, res, type); - - return res; -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* CallExp::toElem(IRState* p) { - Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CallExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // get the callee value @@ -833,7 +763,7 @@ DValue* CallExp::toElem(IRState* p) DValue* CastExp::toElem(IRState* p) { - Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CastExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // get the value to cast @@ -848,13 +778,7 @@ DValue* CastExp::toElem(IRState* p) if (!type->equals(to)) v = DtoPaintType(loc, v, type); - // slices are not valid lvalues - if (v->isSlice()) - return v; - // if we're casting a lvalue, keep it around, we might be in a lvalue cast. - else if(u->isLVal()) - return new DLRValue(u, v); - // otherwise just return the new value + // return the new rvalue return v; } @@ -862,7 +786,7 @@ DValue* CastExp::toElem(IRState* p) LLConstant* CastExp::toConstElem(IRState* p) { - Logger::print("CastExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CastExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; LLConstant* res; @@ -899,7 +823,7 @@ LLConstant* CastExp::toConstElem(IRState* p) DValue* SymOffExp::toElem(IRState* p) { - Logger::print("SymOffExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("SymOffExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(0 && "SymOffExp::toElem should no longer be called :/"); @@ -910,7 +834,7 @@ DValue* SymOffExp::toElem(IRState* p) DValue* AddrExp::toElem(IRState* p) { - Logger::println("AddrExp::toElem: %s | %s", toChars(), type->toChars()); + Logger::println("AddrExp::toElem: %s @ %s", toChars(), type->toChars()); LOG_SCOPE; DValue* v = e1->toElem(p); if (v->isField()) { @@ -1030,34 +954,62 @@ LLConstant* AddrExp::toConstElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// +void PtrExp::cacheLvalue(IRState* p) +{ + Logger::println("Caching l-value of %s", toChars()); + LOG_SCOPE; + cachedLvalue = e1->toElem(p)->getRVal(); +} + DValue* PtrExp::toElem(IRState* p) { - Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars()); + Logger::println("PtrExp::toElem: %s @ %s", toChars(), type->toChars()); LOG_SCOPE; - DValue* a = e1->toElem(p); + // function pointers are special + if (type->toBasetype()->ty == Tfunction) + { + assert(!cachedLvalue); + return new DImValue(type, e1->toElem(p)->getRVal()); + } - // this is *so* ugly.. I'd really like to figure out some way to avoid this badness... - LLValue* lv = a->getRVal(); - LLValue* v = lv; - - Type* bt = type->toBasetype(); - - // we can't load function pointers, but they aren't passed by reference either - // FIXME: maybe a MayLoad function isn't a bad idea after all ... - if (!DtoIsPassedByRef(bt) && bt->ty != Tfunction) - v = DtoLoad(v); - - return new DLRValue(new DVarValue(type, lv), new DImValue(type, v)); + // get the rvalue and return it as an lvalue + LLValue* V; + if (cachedLvalue) + { + V = cachedLvalue; + cachedLvalue = NULL; + } + else + { + V = e1->toElem(p)->getRVal(); + } + return new DVarValue(type, V); } ////////////////////////////////////////////////////////////////////////////////////////// +void DotVarExp::cacheLvalue(IRState* p) +{ + Logger::println("Caching l-value of %s", toChars()); + LOG_SCOPE; + cachedLvalue = toElem(p)->getLVal(); +} + DValue* DotVarExp::toElem(IRState* p) { - Logger::print("DotVarExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("DotVarExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; + if (cachedLvalue) + { + LLValue *V = cachedLvalue; + cachedLvalue = NULL; + VarDeclaration* vd = var->isVarDeclaration(); + assert(vd); + return new DVarValue(type, vd, V); + } + DValue* l = e1->toElem(p); Type* t = type->toBasetype(); @@ -1165,7 +1117,7 @@ DValue* DotVarExp::toElem(IRState* p) DValue* ThisExp::toElem(IRState* p) { - Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ThisExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // this seems to happen for dmd generated assert statements like: @@ -1198,11 +1150,25 @@ DValue* ThisExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// +void IndexExp::cacheLvalue(IRState* p) +{ + Logger::println("Caching l-value of %s", toChars()); + LOG_SCOPE; + cachedLvalue = toElem(p)->getLVal(); +} + DValue* IndexExp::toElem(IRState* p) { - Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("IndexExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; + if (cachedLvalue) + { + LLValue* V = cachedLvalue; + cachedLvalue = NULL; + return new DVarValue(type, V); + } + DValue* l = e1->toElem(p); Type* e1type = e1->type->toBasetype(); @@ -1243,7 +1209,7 @@ DValue* IndexExp::toElem(IRState* p) DValue* SliceExp::toElem(IRState* p) { - Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("SliceExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // this is the new slicing code, it's different in that a full slice will no longer retain the original pointer. @@ -1320,7 +1286,7 @@ DValue* SliceExp::toElem(IRState* p) DValue* CmpExp::toElem(IRState* p) { - Logger::print("CmpExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CmpExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -1439,7 +1405,7 @@ DValue* CmpExp::toElem(IRState* p) DValue* EqualExp::toElem(IRState* p) { - Logger::print("EqualExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("EqualExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -1530,7 +1496,7 @@ DValue* EqualExp::toElem(IRState* p) DValue* PostExp::toElem(IRState* p) { - Logger::print("PostExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("PostExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -1584,7 +1550,7 @@ DValue* PostExp::toElem(IRState* p) DValue* NewExp::toElem(IRState* p) { - Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("NewExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(newtype); @@ -1665,7 +1631,7 @@ DValue* NewExp::toElem(IRState* p) DValue* DeleteExp::toElem(IRState* p) { - Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("DeleteExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* dval = e1->toElem(p); @@ -1725,7 +1691,7 @@ DValue* DeleteExp::toElem(IRState* p) DValue* ArrayLengthExp::toElem(IRState* p) { - Logger::print("ArrayLengthExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ArrayLengthExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); @@ -1798,7 +1764,7 @@ DValue* AssertExp::toElem(IRState* p) DValue* NotExp::toElem(IRState* p) { - Logger::print("NotExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("NotExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); @@ -1815,7 +1781,7 @@ DValue* NotExp::toElem(IRState* p) DValue* AndAndExp::toElem(IRState* p) { - Logger::print("AndAndExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("AndAndExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // allocate a temporary for the final result. failed to come up with a better way :/ @@ -1853,7 +1819,7 @@ DValue* AndAndExp::toElem(IRState* p) DValue* OrOrExp::toElem(IRState* p) { - Logger::print("OrOrExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("OrOrExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // allocate a temporary for the final result. failed to come up with a better way :/ @@ -1891,25 +1857,12 @@ DValue* OrOrExp::toElem(IRState* p) #define BinBitExp(X,Y) \ DValue* X##Exp::toElem(IRState* p) \ { \ - Logger::print("%sExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ + Logger::print("%sExp::toElem: %s @ %s\n", #X, toChars(), type->toChars()); \ LOG_SCOPE; \ DValue* u = e1->toElem(p); \ DValue* v = e2->toElem(p); \ LLValue* x = llvm::BinaryOperator::Create(llvm::Instruction::Y, u->getRVal(), v->getRVal(), "tmp", p->scopebb()); \ return new DImValue(type, x); \ -} \ -\ -DValue* X##AssignExp::toElem(IRState* p) \ -{ \ - Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ - LOG_SCOPE; \ - DValue* u = e1->toElem(p); \ - DValue* v = e2->toElem(p); \ - LLValue* uval = u->getRVal(); \ - LLValue* vval = v->getRVal(); \ - LLValue* tmp = llvm::BinaryOperator::Create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ - DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \ - return u; \ } BinBitExp(And,And); @@ -1920,7 +1873,7 @@ BinBitExp(Ushr,LShr); DValue* ShrExp::toElem(IRState* p) { - Logger::print("ShrExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ShrExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); DValue* v = e2->toElem(p); @@ -1932,23 +1885,6 @@ DValue* ShrExp::toElem(IRState* p) return new DImValue(type, x); } -DValue* ShrAssignExp::toElem(IRState* p) -{ - Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - DValue* u = e1->toElem(p); - DValue* v = e2->toElem(p); - LLValue* uval = u->getRVal(); - LLValue* vval = v->getRVal(); - LLValue* tmp; - if (e1->type->isunsigned()) - tmp = p->ir->CreateLShr(uval, vval, "tmp"); - else - tmp = p->ir->CreateAShr(uval, vval, "tmp"); - DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); - return u; -} - ////////////////////////////////////////////////////////////////////////////////////////// DValue* HaltExp::toElem(IRState* p) @@ -1980,7 +1916,7 @@ DValue* HaltExp::toElem(IRState* p) DValue* DelegateExp::toElem(IRState* p) { - Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("DelegateExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; if(func->isStatic()) @@ -2041,7 +1977,7 @@ DValue* DelegateExp::toElem(IRState* p) DValue* IdentityExp::toElem(IRState* p) { - Logger::print("IdentityExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("IdentityExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); @@ -2101,7 +2037,7 @@ DValue* IdentityExp::toElem(IRState* p) DValue* CommaExp::toElem(IRState* p) { - Logger::print("CommaExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CommaExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); @@ -2114,7 +2050,7 @@ DValue* CommaExp::toElem(IRState* p) DValue* CondExp::toElem(IRState* p) { - Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CondExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; Type* dtype = type->toBasetype(); @@ -2159,7 +2095,7 @@ DValue* CondExp::toElem(IRState* p) DValue* ComExp::toElem(IRState* p) { - Logger::print("ComExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ComExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* u = e1->toElem(p); @@ -2175,7 +2111,7 @@ DValue* ComExp::toElem(IRState* p) DValue* NegExp::toElem(IRState* p) { - Logger::print("NegExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("NegExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -2194,7 +2130,7 @@ DValue* NegExp::toElem(IRState* p) DValue* CatExp::toElem(IRState* p) { - Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CatExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; Type* t = type->toBasetype(); @@ -2218,7 +2154,7 @@ DValue* CatExp::toElem(IRState* p) DValue* CatAssignExp::toElem(IRState* p) { - Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("CatAssignExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* l = e1->toElem(p); @@ -2245,7 +2181,7 @@ DValue* CatAssignExp::toElem(IRState* p) DValue* FuncExp::toElem(IRState* p) { - Logger::print("FuncExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("FuncExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(fd); @@ -2284,7 +2220,7 @@ DValue* FuncExp::toElem(IRState* p) LLConstant* FuncExp::toConstElem(IRState* p) { - Logger::print("FuncExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("FuncExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(fd); @@ -2300,7 +2236,7 @@ LLConstant* FuncExp::toConstElem(IRState* p) DValue* ArrayLiteralExp::toElem(IRState* p) { - Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ArrayLiteralExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // D types @@ -2369,7 +2305,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p) LLConstant* ArrayLiteralExp::toConstElem(IRState* p) { - Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("ArrayLiteralExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // extract D types @@ -2409,7 +2345,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) DValue* StructLiteralExp::toElem(IRState* p) { - Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("StructLiteralExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // get inits @@ -2467,7 +2403,7 @@ DValue* StructLiteralExp::toElem(IRState* p) LLConstant* StructLiteralExp::toConstElem(IRState* p) { - Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("StructLiteralExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; // get inits @@ -2496,7 +2432,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) DValue* InExp::toElem(IRState* p) { - Logger::print("InExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("InExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; DValue* key = e1->toElem(p); @@ -2522,7 +2458,7 @@ DValue* RemoveExp::toElem(IRState* p) DValue* AssocArrayLiteralExp::toElem(IRState* p) { - Logger::print("AssocArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); + Logger::print("AssocArrayLiteralExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; assert(keys); diff --git a/runtime/internal/memory.d b/runtime/internal/memory.d index acf74ad5..6a88ee37 100644 --- a/runtime/internal/memory.d +++ b/runtime/internal/memory.d @@ -68,12 +68,9 @@ private import tango.stdc.posix.dlfcn; } } - version(LDC) + pragma(intrinsic, "llvm.frameaddress") { - pragma(intrinsic, "llvm.frameaddress") - { - void* llvm_frameaddress(uint level=0); - } + void* llvm_frameaddress(uint level=0); } } @@ -147,11 +144,7 @@ extern (C) void* rt_stackBottom() */ extern (C) void* rt_stackTop() { - version(LDC) - { - return llvm_frameaddress(); - } - else version( D_InlineAsm_X86 ) + version( D_InlineAsm_X86 ) { asm { @@ -162,7 +155,7 @@ extern (C) void* rt_stackTop() } else { - static assert( false, "Architecture not supported." ); + return llvm_frameaddress(); } }