@@ -419,22 +419,28 @@ class LocalVariableMap {
419419 // The expression for this variable, OR
420420 const Expr *Exp = nullptr ;
421421
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 ;
424427
425428 // The map with which Exp should be interpreted.
426429 Context Ctx;
427430
428431 bool isReference () const { return !Exp; }
429432
433+ void invalidateRef () { DirectRef = CanonicalRef = 0 ; }
434+
430435 private:
431436 // Create ordinary variable definition
432437 VarDefinition (const NamedDecl *D, const Expr *E, Context C)
433438 : Dec(D), Exp(E), Ctx(C) {}
434439
435440 // 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) {}
438444 };
439445
440446private:
@@ -445,7 +451,7 @@ class LocalVariableMap {
445451public:
446452 LocalVariableMap () {
447453 // 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 ()));
449455 }
450456
451457 // / Look up a definition, within the given context.
@@ -471,7 +477,7 @@ class LocalVariableMap {
471477 Ctx = VarDefinitions[i].Ctx ;
472478 return VarDefinitions[i].Exp ;
473479 }
474- i = VarDefinitions[i].Ref ;
480+ i = VarDefinitions[i].DirectRef ;
475481 }
476482 return nullptr ;
477483 }
@@ -508,7 +514,7 @@ class LocalVariableMap {
508514 void dump () {
509515 for (unsigned i = 1 , e = VarDefinitions.size (); i < e; ++i) {
510516 const Expr *Exp = VarDefinitions[i].Exp ;
511- unsigned Ref = VarDefinitions[i].Ref ;
517+ unsigned Ref = VarDefinitions[i].DirectRef ;
512518
513519 dumpVarDefinitionName (i);
514520 llvm::errs () << " = " ;
@@ -539,9 +545,9 @@ class LocalVariableMap {
539545 friend class VarMapBuilder ;
540546
541547 // Resolve any definition ID down to its non-reference base ID.
542- unsigned getCanonicalDefinitionID (unsigned ID) {
548+ unsigned getCanonicalDefinitionID (unsigned ID) const {
543549 while (ID > 0 && VarDefinitions[ID].isReference ())
544- ID = VarDefinitions[ID].Ref ;
550+ ID = VarDefinitions[ID].CanonicalRef ;
545551 return ID;
546552 }
547553
@@ -564,10 +570,11 @@ class LocalVariableMap {
564570 }
565571
566572 // 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) {
568574 unsigned newID = VarDefinitions.size ();
569575 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));
571578 return NewCtx;
572579 }
573580
@@ -769,15 +776,14 @@ void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
769776 const unsigned *I2 = C2.lookup (P.first );
770777 if (!I2) {
771778 // Variable does not exist at the end of the loop, invalidate.
772- VDef->Ref = 0 ;
779+ VDef->invalidateRef () ;
773780 continue ;
774781 }
775782
776783 // Compare the canonical IDs. This correctly handles chains of references
777784 // 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
781787 }
782788}
783789
0 commit comments