Changeset 144

Show
Ignore:
Timestamp:
11/21/07 02:11:00 (9 months ago)
Author:
Don Clugston
Message:

First refactoring to take advantage of static foreach.

Files:

Legend:

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

    r143 r144  
    4747public import blade.SyntaxTree : AbstractSyntaxTree, syntaxtreeof, AST, Symbol; 
    4848private import blade.BladeUtil : enquote; 
    49 private import blade.BladeRank; 
    5049private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression; 
    51 public import blade.CodegenX86 : generateCodeForAsmX87, generateCodeForSSE, MAX_X87_VECTORS, MAX_SSE_VECTORS; 
     50public import blade.CodegenX86 : generateCodeForAsmX87, MAX_X87_VECTORS, 
     51                                 generateCodeForSSE,  MAX_SSE_VECTORS; 
    5252 
    5353public: 
     
    8080} 
    8181 
     82 
    8283// These functions have the complete expression encoded in the template type. 
    8384// One of these functions is instantiated for each expression. 
     
    9091 */ 
    9192void SSEVECGEN(int SSEVersion, char [] expr, Values...)(int veclength, Values values) { 
    92     const ranklist = TupleRank!(Values); 
    9393    debug(BladeBackEnd) { 
    94        pragma(msg, generateCodeForSSE(SSEVersion, ranklist, expr)); 
    95     } 
    96     mixin(generateCodeForSSE(SSEVersion, ranklist, expr)); 
    97 
     94       pragma(msg, generateCodeForSSE!(Values)(SSEVersion, expr)); 
     95    } 
     96    mixin(generateCodeForSSE!(Values)(SSEVersion, expr)); 
     97
    9898 
    9999/** Function to implement BLAS1 operations using X87 assembler. 
    100100 * Every member of the Values tuple must only be real, float[], double [], or real[]. 
    101101 */ 
    102 void X87VECGEN(char [] rawexpr, Values...)(int veclength, Values values) { 
    103     const typelist = elementTupleToString!(Values); 
    104     const ranklist = TupleRank!(Values); 
    105     const char [] expr = rawexpr; 
     102void X87VECGEN(char [] expr, Values...)(int veclength, Values values) { 
    106103    debug(BladeBackEnd) {     
    107         pragma(msg, generateCodeForAsmX87(typelist, ranklist, expr)); 
    108     } 
    109     mixin(generateCodeForAsmX87(typelist, ranklist, expr)); 
     104        pragma(msg, generateCodeForAsmX87!(Values)(expr)); 
     105    } 
     106    mixin(generateCodeForAsmX87!(Values)(expr)); 
    110107} 
    111108 
     
    185182    char [] result = assertAllVectorLengthsEqual(tree, revised); 
    186183    result ~= `X87VECGEN!("` ~ enquote(revised.expression) ~ `"`; 
     184     
    187185    char [] vals; 
    188186     
     
    231229    char [] result = assertAllVectorLengthsEqual(tree, revised); 
    232230    result ~= assertAllVectorsAlign128(tree, revised); 
     231 
    233232        
    234233    result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ `,"` ~ enquote(revised.expression) ~ `"`; 
  • trunk/blade/BladeDemo.d

    r143 r144  
    3333     
    3434    mixin(vectorize(` a += (d[2..$-1]*2.01*a[2]-another[][1])["abc".length-3..$]`)); 
    35     mixin(vectorize(" a   -= 2.01*(        3.04+k)*r")); 
     35     
     36    mixin(vectorize(" a-= 2.01*(        3.04+k)*r")); 
    3637    mixin(vectorize("q+= q*2.01")); 
    3738    writefln("a=", a);     
  • trunk/blade/BladeRank.d

    r143 r144  
    77module blade.BladeRank; 
    88 
     9 
    910// ------------------------------------------------ 
    1011//   Dealing with linear algebra types 
     
    1516template Rank(T) { 
    1617    // If it can be indexed, it's a vector 
    17     static if (is(typeof(T[0]))) const int Rank = 1 + Rank!(typeof(T[0])); 
    18     else const int Rank = 0
     18    static if (is(typeof(T[0]))) const char Rank = 1 + Rank!(typeof(T[0])); 
     19    else const char Rank = '0'
    1920} 
    2021 
     
    4344/// Determine the rank of every item of the tuple T. 
    4445template TupleRank(T...) { 
    45     static if (T.length==1) const int[] TupleRank = [ Rank!(T[0])]; 
    46     else const int[] TupleRank = Rank!(T[0]) ~ TupleRank!(T[1..$]); 
    47 
    48  
     46    static if (T.length==1) const char[] TupleRank = "" ~ Rank!(T[0]); 
     47    else const char[] TupleRank = Rank!(T[0]) ~ TupleRank!(T[1..$]); 
     48
     49 
     50/* 
    4951debug(UnitTest) { 
    5052private: 
     
    6971 
    7072} 
     73*/ 
    7174 
    7275 
     
    7578 
    7679// Count the number of vectors 
    77 int countVectors(int[] ranklist) 
     80int countVectors(char[] ranklist) 
    7881{ 
    7982    int numVecs=0; 
    8083    for (int i=0; i<ranklist.length; ++i) { 
    81         if (ranklist[i]==1) ++numVecs; 
     84        if (ranklist[i]=='1') ++numVecs; 
    8285    } 
    8386    return numVecs; 
    8487} 
    8588 
    86 int vectorNum(int [] ranklist, char var) 
     89int vectorNum(char [] ranklist, char var) 
    8790{ 
    8891    int numVecs=0; 
    8992    for (int i=0; i<var-'A'; ++i) { 
    90         if (ranklist[i]==1) ++numVecs; 
     93        if (ranklist[i]=='1') ++numVecs; 
    9194    } 
    9295    return numVecs; 
    9396} 
    9497 
    95 int scalarNum(int [] ranklist, char var) 
     98int scalarNum(char [] ranklist, char var) 
    9699{ 
    97100    int k=0; 
    98101    for (int i=0; i<var-'A'; ++i) { 
    99         if (ranklist[i]==0) ++k; 
     102        if (ranklist[i]=='0') ++k; 
    100103    } 
    101104    return k; 
    102105} 
    103106 
    104 int realScalarNum(char [][] typelist, int [] ranklist, char var) 
     107int realScalarNum(char [][] typelist, char [] ranklist, char var) 
    105108{ 
    106109    int k=0; 
    107110    for (int i=0; i<var-'A'; ++i) { 
    108         if (ranklist[i]==0 && typelist[i]=="real") ++k; 
     111        if (ranklist[i]=='0' && typelist[i]=="real") ++k; 
    109112    } 
    110113    return k; 
  • trunk/blade/CodegenX86.d

    r143 r144  
    5454/// Converts an infix string into postfix. 
    5555/// Apply x87-specific optimisations during the conversion. 
    56 char [] makePostfixForX87(char [] operations, char [][] typelist, int[] ranklist) 
     56char [] makePostfixForX87(char [] operations, char [][] typelist, char[] ranklist) 
    5757{ 
    5858    if (operations.length==1) return operations; 
     
    9393        // When an operation is performed between a real[] and a non-real[], 
    9494        // we want to have the real[] being the one which is loaded first. 
    95         if (second.length==1 && typelist[second[0]-'A']=="real" && ranklist[second[0]-'A']==1) { 
     95        if (second.length==1 && typelist[second[0]-'A']=="real" && ranklist[second[0]-'A']=='1') { 
    9696               return second ~ first ~ oprvs; 
    9797        } 
     
    102102 
    103103unittest { 
    104 assert(makePostfixForX87("A=B", elementTupleToString!(double, double),[1,1])=="BA="); 
    105 assert(makePostfixForX87("(B*C)+A", elementTupleToString!(double, float, float),[1,1,1])=="BC*A+"); 
    106 assert(makePostfixForX87("(B*C)+A", elementTupleToString!(real, float, float),[1,1,1])=="ABC*+"); 
    107 assert(makePostfixForX87("A-(B*C)", elementTupleToString!(double, float, float),[1,0,0])=="BC*A_"); 
    108 assert(makePostfixForX87("(B*C)-A", elementTupleToString!(float, float, float),[1,0,0])=="BC*A-"); 
    109 assert(makePostfixForX87("(B*C)-A", elementTupleToString!(real, float, float),[1,0,0])=="ABC*_"); 
    110 assert(makePostfixForX87("C+=((B*C)-A)", elementTupleToString!(real, float, float),[1,0,1])=="CABC*_+C="); 
    111 assert(makePostfixForX87("C-=((B*C)-A)", elementTupleToString!(real, float, float),[1,0,1])=="CABC*_-C="); 
    112 assert(makePostfixForX87("C-=(B*A)", elementTupleToString!(real, float, float),[1,0,1]) =="BA*C_C="); 
    113 assert(makePostfixForX87("C-=(B*A)", elementTupleToString!(real, float, real),[1,0,1]) =="BA*C_C="); 
    114 assert(makePostfixForX87("((A*B)+(C*D))+(E*F)", elementTupleToString!(int, int, int),[0,0,0])=="EF*AB*CD*++"); 
    115  
    116 
    117  
     104assert(makePostfixForX87("A=B", elementTupleToString!(double, double),"11")=="BA="); 
     105assert(makePostfixForX87("(B*C)+A", elementTupleToString!(double, float, float),"111")=="BC*A+"); 
     106assert(makePostfixForX87("(B*C)+A", elementTupleToString!(real, float, float),"111")=="ABC*+"); 
     107assert(makePostfixForX87("A-(B*C)", elementTupleToString!(double, float, float),"100")=="BC*A_"); 
     108assert(makePostfixForX87("(B*C)-A", elementTupleToString!(float, float, float),"100")=="BC*A-"); 
     109assert(makePostfixForX87("(B*C)-A", elementTupleToString!(real, float, float),"100")=="ABC*_"); 
     110assert(makePostfixForX87("C+=((B*C)-A)", elementTupleToString!(real, float, float),"101")=="CABC*_+C="); 
     111assert(makePostfixForX87("C-=((B*C)-A)", elementTupleToString!(real, float, float),"101")=="CABC*_-C="); 
     112assert(makePostfixForX87("C-=(B*A)", elementTupleToString!(real, float, float),"101") =="BA*C_C="); 
     113assert(makePostfixForX87("C-=(B*A)", elementTupleToString!(real, float, real),"101") =="BA*C_C="); 
     114assert(makePostfixForX87("((A*B)+(C*D))+(E*F)", elementTupleToString!(int, int, int),"000")=="EF*AB*CD*++"); 
     115 
     116
    118117 
    119118// num chars before we get a comma. 
     
    128127/// Converts an infix string into postfix. 
    129128/// Apply SSE/SSE2-specific optimisations during the conversion. 
    130 char [] makePostfixForSSE(char [] operations, int[] ranklist) 
     129char [] makePostfixForSSE(char [] operations, char [] ranklist) 
    131130{ 
    132131    if (operations.length==1) return operations; 
     
    164163        // When an operation is performed between a vector and a scalar 
    165164        // we want to have the vector being the one which is loaded first. 
    166         if (first.length==1 && ranklist[first[0]-'A']==0) { 
     165        if (first.length==1 && ranklist[first[0]-'A']=='0') { 
    167166               return second ~ first ~ op; 
    168167        } 
     
    171170    return first ~ second ~ op; 
    172171} 
     172 
     173private: 
    173174 
    174175unittest { 
     
    285286 
    286287// indexed by i. 
    287 char [] indexedVector(char [][] typelist, int [] ranklist, char var) 
     288char [] indexedVector(char [][] typelist, char [] ranklist, char var) 
    288289{ 
    289290    if (typelist[var-'A']=="real") return " real ptr [" ~ vectorRegister[vectorNum(ranklist, var)] ~ "]"; 
     
    293294 
    294295// indexed by i-1 
    295 char [] indexedVectorPrev(char [][] typelist, int [] ranklist, char var) 
     296char [] indexedVectorPrev(char [][] typelist, char [] ranklist, char var) 
    296297{ 
    297298    char [] stride = " - " ~ vectorSize(typelist[var-'A']); 
     
    301302} 
    302303 
    303 char [] indexedSSEVector(int [] ranklist, char var, char [] vecsize) 
     304char [] indexedSSEVector(char [] ranklist, char var, char [] vecsize) 
    304305{ 
    305306    return "[" ~ vectorRegister[vectorNum(ranklist, var)] ~ " + " ~ vecsize ~"*EAX]"; 
    306307} 
    307308 
    308 char [] indexedSSENext(int [] ranklist, char var, char [] vecsize) 
     309char [] indexedSSENext(char [] ranklist, char var, char [] vecsize) 
    309310{ 
    310311    return "[" ~ vectorRegister[vectorNum(ranklist, var)] ~ " + " ~ vecsize ~"*EAX+16]"; 
    311312} 
    312313 
    313 char [] indexedVectorWithStride(char [][] typelist, int [] ranklist, char var, int stride) 
     314char [] indexedVectorWithStride(char [][] typelist, char [] ranklist, char var, int stride) 
    314315{ 
    315316    char [] stridestr = " - " ~ vectorSize(typelist[var-'A']) ~ "*" ~ itoa(stride); 
     
    366367 
    367368*/ 
    368 char [] generateCodeForAsmX87(char [][] typelist, int [] ranklist, char [] infixOperations, char cumulatingOp=0) 
    369 
     369char [] generateCodeForAsmX87(Values...)(char [] infixOperations, char cumulatingOp=0) 
     370
     371    char [] ranklist; 
     372    char [][] typelist; 
     373    foreach(T; Values) { 
     374        static if (is(typeof(T[0]))) { 
     375            ranklist~="1";  
     376            typelist ~= typeof(T[0]).stringof; 
     377        } else  { 
     378            ranklist~="0"; 
     379            typelist ~= T.stringof; 
     380        } 
     381    } 
    370382    char [] operations = makePostfixForX87(infixOperations, typelist, ranklist); 
    371383    char [] result=""; 
     
    377389    int vecnum = 0; 
    378390    for (int i=0; i< ranklist.length;++i) { 
    379         if (ranklist[i]==1){ 
     391        if (ranklist[i]=='1'){ 
    380392            if (typelist[i]=="real") { 
    381393                incrementRealVectors ~= "  add " ~ vectorRegister[vecnum] ~ ", " ~ REALSIZE ~ ";\n"; 
     
    396408    int numconsts=0; 
    397409    for (int i=0; i<ranklist.length; ++i) { 
    398       if (ranklist[i]==1) { 
     410      if (ranklist[i]=='1') { 
    399411          if (typelist[i]=="real") { 
    400412              result ~= "  mov " ~ vectorRegister[numvecs] ~ ", values[" ~ itoa(i) ~ "];"; 
     
    449461            // load a vector onto the FPU stack, to begin a new subexpression. 
    450462            int u  = operations[done]-'A'; 
    451             if (ranklist[operations[done]-'A']==1) { 
     463            if (ranklist[operations[done]-'A']=='1') { 
    452464                next = "  fld "  ~ indexedVector(typelist, ranklist, operations[done] ) ~ ";  //" ~ operations[done] ~\n; 
    453465            } else { // load constant. Will never be a real 
     
    457469            ++done; 
    458470            numOnStack++; 
    459       } else if (ranklist[operations[done]-'A']==1) { 
     471      } else if (ranklist[operations[done]-'A']=='1') { 
    460472             // An operation will be performed between the stack top and a vector. 
    461473             // If it's a float or double, we can combine the load+arithmetic op 
     
    525537 * At entry, all vector parameters are aligned. 
    526538 */ 
    527 char [] generateCodeForSSE(int SSEVer, int [] ranklist, char [] infixOperations, char cumulatingOp=0) 
    528 
     539char [] generateCodeForSSE(Values...)(int SSEVer, char [] infixOperations, char cumulatingOp=0) 
     540
     541    char [] ranklist; 
     542    foreach(T; Values) { 
     543        static if (is(typeof(T[0]))) ranklist~="1"; else ranklist~="0"; 
     544    } 
    529545    char [] operations = makePostfixForSSE(infixOperations, ranklist); 
    530546    char [] result=""; 
     
    546562    int numconsts=0; 
    547563    for (int i=0; i<ranklist.length; ++i) { 
    548       if (ranklist[i]==1) { 
     564      if (ranklist[i]=='1') { 
    549565        result ~= "  lea " ~ vectorRegister[vecregnum] 
    550566          ~ ", [" ~ vectorsize ~ "*EAX];   " 
     
    591607            ++done; 
    592608            numOnStack++; 
    593       } else if (ranklist[operations[done]-'A']==1) { 
     609      } else if (ranklist[operations[done]-'A']=='1') { 
    594610             // An operation will be performed between the stack top and a vector. 
    595611            comment = ";  // " ~ operations[done..done+2] ~ \n;