Changeset 169

Show
Ignore:
Timestamp:
01/07/08 03:17:39 (8 months ago)
Author:
Don Clugston
Message:

* Improved treatment of intrinsic functions.
* Added sum() intrinsic to both front-end and back-end.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/blade/Blade.d

    r168 r169  
    551551         
    552552        if (comp[$-1]!=']') { // compound expression (not an indexed array) 
    553             if (comp[0]=='d') { 
     553            if (comp[0]>='a' && comp[0]<='z') { 
    554554                // dot product is a nested expression 
    555555                return invokeNestedExpression(comp, tree.symbolTable); 
  • trunk/blade/BladeDemo.d

    r168 r169  
    5757   mixin(vectorize("u = dot(q,q*dot(q,q))")); 
    5858   mixin(vectorize("u = dot(a, q)")); 
     59   mixin(vectorize("u = sum(a)")); 
    5960 
    6061    writefln("a=", a); 
  • trunk/blade/BladeRank.d

    r167 r169  
    123123    } 
    124124    ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 
    125         if (func=="d") { // dot product 
     125        if (func=="dot") { // dot product 
    126126            if (args.length!=2) return RankError.CommaExpected; 
    127127            auto lrank = doVisit(this_,args[0]); 
     
    131131            if (lrank!=1 || rrank!=1) return RankError.RankMismatchDotProduct;        
    132132            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); 
    135139        return 0; 
    136140    } 
     
    215219     
    216220    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);     
    221225     
    222226    assert(exprRank("A[B,B,B]", "60")==3); 
  • trunk/blade/BladeSimplify.d

    r168 r169  
    4848} 
    4949 
     50// TODO: ".re", ".im" should join this list. 
    5051bool isBladeIntrinsic(char [] str) 
    5152{ 
    52     return str=="dot" || str=="exp" || str=="sqrt"; 
    53 
     53    return str=="dot" || str=="sum"; 
     54
     55 
    5456 
    5557// Given an abstract syntax tree, returns a RevisedExpression. 
     
    8284/* Adjust the expression to remove all references to duplicated symbol table 
    8385 * 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
    8587*/ 
    8688char [] removeDuplicates(AbstractSyntaxTree tree) 
    8789{ 
    8890    int numdups=0; 
    89     char [] mapping = ""; 
     91    char [] mapping = ""; // The new letter which this symbol should become, 
     92                          // or '!' if it is an intrinsic 
    9093    for (int i=0; i<tree.symbolTable.length; ++i) { 
    9194        char c = 'A'+i; 
    92         if (tree.symbolTable[i].value=="dot") { 
     95        if (isBladeIntrinsic(tree.symbolTable[i].value)) { 
    9396            ++numdups; 
    94             c = 'd'; 
     97            c = '!'; 
    9598        } else { 
    9699            for (int j=0; j<i; ++j) { 
     
    108111    for (int i=0; i<tree.expression.length;++i) { 
    109112        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; 
    112117    } 
    113118    return e;     
     
    277282    } 
    278283    ReturnType onVisitFunction(This this_, char [] func, char [][] args) {         
    279         if (func=="d") { // dot product. 
     284        if (func=="dot") { // dot product. 
    280285            // Each element is reduced seperately 
    281286            char [] left = wrapInParens(doVisit(this_,args[0])); 
    282287            char [] right = wrapInParens(doVisit(this_, args[1])); 
    283288            return func ~ "(" ~ left ~ "," ~ right ~ ")"; 
     289        } else if (func=="sum") { 
     290            char [] left = wrapInParens(doVisit(this_,args[0])); 
     291            return func ~ "(" ~ left ~ ")"; 
    284292        } 
    285293        assert(0, "BLADE ICE: Unsupported function"); 
     
    393401                } else assert(0, "BLADE ICE"); 
    394402                if (isDotProduct) { 
    395                   return "d(" ~ first ~ "," ~ second ~ ")"; 
     403                  return "dot(" ~ first ~ "," ~ second ~ ")"; 
    396404                } 
    397405            } 
     
    420428    assert(foldIndices("A[,B..$,C]", "300")=="A[,B..$,C]"); 
    421429    // 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])))");     
    423431    assert(foldIndices("(A*B)[C..D,D]", "2200")=="(A[C..D,])*(B[D])"); 
    424432    assert(foldIndices("(A*B)[C..D]", "2200")=="(A[C..D,])*B"); 
    425433    assert(foldIndices("(A*B)[C..D]", "2100")=="(A[C..D,])*B"); 
    426434    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]))"); 
    428436     
    429437    assert(foldIndices("((A*B)*C)[D]", "2220")=="((A[D,])*B)*C"); 
    430438    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]))");  
    433441    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))))"); 
    435443} 
    436444 
     
    452460    } 
    453461    ReturnType onVisitFunction(This this_, char [] func, char [][] args) {         
    454         if (func=="d") { // dot product. 
     462        if (func=="dot") { // dot product. 
    455463            ScalarFold left = doVisit(this_,args[0]); 
    456464            ScalarFold right = doVisit(this_, args[1]); 
    457465            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) ~ ")}")); 
    458469        } else { 
    459470            assert(0, "BLADE: Unsupported function"); 
     
    574585unittest { 
    575586    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)})"); 
    577588    assert(foldScalars("A-(B*C)", "101")=="A+(C*{(-B)})"); 
    578589    assert(foldScalars("A-(B*(-C))", "101")=="A+(C*{(-(-B))})"); 
     
    581592    assert(foldScalars("(-A)-(-C)", "101")=="C-A"); 
    582593    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  
    3535        return visitor.onVisitSymbol(visitor, expr); 
    3636    } 
    37     if (expr.length>3 && (expr[0]>='a' && expr[1]<='z') && expr[1]=='(') { // function 
     37    if (expr.length>3 && (expr[0]>='a' && expr[0]<='z')) { // function 
    3838        char [][] args; 
    39         int x=2; 
     39        int z=1; 
     40        while(z<expr.length && expr[z]!='(') ++z; 
     41        int x = z+1; 
    4042        while (x<expr.length) { 
    4143            int y = exprLength(expr[x..$-1]); 
     
    4345            x = x+y+2; // skip the comma 
    4446        } 
    45         return visitor.onVisitFunction(visitor, expr[0..1], args); 
     47        return visitor.onVisitFunction(visitor, expr[0..z], args); 
    4648    } 
    4749    if (expr.length>2 && (expr[0..2]=="++" || expr[0..2]=="--")) { 
  • trunk/blade/CodegenX86.d

    r168 r169  
    4040* 
    4141*/ 
     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 */ 
    4248 
    4349module blade.CodegenX86; 
     
    482488} 
    483489 
     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 
    484495private: 
    485496// split off from the template to make code coverage work 
  • trunk/blade/PostfixX86.d

    r168 r169  
    4242    } 
    4343    ReturnType onVisitFunction(This this_, char [] func, char [][] args) { 
    44         if (func=="d") { 
     44        if (func=="dot") { 
    4545            return "0" ~ doVisit(this_,args[0]) ~ doVisit(this_, args[1]) ~ "*+"; 
    4646        } 
     
    118118    } 
    119119    ReturnType onVisitFunction(This this_, char [] func, char [][] args) {       
    120         if (func=="d") { 
     120        if (func=="dot") { 
    121121            return "0" ~ doVisit(this_,args[0]) ~ doVisit(this_, args[1]) ~ "*+"; 
    122122        } 
     123        if (func=="sum") return "0" ~ doVisit(this_, args[0]) ~ "+"; 
    123124        assert(0, "BLADE ICE: Unsupported"); 
    124125    }