1 module epsilon.soag.optimizer; 2 3 import EAG = epsilon.eag; 4 import runtime; 5 import ALists = epsilon.soag.alists; 6 import SOAG = epsilon.soag.soag; 7 import Protocol = epsilon.soag.protocol; 8 import VisitSeq = epsilon.soag.visitseq; 9 import std.stdio; 10 11 const firstGlobalVar = 1; 12 const firstStackVar = 1; 13 int GlobalVar; 14 int StackVar; 15 int[] PN; 16 bool admissible; 17 bool disjoint; 18 ALists.AList VDS; 19 ALists.AList VS; 20 21 /** 22 * IN: Tripel 23 * OUT: - 24 * SEM: bed. Einfügen des Tripels in die modulglobale Liste VDS, die als Menge interpretiert wird, 25 * deshalb wird das Tripel nur dann eingefügt, wenn es nicht schon Bestandteil der Liste ist. 26 */ 27 void IncludeVDS(int S, int VN1, int VN2) nothrow @safe 28 { 29 int i = ALists.firstIndex; 30 bool notisElement = true; 31 32 while (i < VDS.Last && notisElement) 33 { 34 notisElement = VDS.Elem[i] != S || VDS.Elem[i + 1] != VN1 || VDS.Elem[i + 2] != VN2; 35 i += 3; 36 } 37 if (notisElement) 38 { 39 ALists.Append(VDS, S); 40 ALists.Append(VDS, VN1); 41 ALists.Append(VDS, VN2); 42 } 43 } 44 45 void WriteVDS() 46 { 47 stdout.writeln("Inhalt VDS:"); 48 for (size_t i = ALists.firstIndex; i <= VDS.Last; i += 3) 49 stdout.writeln(EAG.HNontRepr(VDS.Elem[i]), ", ", VDS.Elem[i + 1], ", ", VDS.Elem[i + 2]); 50 stdout.writeln; 51 } 52 53 /** 54 * IN: Tupel 55 * OUT: - 56 * SEM: bed. Einfügen des Tupels in die modulglobale Liste VS, die als Menge interpretiert wird, 57 * deshalb wird das Tupel nur dann eingefügt, wenn es nicht schon Bestandteil der Liste ist. 58 */ 59 void IncludeVS(int S, int VN) nothrow @safe 60 { 61 int i = ALists.firstIndex; 62 bool notisElement = true; 63 64 while (i < VS.Last && notisElement) 65 { 66 notisElement = VS.Elem[i] != S || VS.Elem[i + 1] != VN; 67 i += 2; 68 } 69 if (notisElement) 70 { 71 ALists.Append(VS, S); 72 ALists.Append(VS, VN); 73 } 74 } 75 76 void WriteVS() 77 { 78 stdout.writeln("Inhalt VS:"); 79 for (size_t i = ALists.firstIndex; i <= VS.Last; i += 2) 80 stdout.writeln(EAG.HNontRepr(VS.Elem[i]), ", ", VS.Elem[i + 1]); 81 stdout.writeln; 82 } 83 84 /** 85 * IN: Regel, Affixparameter 86 * OUT: Plannummer 87 * SEM: Ermittelt die Nummer des Visitplanes, während dessen Auswertung der Affixparameter berechnet wird 88 */ 89 int GetPlanNo(int R, int AP) @nogc nothrow @safe 90 { 91 const SO = SOAG.AffOcc[AP].SymOccInd; 92 93 if (SO == SOAG.Rule[R].SymOcc.Beg) 94 return VisitSeq.GetVisitNo(AP); 95 96 const VN = VisitSeq.GetVisitNo(AP); 97 98 return PN[VisitSeq.GetVisit(R, SO, VN)]; 99 } 100 101 /** 102 * IN: Regel, Affixparameter 103 * OUT: Position in der virtuellen extended visit sequence (EVS) 104 * SEM: Ermittelt der Position des Affixparameter in der EVS (entspricht set(a) aus der Theorie) 105 */ 106 int GetEVSPosforAffOcc(int R, int AP) @nogc nothrow @safe 107 { 108 int SO = SOAG.AffOcc[AP].SymOccInd; 109 int VN = VisitSeq.GetVisitNo(AP); 110 const S = SOAG.SymOcc[SO].SymInd; 111 const AN = SOAG.AffOcc[AP].AffOccNum.InSym; 112 int V; 113 114 if (SO == SOAG.Rule[R].SymOcc.Beg && SOAG.IsInherited(S, AN)) 115 { 116 if (VN == 1) 117 return 0; 118 V = VisitSeq.GetVisit(R, SO, VN - 1); 119 return V * 3 + 1; 120 } 121 V = VisitSeq.GetVisit(R, SO, VN); 122 return SOAG.IsInherited(S, AN) ? V * 3 + 1 : V * 3 + 3; 123 } 124 125 /** 126 * IN: Regel, Symbolvorkommen, Visit-Nummer 127 * OUT: Position in der virtuellen extended visit sequence (EVS) 128 * SEM: Ermittelt der Position des durch Symbolvorkommen und Visitnummer eindeutig gekennzeichneten Visits 129 * in der EVS (entspricht visit(j,m) aus der Theorie) 130 */ 131 int GetEVSPosforVisit(int R, int SO, int VN) @nogc nothrow @safe 132 { 133 const V = VisitSeq.GetVisit(R, SO, VN); 134 135 return V * 3 + 2; 136 } 137 138 /** 139 * SEM: Initialisierung der Struktur PN - Berechnung der Plannummer jedes Visits 140 */ 141 void Init() nothrow @safe 142 { 143 PN = new int[SOAG.NextVS]; 144 foreach (R; SOAG.firstRule .. SOAG.NextRule) 145 { 146 int PlanNo = 1; 147 148 foreach (V; SOAG.Rule[R].VS.Beg .. SOAG.Rule[R].VS.End + 1) 149 { 150 PN[V] = PlanNo; 151 if (cast(SOAG.Leave) SOAG.VS[V]) 152 ++PlanNo; 153 } 154 } 155 SOAG.StorageName = new int[SOAG.NextPartNum]; 156 SOAG.NextStorageName = SOAG.NextPartNum; 157 foreach (V; SOAG.firstStorageName .. SOAG.NextStorageName) 158 SOAG.StorageName[V] = 0; 159 ALists.New(VDS, 16); 160 ALists.New(VS, 16); 161 } 162 163 /** 164 * IN: Symbol, Affixpositionsnummer 165 * OUT: - 166 * SEM: Initialisierung der Mengen VDS und VS für eine Affixposition (analog Step 1 Theorie) 167 */ 168 void InitVDSandVS(size_t S, int A) nothrow 169 { 170 int SO; 171 int AP; 172 int PN; 173 int R; 174 int RS; 175 int AP1; 176 int PN1; 177 int AN; 178 int AN1; 179 180 ALists.Reset(VDS); 181 ALists.Reset(VS); 182 SO = SOAG.Sym[S].FirstOcc; 183 while (SO != SOAG.nil) 184 { 185 AP = SOAG.SymOcc[SO].AffOcc.Beg + A; 186 R = SOAG.SymOcc[SO].RuleInd; 187 if (SOAG.IsEvaluatorRule(R)) 188 { 189 PN = GetPlanNo(R, AP); 190 RS = SOAG.SymOcc[SOAG.Rule[R].SymOcc.Beg].SymInd; 191 IncludeVS(RS, PN); 192 for (AP1 = SOAG.Rule[R].AffOcc.Beg; AP1 <= SOAG.Rule[R].AffOcc.End; ++AP1) 193 { 194 AN1 = SOAG.AffOcc[AP1].AffOccNum.InRule; 195 AN = SOAG.AffOcc[AP].AffOccNum.InRule; 196 if (SOAG.Rule[R].DP[AN][AN1]) 197 { 198 PN1 = GetPlanNo(R, AP1); 199 if (PN < PN1) 200 IncludeVDS(RS, PN, PN1); 201 } 202 } 203 } 204 SO = SOAG.SymOcc[SO].Next; 205 } 206 } 207 208 /** 209 * SEM: Kompletiert die Initialisierung der Menge VDS (analog Step 2 der Theorie) 210 */ 211 void CompleteInitVDS() nothrow 212 { 213 int R; 214 int S; 215 int SO; 216 int VN1; 217 int VN2; 218 int V1; 219 int V2; 220 int RS; 221 int i = ALists.firstIndex; 222 223 while (i < VDS.Last) 224 { 225 S = VDS.Elem[i]; 226 ++i; 227 VN1 = VDS.Elem[i]; 228 ++i; 229 VN2 = VDS.Elem[i]; 230 ++i; 231 SO = SOAG.Sym[S].FirstOcc; 232 while (SO != SOAG.nil) 233 { 234 R = SOAG.SymOcc[SO].RuleInd; 235 if (SOAG.IsEvaluatorRule(R)) 236 { 237 if (SOAG.Rule[R].SymOcc.Beg != SO) 238 { 239 V1 = VisitSeq.GetVisit(R, SO, VN1); 240 V2 = VisitSeq.GetNextVisit(V1, R, SO, VN2); 241 if (PN[V1] < PN[V2]) 242 { 243 RS = SOAG.SymOcc[SOAG.Rule[SOAG.SymOcc[SO].RuleInd].SymOcc.Beg].SymInd; 244 IncludeVDS(RS, PN[V1], PN[V2]); 245 } 246 } 247 } 248 SO = SOAG.SymOcc[SO].Next; 249 } 250 } 251 } 252 253 /** 254 * IN: Symbol, Affixpos.Nr. 255 * OUT: - 256 * SEM: Test, ob Affixposition als Stack oder als globale Variable abgespeichert werden kann - 257 * nach Theorem 1 und 3 der Theorie 258 */ 259 void CheckStorageType(size_t S, int A) @nogc nothrow 260 { 261 int R; 262 int SO; 263 int AP1; 264 int AN1; 265 int VN1; 266 int AP2; 267 int AN2; 268 int VN2; 269 int S1; 270 int SO1; 271 int PN1; 272 int PN2; 273 274 /** 275 * IN: Symbol, Affixpos.Nr., aktuelle Regel, zwei Positionen der EVS 276 */ 277 void CheckT2P1andT1P1(size_t S, int A, int R, int PN1, int PN2) 278 { 279 int AP3; 280 int AN3; 281 int AP4; 282 int AN4; 283 int PN3; 284 int PN4; 285 int SO1 = SOAG.Sym[S].FirstOcc; 286 287 while (SO1 != SOAG.nil) 288 { 289 if (R == SOAG.SymOcc[SO1].RuleInd) 290 { 291 AP3 = SOAG.SymOcc[SO1].AffOcc.Beg + A; 292 AN3 = SOAG.AffOcc[AP3].AffOccNum.InRule; 293 PN3 = GetEVSPosforAffOcc(R, AP3); 294 if (PN1 < PN3 && PN3 < PN2) 295 disjoint = false; 296 for (AP4 = SOAG.Rule[R].AffOcc.Beg; AP4 <= SOAG.Rule[R].AffOcc.End; ++AP4) 297 { 298 AN4 = SOAG.AffOcc[AP4].AffOccNum.InRule; 299 if (SOAG.Rule[R].DP[AN3][AN4]) 300 { 301 PN4 = GetEVSPosforAffOcc(R, AP4); 302 if (PN1 < PN3 && PN3 < PN2 && PN2 <= PN4) 303 admissible = false; 304 } 305 } 306 } 307 SO1 = SOAG.SymOcc[SO1].Next; 308 } 309 } 310 311 /** 312 * IN: aktuelle Regel, zwei Positionen in der EVS 313 */ 314 void CheckT2P2(int R, int PN1, int PN2) 315 { 316 int S1; 317 int SO1; 318 int PN; 319 int VN; 320 321 for (size_t t = ALists.firstIndex; t <= VS.Last; t += 2) 322 { 323 S1 = VS.Elem[t]; 324 VN = VS.Elem[t + 1]; 325 SO1 = SOAG.Sym[S1].FirstOcc; 326 while (SO1 != SOAG.nil) 327 { 328 if (R == SOAG.SymOcc[SO1].RuleInd && SOAG.Rule[R].SymOcc.Beg != SO1) 329 { 330 PN = GetEVSPosforVisit(R, SO1, VN); 331 if (PN1 < PN && PN < PN2) 332 disjoint = false; 333 } 334 SO1 = SOAG.SymOcc[SO1].Next; 335 } 336 } 337 } 338 339 /** 340 * IN: aktuelle Regel, zwei Positionen in der EVS 341 */ 342 void CheckT1P2andP3(int R, int PN1, int PN2) 343 { 344 int S1; 345 int SO1; 346 int VN3; 347 int VN4; 348 int PN3; 349 int PN4; 350 351 for (int t = ALists.firstIndex; t <= VDS.Last; t += 3) 352 { 353 S1 = VDS.Elem[t]; 354 VN3 = VDS.Elem[t + 1]; 355 VN4 = VDS.Elem[t + 2]; 356 SO1 = SOAG.Sym[S1].FirstOcc; 357 while (SO1 != SOAG.nil) 358 { 359 if (R == SOAG.SymOcc[SO1].RuleInd && SOAG.Rule[R].SymOcc.Beg != SO1) 360 { 361 PN3 = GetEVSPosforVisit(R, SO1, VN3); 362 PN4 = GetEVSPosforVisit(R, SO1, VN4); 363 if (PN1 < PN3 && PN3 < PN2 && PN2 < PN4 || PN3 < PN1 && PN1 < PN4 && PN4 < PN2) 364 admissible = false; 365 } 366 SO1 = SOAG.SymOcc[SO1].Next; 367 } 368 } 369 } 370 371 /** 372 * IN: Affixpos.Nr., aktuelle Regel, zwei Position in der EVS 373 */ 374 void CheckT2P3(size_t S, int A, int R, int PN1, int PN2) 375 { 376 int SO2; 377 int AP1; 378 int PN3; 379 380 for (SO2 = SOAG.Rule[R].SymOcc.Beg; SO2 <= SOAG.Rule[R].SymOcc.End; ++SO2) 381 { 382 if (SOAG.SymOcc[SO2].SymInd == S) 383 { 384 AP1 = SOAG.SymOcc[SO2].AffOcc.Beg + A; 385 PN3 = GetEVSPosforAffOcc(R, AP1); 386 if (PN1 < PN3 && PN3 < PN2) 387 disjoint = false; 388 } 389 } 390 } 391 392 /** 393 * IN: aktuelle Regel, zwei Position in der EVS 394 */ 395 void CheckT2P4(int R, int SO, int PN1, int PN2) 396 { 397 int S2; 398 int SO2; 399 int VN3; 400 int PN3; 401 402 for (int t = ALists.firstIndex; t <= VS.Last; t += 2) 403 { 404 S2 = VS.Elem[t]; 405 VN3 = VS.Elem[t + 1]; 406 SO2 = SOAG.Sym[S2].FirstOcc; 407 while (SO2 != SOAG.nil) 408 { 409 if (R == SOAG.SymOcc[SO2].RuleInd && SOAG.Rule[R].SymOcc.Beg != SO2 && SO != SO2) 410 { 411 PN3 = GetEVSPosforVisit(R, SO2, VN3); 412 if (PN1 < PN3 && PN3 < PN2) 413 disjoint = false; 414 } 415 SO2 = SOAG.SymOcc[SO2].Next; 416 } 417 } 418 } 419 420 /** 421 * IN: aktuelle Regel, zwei Position in der EVS 422 */ 423 void CheckT1P4(int R, int SO, int PN1, int PN2) 424 { 425 int S2; 426 int SO2; 427 int VN3; 428 int VN4; 429 int PN3; 430 int PN4; 431 432 for (int t = ALists.firstIndex; t <= VDS.Last; t += 3) 433 { 434 S2 = VDS.Elem[t]; 435 VN3 = VDS.Elem[t + 1]; 436 VN4 = VDS.Elem[t + 2]; 437 SO2 = SOAG.Sym[S2].FirstOcc; 438 while (SO2 != SOAG.nil) 439 { 440 if (R == SOAG.SymOcc[SO2].RuleInd && SOAG.Rule[R].SymOcc.Beg != SO2 && SO != SO2) 441 { 442 PN3 = GetEVSPosforVisit(R, SO2, VN3); 443 PN4 = GetEVSPosforVisit(R, SO2, VN4); 444 if (PN1 < PN3 && PN3 < PN2 && PN2 < PN4) 445 admissible = false; 446 } 447 SO2 = SOAG.SymOcc[SO2].Next; 448 } 449 } 450 } 451 452 SO = SOAG.Sym[S].FirstOcc; 453 while (SO != SOAG.nil) 454 { 455 AP1 = SOAG.SymOcc[SO].AffOcc.Beg + A; 456 AN1 = SOAG.AffOcc[AP1].AffOccNum.InRule; 457 R = SOAG.SymOcc[SO].RuleInd; 458 if (SOAG.IsEvaluatorRule(R)) 459 { 460 PN1 = GetEVSPosforAffOcc(R, AP1); 461 for (AP2 = SOAG.Rule[R].AffOcc.Beg; AP2 <= SOAG.Rule[R].AffOcc.End; ++AP2) 462 { 463 AN2 = SOAG.AffOcc[AP2].AffOccNum.InRule; 464 if (SOAG.Rule[R].DP[AN1][AN2]) 465 { 466 PN2 = GetEVSPosforAffOcc(R, AP2); 467 CheckT2P1andT1P1(S, A, R, PN1, PN2); 468 CheckT2P2(R, PN1, PN2); 469 CheckT1P2andP3(R, PN1, PN2); 470 } 471 } 472 } 473 SO = SOAG.SymOcc[SO].Next; 474 } 475 for (int t = ALists.firstIndex; t <= VDS.Last; t += 3) 476 { 477 S1 = VDS.Elem[t]; 478 VN1 = VDS.Elem[t + 1]; 479 VN2 = VDS.Elem[t + 2]; 480 SO1 = SOAG.Sym[S1].FirstOcc; 481 while (SO1 != SOAG.nil) 482 { 483 R = SOAG.SymOcc[SO1].RuleInd; 484 if (SOAG.IsEvaluatorRule(R)) 485 { 486 if (SOAG.Rule[R].SymOcc.Beg != SO1) 487 { 488 PN1 = GetEVSPosforVisit(R, SO1, VN1); 489 PN2 = GetEVSPosforVisit(R, SO1, VN2); 490 CheckT2P3(S, A, R, PN1, PN2); 491 CheckT2P4(R, SO1, PN1, PN2); 492 CheckT1P4(R, SO1, PN1, PN2); 493 } 494 } 495 SO1 = SOAG.SymOcc[SO1].Next; 496 } 497 } 498 } 499 500 void Optimize() nothrow 501 { 502 Init; 503 GlobalVar = firstGlobalVar - 1; 504 StackVar = firstStackVar - 1; 505 foreach (S; EAG.All.bitsSet) 506 { 507 for (int AP = SOAG.Sym[S].AffPos.Beg; AP <= SOAG.Sym[S].AffPos.End; ++AP) 508 { 509 const A = AP - SOAG.Sym[S].AffPos.Beg; 510 511 if (!EAG.Pred[S] || SOAG.IsSynthesized(S, A)) 512 { 513 disjoint = true; 514 admissible = true; 515 InitVDSandVS(S, A); 516 CompleteInitVDS; 517 CheckStorageType(S, A); 518 if (disjoint) 519 { 520 ++GlobalVar; 521 SOAG.StorageName[AP] = -GlobalVar; 522 } 523 else if (admissible) 524 { 525 ++StackVar; 526 SOAG.StorageName[AP] = StackVar; 527 } 528 } 529 } 530 } 531 }