Changeset 169
- Timestamp:
- 01/07/08 03:17:39 (8 months ago)
- Files:
-
- trunk/blade/Blade.d (modified) (1 diff)
- trunk/blade/BladeDemo.d (modified) (1 diff)
- trunk/blade/BladeRank.d (modified) (3 diffs)
- trunk/blade/BladeSimplify.d (modified) (9 diffs)
- trunk/blade/BladeVisitor.d (modified) (2 diffs)
- trunk/blade/CodegenX86.d (modified) (2 diffs)
- trunk/blade/PostfixX86.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r168 r169 551 551 552 552 if (comp[$-1]!=']') { // compound expression (not an indexed array) 553 if (comp[0] =='d') {553 if (comp[0]>='a' && comp[0]<='z') { 554 554 // dot product is a nested expression 555 555 return invokeNestedExpression(comp, tree.symbolTable); trunk/blade/BladeDemo.d
r168 r169 57 57 mixin(vectorize("u = dot(q,q*dot(q,q))")); 58 58 mixin(vectorize("u = dot(a, q)")); 59 mixin(vectorize("u = sum(a)")); 59 60 60 61 writefln("a=", a); trunk/blade/BladeRank.d
r167 r169 123 123 } 124 124 ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 125 if (func=="d ") { // dot product125 if (func=="dot") { // dot product 126 126 if (args.length!=2) return RankError.CommaExpected; 127 127 auto lrank = doVisit(this_,args[0]); … … 131 131 if (lrank!=1 || rrank!=1) return RankError.RankMismatchDotProduct; 132 132 return 0; 133 } 134 assert(0, "BLADE ICE: Unsupported function"); 133 } else if (func=="sum") { 134 auto lrank = doVisit(this_,args[0]); 135 if (lrank<0) return lrank; // propagate errors 136 return 0; 137 } 138 assert(0, "BLADE ICE: Unsupported function:" ~ func); 135 139 return 0; 136 140 } … … 215 219 216 220 assert(exprRank("C+=(A[B])", "302")==2); 217 assert(exprRank("d (A)", "1")==RankError.CommaExpected);218 assert(exprRank("d (A,B)", "10")==RankError.RankMismatchDotProduct);219 220 assert(exprRank("d (B,(A*(d(B,B))))", "11")==0);221 assert(exprRank("dot(A)", "1")==RankError.CommaExpected); 222 assert(exprRank("dot(A,B)", "10")==RankError.RankMismatchDotProduct); 223 224 assert(exprRank("dot(B,(A*(dot(B,B))))", "11")==0); 221 225 222 226 assert(exprRank("A[B,B,B]", "60")==3); trunk/blade/BladeSimplify.d
r168 r169 48 48 } 49 49 50 // TODO: ".re", ".im" should join this list. 50 51 bool isBladeIntrinsic(char [] str) 51 52 { 52 return str=="dot" || str=="exp" || str=="sqrt"; 53 } 53 return str=="dot" || str=="sum"; 54 } 55 54 56 55 57 // Given an abstract syntax tree, returns a RevisedExpression. … … 82 84 /* Adjust the expression to remove all references to duplicated symbol table 83 85 * entries. (Duplicates can occur as a result of resolving aliases or constants). 84 * Also convert intrinsics to single-char codes.86 * Also move intrinsics in-line. 85 87 */ 86 88 char [] removeDuplicates(AbstractSyntaxTree tree) 87 89 { 88 90 int numdups=0; 89 char [] mapping = ""; 91 char [] mapping = ""; // The new letter which this symbol should become, 92 // or '!' if it is an intrinsic 90 93 for (int i=0; i<tree.symbolTable.length; ++i) { 91 94 char c = 'A'+i; 92 if ( tree.symbolTable[i].value=="dot") {95 if (isBladeIntrinsic(tree.symbolTable[i].value)) { 93 96 ++numdups; 94 c = ' d';97 c = '!'; 95 98 } else { 96 99 for (int j=0; j<i; ++j) { … … 108 111 for (int i=0; i<tree.expression.length;++i) { 109 112 char c = tree.expression[i]; 110 if (c>='A' && c<='Z') e~= mapping[c-'A']; 111 else e~=c; 113 if (c>='A' && c<='Z') { 114 if (mapping[c-'A']=='!') e~=tree.symbolTable[c-'A'].value; 115 else e~= mapping[c-'A']; 116 } else e~=c; 112 117 } 113 118 return e; … … 277 282 } 278 283 ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 279 if (func=="d ") { // dot product.284 if (func=="dot") { // dot product. 280 285 // Each element is reduced seperately 281 286 char [] left = wrapInParens(doVisit(this_,args[0])); 282 287 char [] right = wrapInParens(doVisit(this_, args[1])); 283 288 return func ~ "(" ~ left ~ "," ~ right ~ ")"; 289 } else if (func=="sum") { 290 char [] left = wrapInParens(doVisit(this_,args[0])); 291 return func ~ "(" ~ left ~ ")"; 284 292 } 285 293 assert(0, "BLADE ICE: Unsupported function"); … … 393 401 } else assert(0, "BLADE ICE"); 394 402 if (isDotProduct) { 395 return "d (" ~ first ~ "," ~ second ~ ")";403 return "dot(" ~ first ~ "," ~ second ~ ")"; 396 404 } 397 405 } … … 420 428 assert(foldIndices("A[,B..$,C]", "300")=="A[,B..$,C]"); 421 429 // Multidimensional slicing 422 assert(foldIndices("(C*((A*B)[C]))[D]", "2200")=="C*(d ((A[C,]),(B[D])))");430 assert(foldIndices("(C*((A*B)[C]))[D]", "2200")=="C*(dot((A[C,]),(B[D])))"); 423 431 assert(foldIndices("(A*B)[C..D,D]", "2200")=="(A[C..D,])*(B[D])"); 424 432 assert(foldIndices("(A*B)[C..D]", "2200")=="(A[C..D,])*B"); 425 433 assert(foldIndices("(A*B)[C..D]", "2100")=="(A[C..D,])*B"); 426 434 assert(foldIndices("(A*B)[C..D]", "1200")=="A*(B[C..D])"); 427 assert(foldIndices("(A*B)[C]", "120")=="d (A,(B[C]))");435 assert(foldIndices("(A*B)[C]", "120")=="dot(A,(B[C]))"); 428 436 429 437 assert(foldIndices("((A*B)*C)[D]", "2220")=="((A[D,])*B)*C"); 430 438 assert(foldIndices("((A+B)*C)[D]", "2220")=="((A[D,])+(B[D,]))*C"); 431 assert(foldIndices("((D*A)*B)[C]", "2100")=="d ((D*(A[C,])),B)");432 assert(foldIndices("(((A*B)*C)[D..E])[D]", "12200")=="d ((A*B),(C[D+D]))");439 assert(foldIndices("((D*A)*B)[C]", "2100")=="dot((D*(A[C,])),B)"); 440 assert(foldIndices("(((A*B)*C)[D..E])[D]", "12200")=="dot((A*B),(C[D+D]))"); 433 441 assert(foldIndices("A+=(((D[B])*C)[B])", "2004")=="A+=((D[B,B])*C)"); 434 assert(foldIndices("d (A,(A*d(A,A)))","1")=="d(A,(A*(d(A,A))))");442 assert(foldIndices("dot(A,(A*dot(A,A)))","1")=="dot(A,(A*(dot(A,A))))"); 435 443 } 436 444 … … 452 460 } 453 461 ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 454 if (func=="d ") { // dot product.462 if (func=="dot") { // dot product. 455 463 ScalarFold left = doVisit(this_,args[0]); 456 464 ScalarFold right = doVisit(this_, args[1]); 457 465 return ScalarFold("", combineMul(combineMul(left.multiplier, right.multiplier), "{" ~ func ~ "(" ~ wrapInParens(left.expr) ~ "," ~ wrapInParens(right.expr) ~ ")}")); 466 } else if (func=="sum") { 467 ScalarFold left = doVisit(this_,args[0]); 468 return ScalarFold("", combineMul(left.multiplier, "{" ~ func ~ "(" ~ wrapInParens(left.expr) ~ ")}")); 458 469 } else { 459 470 assert(0, "BLADE: Unsupported function"); … … 574 585 unittest { 575 586 assert(foldScalars("A*=(B*C)", "100")=="A*={(B*C)}"); 576 assert(foldScalars("d (A,(A*d(A,A)))", "1")=="({d(A,A)})*({d(A,A)})");587 assert(foldScalars("dot(A,(A*dot(A,A)))", "1")=="({dot(A,A)})*({dot(A,A)})"); 577 588 assert(foldScalars("A-(B*C)", "101")=="A+(C*{(-B)})"); 578 589 assert(foldScalars("A-(B*(-C))", "101")=="A+(C*{(-(-B))})"); … … 581 592 assert(foldScalars("(-A)-(-C)", "101")=="C-A"); 582 593 assert(foldScalars("A*=-(-B)", "10")=="A*={(-(-B))}"); 583 } 594 assert(foldScalars("sum((A*sum(A)))", "1")=="({sum(A)})*({sum(A)})"); 595 } trunk/blade/BladeVisitor.d
r167 r169 35 35 return visitor.onVisitSymbol(visitor, expr); 36 36 } 37 if (expr.length>3 && (expr[0]>='a' && expr[ 1]<='z') && expr[1]=='(') { // function37 if (expr.length>3 && (expr[0]>='a' && expr[0]<='z')) { // function 38 38 char [][] args; 39 int x=2; 39 int z=1; 40 while(z<expr.length && expr[z]!='(') ++z; 41 int x = z+1; 40 42 while (x<expr.length) { 41 43 int y = exprLength(expr[x..$-1]); … … 43 45 x = x+y+2; // skip the comma 44 46 } 45 return visitor.onVisitFunction(visitor, expr[0.. 1], args);47 return visitor.onVisitFunction(visitor, expr[0..z], args); 46 48 } 47 49 if (expr.length>2 && (expr[0..2]=="++" || expr[0..2]=="--")) { trunk/blade/CodegenX86.d
r168 r169 40 40 * 41 41 */ 42 43 /* 44 * POTENTIAL FROM RECENT INSTRUCTION SETS: 45 * SSE5(AMD): fmaddpd can dramatically improve both performance and accuracy. 46 * SSE4(Intel): dppd has limited use. 47 */ 42 48 43 49 module blade.CodegenX86; … … 482 488 } 483 489 490 // Note: If SSE4 is available, the dppd and dpps instructions could be 491 // used to replace the final *+ in dot-product operations. This would allow 492 // an in-order dot product to be performed, but doesn't give much speed 493 // improvement. 494 484 495 private: 485 496 // split off from the template to make code coverage work trunk/blade/PostfixX86.d
r168 r169 42 42 } 43 43 ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 44 if (func=="d ") {44 if (func=="dot") { 45 45 return "0" ~ doVisit(this_,args[0]) ~ doVisit(this_, args[1]) ~ "*+"; 46 46 } … … 118 118 } 119 119 ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 120 if (func=="d ") {120 if (func=="dot") { 121 121 return "0" ~ doVisit(this_,args[0]) ~ doVisit(this_, args[1]) ~ "*+"; 122 122 } 123 if (func=="sum") return "0" ~ doVisit(this_, args[0]) ~ "+"; 123 124 assert(0, "BLADE ICE: Unsupported"); 124 125 }
