Fixed version of 122160 (the previous one would fold undefined symbols).
authorRafael Espindola <rafael.espindola@gmail.com>
Sun, 19 Dec 2010 04:18:56 +0000 (04:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sun, 19 Dec 2010 04:18:56 +0000 (04:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122167 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCExpr.cpp

index 94b9f0079a4adf86476ac9478c0381f7462f8681..879728f2fee82b1d107cd77e07b630dec9aa86df 100644 (file)
@@ -293,22 +293,55 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
 }
 
 /// \brief Helper method for \see EvaluateSymbolAdd().
-static void AttemptToFoldSymbolOffsetDifference(const MCAsmLayout *Layout,
+static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
+                                                const MCAsmLayout *Layout,
+                                                const SectionAddrMap *Addrs,
+                                                bool InSet,
                                                 const MCSymbolRefExpr *&A,
                                                 const MCSymbolRefExpr *&B,
                                                 int64_t &Addend) {
-  const MCAssembler &Asm = Layout->getAssembler();
+  if (!A || !B)
+    return;
+
+  const MCSymbol &SA = A->getSymbol();
+  const MCSymbol &SB = B->getSymbol();
+
+  if (SA.isUndefined() || SB.isUndefined())
+    return;
 
-  if (A && B &&
-      Asm.getWriter().IsSymbolRefDifferenceFullyResolved(Asm, A, B, false)) {
-    // Eagerly evaluate.
-    Addend += (Layout->getSymbolOffset(&Asm.getSymbolData(A->getSymbol())) -
-               Layout->getSymbolOffset(&Asm.getSymbolData(B->getSymbol())));
+  if (!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
+    return;
+
+  MCSymbolData &AD = Asm->getSymbolData(SA);
+  MCSymbolData &BD = Asm->getSymbolData(SB);
+
+  if (AD.getFragment() == BD.getFragment()) {
+    Addend += (AD.getOffset() - BD.getOffset());
 
     // Clear the symbol expr pointers to indicate we have folded these
     // operands.
     A = B = 0;
+    return;
   }
+
+  if (!Layout)
+    return;
+
+  const MCSectionData &SecA = *AD.getFragment()->getParent();
+  const MCSectionData &SecB = *BD.getFragment()->getParent();
+
+  if ((&SecA != &SecB) && !Addrs)
+    return;
+
+  // Eagerly evaluate.
+  Addend += (Layout->getSymbolOffset(&Asm->getSymbolData(A->getSymbol())) -
+             Layout->getSymbolOffset(&Asm->getSymbolData(B->getSymbol())));
+  if (Addrs && (&SecA != &SecB))
+    Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
+
+  // Clear the symbol expr pointers to indicate we have folded these
+  // operands.
+  A = B = 0;
 }
 
 /// \brief Evaluate the result of an add between (conceptually) two MCValues.
@@ -346,8 +379,11 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
   // Fold the result constant immediately.
   int64_t Result_Cst = LHS_Cst + RHS_Cst;
 
+  assert((!Layout || Asm) &&
+         "Must have an assembler object if layout is given!");
+
   // If we have a layout, we can fold resolved differences.
-  if (Layout) {
+  if (Asm) {
     // First, fold out any differences which are fully resolved. By
     // reassociating terms in
     //   Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
@@ -358,10 +394,14 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
     //   (RHS_A - RHS_B).
     // Since we are attempting to be as aggresive as possible about folding, we
     // attempt to evaluate each possible alternative.
-    AttemptToFoldSymbolOffsetDifference(Layout, LHS_A, LHS_B, Result_Cst);
-    AttemptToFoldSymbolOffsetDifference(Layout, LHS_A, RHS_B, Result_Cst);
-    AttemptToFoldSymbolOffsetDifference(Layout, RHS_A, LHS_B, Result_Cst);
-    AttemptToFoldSymbolOffsetDifference(Layout, RHS_A, RHS_B, Result_Cst);
+    AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B,
+                                        Result_Cst);
+    AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B,
+                                        Result_Cst);
+    AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B,
+                                        Result_Cst);
+    AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B,
+                                        Result_Cst);
   }
 
   // We can't represent the addition or subtraction of two symbols.
@@ -378,44 +418,6 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
   if (B && !A)
     return false;
 
-  // Absolutize symbol differences between defined symbols when we have a
-  // layout object and the target requests it.
-
-  assert((!Layout || Asm) &&
-         "Must have an assembler object if layout is given!");
-
-  if (Asm && A && B) {
-    if (A->getSymbol().isDefined() && B->getSymbol().isDefined() &&
-        Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B,
-                                                            InSet)) {
-      MCSymbolData &AD = Asm->getSymbolData(A->getSymbol());
-      MCSymbolData &BD = Asm->getSymbolData(B->getSymbol());
-
-      if (AD.getFragment() == BD.getFragment()) {
-        Res = MCValue::get(+ AD.getOffset()
-                           - BD.getOffset()
-                           + Result_Cst);
-        return true;
-      }
-
-      if (Layout) {
-        const MCSectionData &SecA = *AD.getFragment()->getParent();
-        const MCSectionData &SecB = *BD.getFragment()->getParent();
-        int64_t Val = + Layout->getSymbolOffset(&AD)
-                      - Layout->getSymbolOffset(&BD)
-                      + Result_Cst;
-        if (&SecA != &SecB) {
-          if (!Addrs)
-            return false;
-          Val += Addrs->lookup(&SecA);
-          Val -= Addrs->lookup(&SecB);
-        }
-        Res = MCValue::get(Val);
-        return true;
-      }
-    }
-  }
-
   Res = MCValue::get(A, B, Result_Cst);
   return true;
 }