@@ -419,22 +419,28 @@ class LocalVariableMap {
419
419
// The expression for this variable, OR
420
420
const Expr *Exp = nullptr ;
421
421
422
- // Reference to another VarDefinition
423
- unsigned Ref = 0 ;
422
+ // Direct reference to another VarDefinition
423
+ unsigned DirectRef = 0 ;
424
+
425
+ // Reference to underlying canonical non-reference VarDefinition.
426
+ unsigned CanonicalRef = 0 ;
424
427
425
428
// The map with which Exp should be interpreted.
426
429
Context Ctx;
427
430
428
431
bool isReference () const { return !Exp; }
429
432
433
+ void invalidateRef () { DirectRef = CanonicalRef = 0 ; }
434
+
430
435
private:
431
436
// Create ordinary variable definition
432
437
VarDefinition (const NamedDecl *D, const Expr *E, Context C)
433
438
: Dec(D), Exp(E), Ctx(C) {}
434
439
435
440
// Create reference to previous definition
436
- VarDefinition (const NamedDecl *D, unsigned R, Context C)
437
- : Dec(D), Ref(R), Ctx(C) {}
441
+ VarDefinition (const NamedDecl *D, unsigned DirectRef, unsigned CanonicalRef,
442
+ Context C)
443
+ : Dec(D), DirectRef(DirectRef), CanonicalRef(CanonicalRef), Ctx(C) {}
438
444
};
439
445
440
446
private:
@@ -445,7 +451,7 @@ class LocalVariableMap {
445
451
public:
446
452
LocalVariableMap () {
447
453
// index 0 is a placeholder for undefined variables (aka phi-nodes).
448
- VarDefinitions.push_back (VarDefinition (nullptr , 0u , getEmptyContext ()));
454
+ VarDefinitions.push_back (VarDefinition (nullptr , 0 , 0 , getEmptyContext ()));
449
455
}
450
456
451
457
// / Look up a definition, within the given context.
@@ -471,7 +477,7 @@ class LocalVariableMap {
471
477
Ctx = VarDefinitions[i].Ctx ;
472
478
return VarDefinitions[i].Exp ;
473
479
}
474
- i = VarDefinitions[i].Ref ;
480
+ i = VarDefinitions[i].DirectRef ;
475
481
}
476
482
return nullptr ;
477
483
}
@@ -508,7 +514,7 @@ class LocalVariableMap {
508
514
void dump () {
509
515
for (unsigned i = 1 , e = VarDefinitions.size (); i < e; ++i) {
510
516
const Expr *Exp = VarDefinitions[i].Exp ;
511
- unsigned Ref = VarDefinitions[i].Ref ;
517
+ unsigned Ref = VarDefinitions[i].DirectRef ;
512
518
513
519
dumpVarDefinitionName (i);
514
520
llvm::errs () << " = " ;
@@ -539,9 +545,9 @@ class LocalVariableMap {
539
545
friend class VarMapBuilder ;
540
546
541
547
// Resolve any definition ID down to its non-reference base ID.
542
- unsigned getCanonicalDefinitionID (unsigned ID) {
548
+ unsigned getCanonicalDefinitionID (unsigned ID) const {
543
549
while (ID > 0 && VarDefinitions[ID].isReference ())
544
- ID = VarDefinitions[ID].Ref ;
550
+ ID = VarDefinitions[ID].CanonicalRef ;
545
551
return ID;
546
552
}
547
553
@@ -564,10 +570,11 @@ class LocalVariableMap {
564
570
}
565
571
566
572
// Add a new reference to an existing definition.
567
- Context addReference (const NamedDecl *D, unsigned i , Context Ctx) {
573
+ Context addReference (const NamedDecl *D, unsigned Ref , Context Ctx) {
568
574
unsigned newID = VarDefinitions.size ();
569
575
Context NewCtx = ContextFactory.add (Ctx, D, newID);
570
- VarDefinitions.push_back (VarDefinition (D, i, Ctx));
576
+ VarDefinitions.push_back (
577
+ VarDefinition (D, Ref, getCanonicalDefinitionID (Ref), Ctx));
571
578
return NewCtx;
572
579
}
573
580
@@ -769,15 +776,14 @@ void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
769
776
const unsigned *I2 = C2.lookup (P.first );
770
777
if (!I2) {
771
778
// Variable does not exist at the end of the loop, invalidate.
772
- VDef->Ref = 0 ;
779
+ VDef->invalidateRef () ;
773
780
continue ;
774
781
}
775
782
776
783
// Compare the canonical IDs. This correctly handles chains of references
777
784
// and determines if the variable is truly loop-invariant.
778
- if (getCanonicalDefinitionID (VDef->Ref ) != getCanonicalDefinitionID (*I2)) {
779
- VDef->Ref = 0 ; // Mark this variable as undefined
780
- }
785
+ if (VDef->CanonicalRef != getCanonicalDefinitionID (*I2))
786
+ VDef->invalidateRef (); // Mark this variable as undefined
781
787
}
782
788
}
783
789
0 commit comments