Changeset 152

Show
Ignore:
Timestamp:
11/30/07 11:42:59 (10 months ago)
Author:
Don Clugston
Message:

Support strided vector operations (D code only)

Files:

Legend:

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

    r147 r152  
    4747public import blade.SyntaxTree : AbstractSyntaxTree, syntaxtreeof, AST, Symbol; 
    4848private import blade.BladeUtil : enquote; 
    49 private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression
     49private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression, isStrided
    5050public import blade.CodegenX86 : generateCodeForAsmX87, MAX_X87_VECTORS, 
    5151                                 generateCodeForSSE,  MAX_SSE_VECTORS; 
     
    126126    bool SSE1 = true; 
    127127    bool X87 = true; 
     128    bool strided = false; // true if any strided vector or matrix operations exist     
    128129version (D_InlineAsm_X86) {} else { 
    129130    // Without an assembler, there's no chance! 
     
    139140            ++numscalars; 
    140141            // TODO: disallow asm if any non-int/not FP types are used. 
    141             continue; // BUG: assume we can always do scalars 
     142            continue; // BUG: assume asm can always do scalars 
    142143        } 
    143144        if (r>'1') return VecExpressionType.DExpression; // can only do scalars and vectors right now. 
    144         
    145145        // At this point, all compounds are an original symbol + indexing/slicing. 
    146146        int x = revised.mapping[i]-'A'; 
    147147        int y = x; // for compounds, get the original type 
    148         if (x>tree.symbolTable.length) y = revised.compounds[x-tree.symbolTable.length][0]-'A'; 
     148        if (x>=tree.symbolTable.length) { 
     149            y = revised.compounds[x-tree.symbolTable.length][0]-'A'; 
     150            // Check for a stride.. 
     151            if (revised.compounds[x-tree.symbolTable.length][$-1]==']') {                
     152//               assert(0,revised.compounds[x-tree.symbolTable.length]); 
     153                strided |= isStrided(revised.compounds[x-tree.symbolTable.length]); 
     154            } 
     155        } 
    149156         
    150157        char [] t = tree.symbolTable[y].element; 
     
    162169        } 
    163170    } 
     171    if (strided) return VecExpressionType.DExpression; 
    164172    if (numvectors > MAX_X87_VECTORS) X87 = false; 
    165173    if (numvectors > MAX_SSE_VECTORS) { SSE1=false; SSE2=false; } 
     
    305313int findVectorForLength(AbstractSyntaxTree tree, RevisedExpression revised) 
    306314{ 
    307     int dynamic = 0; // last dynamic vector 
     315    int dynamic = -1; // last dynamic vector 
     316    int strided = 0; // last unstrided vector 
    308317    for (int i = 0; i < revised.mapping.length; ++i) { 
    309318        if (revised.rank[i]!='1') continue; 
    310319        int x = revised.mapping[i]-'A'; 
    311         dynamic = i; 
     320        strided = i; 
    312321        if (x < tree.symbolTable.length) { 
    313322            if (arrayLengthIsStatic(tree.symbolTable[x].type)) return i; 
    314         } 
    315     } 
    316     return dynamic; 
     323            dynamic = i; 
     324        } else { 
     325            // Check for a stride. 
     326            if (revised.compounds[x-tree.symbolTable.length][$-1]==']') { 
     327                if (!isStrided(revised.compounds[x-tree.symbolTable.length])) { 
     328                    dynamic = i; 
     329                } 
     330            } 
     331        } 
     332    } 
     333    return dynamic>=0? dynamic : strided; 
    317334     
    318335} 
    319336 
    320 char [] getValueForSymbol(char c, AbstractSyntaxTree tree, RevisedExpression revised) 
    321 
     337char [] getValueForSymbol(char c, AbstractSyntaxTree tree, RevisedExpression revised, char [] firstIndexExpr="") 
     338
     339    int numSlicesRemaining=1; 
     340    if (firstIndexExpr=="") numSlicesRemaining=0; 
     341    char [] v = ""; 
    322342    // is it an original symbol? 
    323343    if (c-'A'<tree.symbolTable.length) { 
    324         return tree.symbolTable[c-'A'].value; 
    325     } 
    326     // else it's a compound 
    327     char [] v = ""; 
    328     foreach(d; revised.compounds[c-'A'-tree.symbolTable.length]) { 
    329         if (d>='A' && d<='Z') v ~= tree.symbolTable[d-'A'].value; 
    330         else v ~= d; 
     344        v = tree.symbolTable[c-'A'].value; 
     345    } 
     346    // else it's a compound or an indexed array 
     347    else if (revised.compounds[c-'A'-tree.symbolTable.length][$-1]==']') { 
     348        // indexed array, possibly involving slicing 
     349        int numbrack=0; 
     350        bool hasSliced=false; 
     351        // it's easier if we go backwards 
     352        // Replace the last slice [a..b] operation with [a+firstIndexExpr] 
     353        // or if no slices exist, append [firstIndexExpr] to the end. 
     354        int endk = revised.compounds[c-'A'-tree.symbolTable.length].length; 
     355        int numbracks = 0; 
     356        bool isSlice=false; 
     357        char [] newSlice; 
     358 
     359        for (int k = revised.compounds[c-'A'-tree.symbolTable.length].length-1;k>=1; --k) {             
     360            char d = revised.compounds[c-'A'-tree.symbolTable.length][k]; 
     361            if (d == ']') {  ++numbracks; } 
     362            if (d == '[') { --numbracks; } 
     363            
     364            if (d==']' && numbracks==1) { newSlice=""; endk = k;} 
     365            else if (d=='.' && numbracks==1) { isSlice=true;  
     366                if(numSlicesRemaining>0){ newSlice=""; endk=k;}  
     367                else newSlice = "." ~ newSlice; 
     368            } 
     369            else if (d=='[' && numbracks==0) { 
     370                if (isSlice && numSlicesRemaining>0) { 
     371                    v = "[" ~ newSlice //revised.compounds[c-'A'-tree.symbolTable.length][k+1..endk] 
     372                    ~ "+" ~ firstIndexExpr ~ "]" ~ v; 
     373                    --numSlicesRemaining; 
     374                } else { 
     375                    v = "[" ~ newSlice ~ "]" ~ v; //revised.compounds[c-'A'-tree.symbolTable.length][k+1..endk] ~ "]"; 
     376                } 
     377                newSlice=""; 
     378                isSlice=false; 
     379            } else if (d==',' && numbracks==1) { 
     380                if (isSlice && numSlicesRemaining>0) { 
     381                    v = "[" ~ newSlice //revised.compounds[c-'A'-tree.symbolTable.length][k+1..endk] 
     382                    ~ "+" ~ firstIndexExpr ~ "]" ~ v; 
     383                    --numSlicesRemaining; 
     384                } else { 
     385                    v = "[" ~ newSlice ~ "]" ~ v; 
     386                } 
     387                newSlice=""; 
     388                isSlice=false; 
     389            } else { 
     390                if (d>='A' && d<='Z') newSlice = tree.symbolTable[d-'A'].value ~ newSlice; 
     391                else newSlice = d ~newSlice; 
     392            } 
     393        } 
     394        for (; numSlicesRemaining>0; --numSlicesRemaining) { 
     395            v~="[" ~ firstIndexExpr ~ "]"; 
     396        } 
     397        return tree.symbolTable[revised.compounds[c-'A'-tree.symbolTable.length][0]-'A'].value ~ v; 
     398/*         
     399        foreach_reverse(d; revised.compounds[c-'A'-tree.symbolTable.length]) { 
     400            if (d>='A' && d<='Z') v = tree.symbolTable[d-'A'].value ~ v; 
     401            else if (d==',' && numbrack==1) { 
     402                if (!hasSliced)  v = "][" ~ v; 
     403                else assert(0, "sliced operations not yet supported"); 
     404            } if (!hasSliced && numbrack==0 && d=='.') { 
     405                if (prev == '.') { 
     406                    hasSliced=true; 
     407                    v = "+" ~ firstIndexExpr ~ v 
     408                } // else we'll drop the . 
     409            }else v = d ~ v; 
     410             
     411            if (d=='[') --numbrack; 
     412            if (d==']') ++numbrack; 
     413            prev = d; 
     414        } 
     415        if (firstIndexExpr!="")  return v ~ firstIndexExpr; 
     416        else return v; 
     417*/         
     418    } else { // compound expression 
     419        foreach(d; revised.compounds[c-'A'-tree.symbolTable.length]) { 
     420            if (d>='A' && d<='Z') v ~= tree.symbolTable[d-'A'].value; 
     421            else v ~= d; 
     422        } 
     423    } 
     424    for (; numSlicesRemaining>0; --numSlicesRemaining) { 
     425        v~="[" ~ firstIndexExpr ~ "]"; 
    331426    } 
    332427    return v; 
     
    337432char [] DCodeGenerator(AbstractSyntaxTree tree, RevisedExpression revised) 
    338433{ 
     434//        assert(!strided, tree.expression ~ "Strided vectors are not yet supported"); 
     435 
    339436    int lenvec = findVectorForLength(tree, revised); 
    340437    char [] result = "for (int blade_index=0; blade_index<"  
     
    345442        if (c>='A' && c<'Z') { 
    346443            // restore all symbols into the expression 
    347             result ~= getValueForSymbol(c, tree, revised); 
     444  //          result ~= getValueForSymbol(c, tree, revised); 
    348445            // If it's a vector, index it 
    349446            if (revised.rank[c-'A']=='1') 
    350                 result ~= "[blade_index]"; 
     447                result ~= getValueForSymbol(revised.mapping[c-'A'], tree, revised, "blade_index"); 
     448            else result ~= getValueForSymbol(revised.mapping[c-'A'], tree, revised); 
    351449        } else result ~= c; 
    352450    } 
  • trunk/blade/BladeDemo.d

    r151 r152  
    3333    double [4][] another = [[33.1, 4543, 43, 878.7], [5.14, 455, 554, 2.43]]; 
    3434    real k=3.4; 
    35     //mixin(vectorize("dot(q,q*dot(q,q))"));     
    36     // should simplify to: dot(q.q) * dot(q,q) 
    37     
     35 
    3836    mixin(vectorize(` a += (d[2..$-1]*2.01*a[2]-another[][1])["abc".length-3..$]`)); 
    3937     
    4038    mixin(vectorize(" a-= 2.01*(        3.04+k)*r")); 
    4139    mixin(vectorize("q+= q*2.01")); 
     40    // All of the next four are equivalent 
     41    mixin(vectorize("a+=6*another[1,0..$]")); 
     42    mixin(vectorize("a+=6*another[1][0..$]")); 
     43    mixin(vectorize("a+=6*another[1]")); 
     44    mixin(vectorize("a+=6*another[1][]")); 
     45     
     46    mixin(vectorize("a[0..2]+=6*another[0..$,1]")); 
    4247   
    43     // This parses OK, but isn't yet supported at the codegen step.   
     48    // Parses OK, but I don't think I'll support this. 
    4449//    mixin(vectorize("a+=6*another[1,[1,$]]")); 
    45     // This parses, but crashes at categorize. 
    46 //    mixin(vectorize("a+=6*another[1,1..$]")); 
     50 
     51    //mixin(vectorize("dot(q,q*dot(q,q))")); // should simplify to: dot(q.q) * dot(q,q) 
     52 
    4753    writefln("a=", a); 
    4854} 
     55 
  • trunk/blade/BladeRank.d

    r151 r152  
    8787        return rank[expr[0]-'A']-'0'; 
    8888    } 
     89    assert(expr[0]=='(', "BLADE ICE:" ~ expr); 
    8990    // strip off the parentheses 
    9091    return exprRank(expr[1..$-1], rank); 
     
    196197            if (rrank!=0) return RankError.NonScalarIndex; 
    197198            return lrank - 1; 
    198         } else if (right[z+1]==',')
     199        } else
    199200            int totrank = lrank; 
    200201            do { 
     
    219220                    if (startrank!=0 || endrank!=0) return RankError.NonScalarSlice; 
    220221                    right = end; 
    221 //                    assert(0, start ~ "@" ~ end); 
    222 //                    assert(0, right); 
    223222                } 
    224223                                 
     
    228227                //assert(0, right[0..z+1]); 
    229228            }while (true); 
    230         } else { 
    231             // slicing -- does not change the rank 
    232             if (!(z+3 < right.length && right[z+1..z+3]=="..")) 
    233                 return RankError.DotDotExpected; 
    234             char [] start = right[0..z+1];  
    235             char [] end = right[z+3..$]; 
    236             int startrank = subexprRank(start, rank); 
    237                 if (startrank<0) return startrank; 
    238             int endrank = subexprRank(end, rank); 
    239                 if (endrank<0) return endrank; 
    240             if (startrank!=0 || endrank!=0) return RankError.NonScalarSlice; 
    241             return lrank;             
    242229        } 
    243230    } 
  • trunk/blade/BladeSimplify.d

    r151 r152  
    249249} 
    250250 
     251public: 
    251252// return true if the given symbol has a non-zero stride. 
    252253// This happens whenever there is a slice (including a complete slice) 
    253 // on a non-final index. 
     254// where there is a later incomplete slice or index. 
     255// 
    254256bool isStrided(char [] s) 
    255257{ 
     
    259261   int paren = 0; 
    260262   bool hasSliced=false; 
     263   bool maybeSlice = false; 
    261264   bool startIndex=false; 
    262265   for(int i=1; i<s.length; ++i) { 
     
    264267        else if (s[i]==')') --paren; 
    265268        if (paren==0 && s[i]==']') { 
    266             if (hasSliced && startIndex) return true;             
    267             numbrack--; if (s[i-1]=='[') { hasSliced=true; startIndex=false; } } 
     269            if (startIndex && hasSliced) return true;    
     270            numbrack--; 
     271            if (s[i-1]=='[') { startIndex=false; }  
     272        } 
    268273        if (paren==0 && s[i]=='[') { 
    269274            startIndex = true; 
     275            maybeSlice = false; 
    270276            numbrack++; 
    271277        } 
    272278        if (paren==0 && numbrack==1 && s[i]==',') {            
    273279            if (hasSliced && startIndex) return true; 
     280            if (maybeSlice) hasSliced = true; 
    274281            startIndex = true; 
    275282        } 
     
    277284        if (paren==0 && numbrack==1 && s[i]=='.' && s[i-1]=='.') { 
    278285             startIndex = false; // [..] slices don't move the index to the next value. 
     286             maybeSlice = true; 
    279287        } 
    280288   } 
     
    282290} 
    283291 
     292private: 
    284293unittest { 
    285294    assert(!isStrided("A[3..5][]")); 
    286295    assert(!isStrided("A[2..7][3]")); 
     296    assert(!isStrided("A[][2]")); 
     297    assert(!isStrided("A[2,[2,7]]")); 
    287298    assert(isStrided("A[[2,7],3]")); 
    288     assert(!isStrided("A[2,[2,7]]")); 
     299    assert(isStrided("C[D..$,D]")); 
    289300    assert(!isStrided("A[7][B[[1,3],2]..6]")); 
    290301}