# HG changeset patch # User Tomas Lindquist Olsen # Date 1238212843 -3600 # Node ID 3cf0066e6fafd67f4b1de40e88bb37f965e91e8b # Parent 2a687353c84d218b0dbc83481349a0a00385e217 - Versioned Expresssion::toElem with #if IN_DMD/IN_LLVM. - Eliminated the DLRValue DValue. - Implemented proactive handling of l-value CastExpS. - Minor tweak in runtime memory.d . diff -r 2a687353c84d -r 3cf0066e6faf dmd/expression.c --- a/dmd/expression.c Fri Mar 27 23:24:47 2009 +0100 +++ b/dmd/expression.c Sat Mar 28 05:00:43 2009 +0100 @@ -887,6 +887,10 @@ this->op = op; this->size = size; type = NULL; + +#if IN_LLVM + cachedLvalue = NULL; +#endif } Expression *Expression::syntaxCopy() diff -r 2a687353c84d -r 3cf0066e6faf dmd/expression.h --- a/dmd/expression.h Fri Mar 27 23:24:47 2009 +0100 +++ b/dmd/expression.h Sat Mar 28 05:00:43 2009 +0100 @@ -46,10 +46,10 @@ 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 @@ #endif #if IN_LLVM +struct IRState; struct DValue; -typedef DValue elem; - -namespace llvm -{ +namespace llvm { class Constant; class ConstantInt; } @@ -160,13 +158,18 @@ 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 @@ void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); Expression *toLvalue(Scope *sc, Expression *e); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ int isBool(int result); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ #ifdef _DH OutBuffer hexp; #endif +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ 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 @@ MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); Expression *interpret(InterState *istate); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ unsigned charAt(size_t i); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ //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 @@ Expression *castTo(Scope *sc, Type *t); void scanForNestedRef(Scope *sc); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD dt_t **toDt(dt_t **pdt); #endif + +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; // Variable @@ -624,18 +671,21 @@ void checkEscape(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); +#if IN_DMD elem *toElem(IRState *irs); -#if IN_DMD 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 @@ 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 @@ 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 @@ 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 @@ Expression *op_overload(Scope *sc); +#if IN_DMD elem *toElemBin(IRState *irs, int op); +#endif }; struct BinAssignExp : BinExp @@ -836,7 +904,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ \ Identifier *opId(); /* For operator overloading */ \ \ - elem *toElem(IRState *irs); \ + ASSIGNEXP_TOELEM \ }; #define X(a) a @@ -1210,6 +1395,7 @@ #undef X #undef ASSIGNEXP +#undef ASSIGNEXP_TOELEM struct AddExp : BinExp { @@ -1225,7 +1411,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -r 2a687353c84d -r 3cf0066e6faf gen/complex.cpp --- a/gen/complex.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/complex.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -429,16 +429,7 @@ } 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 -r 2a687353c84d -r 3cf0066e6faf gen/dvalue.cpp --- a/gen/dvalue.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/dvalue.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -78,15 +78,3 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// - -Type*& DLRValue::getLType() -{ - if (DLRValue* lr = lvalue->isLRValue()) - { - return lr->getLType(); - } - else - { - return lvalue->getType(); - } -} diff -r 2a687353c84d -r 3cf0066e6faf gen/dvalue.h --- a/gen/dvalue.h Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/dvalue.h Sat Mar 28 05:00:43 2009 +0100 @@ -29,7 +29,6 @@ struct DFieldValue; struct DFuncValue; struct DSliceValue; -struct DLRValue; // base class for d-values struct DValue : Object @@ -48,7 +47,6 @@ 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 @@ 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 -r 2a687353c84d -r 3cf0066e6faf gen/functions.cpp --- a/gen/functions.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/functions.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -940,7 +940,7 @@ // 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 -r 2a687353c84d -r 3cf0066e6faf gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/llvmhelpers.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -472,15 +472,9 @@ 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 @@ 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* 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 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 -r 2a687353c84d -r 3cf0066e6faf gen/llvmhelpers.h --- a/gen/llvmhelpers.h Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/llvmhelpers.h Sat Mar 28 05:00:43 2009 +0100 @@ -52,27 +52,29 @@ // 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 @@ // 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 @@ // 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 -r 2a687353c84d -r 3cf0066e6faf gen/structs.cpp --- a/gen/structs.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/structs.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -487,6 +487,12 @@ 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 DtoDeclareStruct(StructDeclaration* sd) +static void DtoDeclareStruct(StructDeclaration* sd) { DtoResolveStruct(sd); @@ -603,7 +609,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -void DtoConstInitStruct(StructDeclaration* sd) +static void DtoConstInitStruct(StructDeclaration* sd) { DtoDeclareStruct(sd); @@ -654,7 +660,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -void DtoDefineStruct(StructDeclaration* sd) +static void DtoDefineStruct(StructDeclaration* sd) { DtoConstInitStruct(sd); diff -r 2a687353c84d -r 3cf0066e6faf gen/structs.h --- a/gen/structs.h Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/structs.h Sat Mar 28 05:00:43 2009 +0100 @@ -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 -r 2a687353c84d -r 3cf0066e6faf gen/toir.cpp --- a/gen/toir.cpp Fri Mar 27 23:24:47 2009 +0100 +++ b/gen/toir.cpp Sat Mar 28 05:00:43 2009 +0100 @@ -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 @@ ////////////////////////////////////////////////////////////////////////////////////////// +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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ ////////////////////////////////////////////////////////////////////////////////////////// +/// 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* 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* 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* 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* 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* 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* 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 @@ 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 @@ 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 @@ 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* 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 @@ ////////////////////////////////////////////////////////////////////////////////////////// +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); - - // 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)); + // function pointers are special + if (type->toBasetype()->ty == Tfunction) + { + assert(!cachedLvalue); + return new DImValue(type, e1->toElem(p)->getRVal()); + } + + // 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* 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 @@ ////////////////////////////////////////////////////////////////////////////////////////// +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* 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* 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* 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* 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* 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* 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* 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* 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* 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* 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 @@ #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 @@ 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 @@ 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* 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* 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* 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* 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* 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* 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* 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* 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* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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* 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 -r 2a687353c84d -r 3cf0066e6faf runtime/internal/memory.d --- a/runtime/internal/memory.d Fri Mar 27 23:24:47 2009 +0100 +++ b/runtime/internal/memory.d Sat Mar 28 05:00:43 2009 +0100 @@ -68,12 +68,9 @@ 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_stackTop() { - version(LDC) - { - return llvm_frameaddress(); - } - else version( D_InlineAsm_X86 ) + version( D_InlineAsm_X86 ) { asm { @@ -162,7 +155,7 @@ } else { - static assert( false, "Architecture not supported." ); + return llvm_frameaddress(); } }