Changeset 152
- Timestamp:
- 11/30/07 11:42:59 (10 months ago)
- Files:
-
- trunk/blade/Blade.d (modified) (7 diffs)
- trunk/blade/BladeDemo.d (modified) (1 diff)
- trunk/blade/BladeRank.d (modified) (4 diffs)
- trunk/blade/BladeSimplify.d (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r147 r152 47 47 public import blade.SyntaxTree : AbstractSyntaxTree, syntaxtreeof, AST, Symbol; 48 48 private import blade.BladeUtil : enquote; 49 private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression ;49 private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression, isStrided; 50 50 public import blade.CodegenX86 : generateCodeForAsmX87, MAX_X87_VECTORS, 51 51 generateCodeForSSE, MAX_SSE_VECTORS; … … 126 126 bool SSE1 = true; 127 127 bool X87 = true; 128 bool strided = false; // true if any strided vector or matrix operations exist 128 129 version (D_InlineAsm_X86) {} else { 129 130 // Without an assembler, there's no chance! … … 139 140 ++numscalars; 140 141 // TODO: disallow asm if any non-int/not FP types are used. 141 continue; // BUG: assume wecan always do scalars142 continue; // BUG: assume asm can always do scalars 142 143 } 143 144 if (r>'1') return VecExpressionType.DExpression; // can only do scalars and vectors right now. 144 145 145 // At this point, all compounds are an original symbol + indexing/slicing. 146 146 int x = revised.mapping[i]-'A'; 147 147 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 } 149 156 150 157 char [] t = tree.symbolTable[y].element; … … 162 169 } 163 170 } 171 if (strided) return VecExpressionType.DExpression; 164 172 if (numvectors > MAX_X87_VECTORS) X87 = false; 165 173 if (numvectors > MAX_SSE_VECTORS) { SSE1=false; SSE2=false; } … … 305 313 int findVectorForLength(AbstractSyntaxTree tree, RevisedExpression revised) 306 314 { 307 int dynamic = 0; // last dynamic vector 315 int dynamic = -1; // last dynamic vector 316 int strided = 0; // last unstrided vector 308 317 for (int i = 0; i < revised.mapping.length; ++i) { 309 318 if (revised.rank[i]!='1') continue; 310 319 int x = revised.mapping[i]-'A'; 311 dynamic= i;320 strided = i; 312 321 if (x < tree.symbolTable.length) { 313 322 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; 317 334 318 335 } 319 336 320 char [] getValueForSymbol(char c, AbstractSyntaxTree tree, RevisedExpression revised) 321 { 337 char [] getValueForSymbol(char c, AbstractSyntaxTree tree, RevisedExpression revised, char [] firstIndexExpr="") 338 { 339 int numSlicesRemaining=1; 340 if (firstIndexExpr=="") numSlicesRemaining=0; 341 char [] v = ""; 322 342 // is it an original symbol? 323 343 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 ~ "]"; 331 426 } 332 427 return v; … … 337 432 char [] DCodeGenerator(AbstractSyntaxTree tree, RevisedExpression revised) 338 433 { 434 // assert(!strided, tree.expression ~ "Strided vectors are not yet supported"); 435 339 436 int lenvec = findVectorForLength(tree, revised); 340 437 char [] result = "for (int blade_index=0; blade_index<" … … 345 442 if (c>='A' && c<'Z') { 346 443 // restore all symbols into the expression 347 result ~= getValueForSymbol(c, tree, revised);444 // result ~= getValueForSymbol(c, tree, revised); 348 445 // If it's a vector, index it 349 446 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); 351 449 } else result ~= c; 352 450 } trunk/blade/BladeDemo.d
r151 r152 33 33 double [4][] another = [[33.1, 4543, 43, 878.7], [5.14, 455, 554, 2.43]]; 34 34 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 38 36 mixin(vectorize(` a += (d[2..$-1]*2.01*a[2]-another[][1])["abc".length-3..$]`)); 39 37 40 38 mixin(vectorize(" a-= 2.01*( 3.04+k)*r")); 41 39 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]")); 42 47 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. 44 49 // 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 47 53 writefln("a=", a); 48 54 } 55 trunk/blade/BladeRank.d
r151 r152 87 87 return rank[expr[0]-'A']-'0'; 88 88 } 89 assert(expr[0]=='(', "BLADE ICE:" ~ expr); 89 90 // strip off the parentheses 90 91 return exprRank(expr[1..$-1], rank); … … 196 197 if (rrank!=0) return RankError.NonScalarIndex; 197 198 return lrank - 1; 198 } else if (right[z+1]==','){199 } else { 199 200 int totrank = lrank; 200 201 do { … … 219 220 if (startrank!=0 || endrank!=0) return RankError.NonScalarSlice; 220 221 right = end; 221 // assert(0, start ~ "@" ~ end);222 // assert(0, right);223 222 } 224 223 … … 228 227 //assert(0, right[0..z+1]); 229 228 }while (true); 230 } else {231 // slicing -- does not change the rank232 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;242 229 } 243 230 } trunk/blade/BladeSimplify.d
r151 r152 249 249 } 250 250 251 public: 251 252 // return true if the given symbol has a non-zero stride. 252 253 // 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 // 254 256 bool isStrided(char [] s) 255 257 { … … 259 261 int paren = 0; 260 262 bool hasSliced=false; 263 bool maybeSlice = false; 261 264 bool startIndex=false; 262 265 for(int i=1; i<s.length; ++i) { … … 264 267 else if (s[i]==')') --paren; 265 268 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 } 268 273 if (paren==0 && s[i]=='[') { 269 274 startIndex = true; 275 maybeSlice = false; 270 276 numbrack++; 271 277 } 272 278 if (paren==0 && numbrack==1 && s[i]==',') { 273 279 if (hasSliced && startIndex) return true; 280 if (maybeSlice) hasSliced = true; 274 281 startIndex = true; 275 282 } … … 277 284 if (paren==0 && numbrack==1 && s[i]=='.' && s[i-1]=='.') { 278 285 startIndex = false; // [..] slices don't move the index to the next value. 286 maybeSlice = true; 279 287 } 280 288 } … … 282 290 } 283 291 292 private: 284 293 unittest { 285 294 assert(!isStrided("A[3..5][]")); 286 295 assert(!isStrided("A[2..7][3]")); 296 assert(!isStrided("A[][2]")); 297 assert(!isStrided("A[2,[2,7]]")); 287 298 assert(isStrided("A[[2,7],3]")); 288 assert( !isStrided("A[2,[2,7]]"));299 assert(isStrided("C[D..$,D]")); 289 300 assert(!isStrided("A[7][B[[1,3],2]..6]")); 290 301 }
