Chromium Code Reviews| Index: src/IceOperand.cpp |
| diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp |
| index f45d2279acb7cd0bccf87abb23bf18840ce4663c..55558f3f10ee934a1d5cf6895f0961d9826632e5 100644 |
| --- a/src/IceOperand.cpp |
| +++ b/src/IceOperand.cpp |
| @@ -13,6 +13,8 @@ |
| /// |
| //===----------------------------------------------------------------------===// |
| +#include <iostream> |
|
Jim Stichnoth
2016/02/02 17:13:44
System includes go at the end of the list.
John
2016/02/02 19:36:39
Done.
|
| + |
| #include "IceOperand.h" |
| #include "IceCfg.h" |
| @@ -24,7 +26,66 @@ |
| namespace Ice { |
| bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) { |
| - return A.Offset == B.Offset && A.Name == B.Name; |
| + // A and B are the same if: |
| + // (1) they have the same name; and |
| + // (2) they have the same offset. |
| + // |
| + // (1) is trivial to implement, but (2) requires some care. |
|
Jim Stichnoth
2016/02/02 17:13:44
I would s/implement/check/ .
John
2016/02/02 19:36:39
Done.
|
| + // |
| + // For (2): |
| + // if A and B have known offsets (i.e., no symbolic references), then |
| + // A == B -> A.Offset == B.Offset. |
| + // else each element i in A.OffsetExpr[i] must be the same (or have the same |
| + // value) than B.OffsetExpr[i]. |
|
Jim Stichnoth
2016/02/02 17:13:44
s/than/as/
John
2016/02/02 19:36:39
Done.
|
| + if (A.Name != B.Name) { |
| + return false; |
| + } |
| + |
| + bool BothHaveKnownOffsets = true; |
| + RelocOffsetT OffsetA = 0; |
| + RelocOffsetT OffsetB = 0; |
| + for (SizeT i = 0; i < A.OffsetExpr.size() && BothHaveKnownOffsets; ++i) { |
| + BothHaveKnownOffsets = A.OffsetExpr[i]->hasOffset(); |
| + if (BothHaveKnownOffsets) { |
| + OffsetA += A.OffsetExpr[i]->getOffset(); |
| + } |
| + } |
| + for (SizeT i = 0; i < B.OffsetExpr.size() && BothHaveKnownOffsets; ++i) { |
| + BothHaveKnownOffsets = B.OffsetExpr[i]->hasOffset(); |
| + if (BothHaveKnownOffsets) { |
| + OffsetB += B.OffsetExpr[i]->getOffset(); |
| + } |
| + } |
| + if (BothHaveKnownOffsets) { |
| + // Both have known offsets (i.e., no unresolved symbolic references), so |
| + // A == B -> A.Offset == B.Offset. |
| + return OffsetA == OffsetB; |
| + } |
| + |
| + // Otherwise, A and B are not the same if their OffsetExpr's have different |
| + // sizes. |
| + if (A.OffsetExpr.size() != B.OffsetExpr.size()) { |
| + return false; |
| + } |
| + |
| + // If the OffsetExprs' sizes are the same, then |
| + // for each i in OffsetExprSize: |
| + for (SizeT i = 0; i < A.OffsetExpr.size(); ++i) { |
| + const auto *const RelocOffsetA = A.OffsetExpr[i]; |
| + const auto *const RelocOffsetB = B.OffsetExpr[i]; |
| + if (RelocOffsetA->hasOffset() && RelocOffsetB->hasOffset()) { |
| + // A.OffsetExpr[i].Offset == B.OffsetExpr[i].Offset iff they are both |
| + // defined; |
| + if (RelocOffsetA->getOffset() != RelocOffsetB->getOffset()) { |
| + return false; |
| + } |
| + } else if (RelocOffsetA != RelocOffsetB) { |
| + // or, if they are undefined, then the RelocOffsets must be the same. |
| + return false; |
| + } |
| + } |
| + |
| + return true; |
| } |
| bool operator<(const RegWeight &A, const RegWeight &B) { |
| @@ -501,8 +562,13 @@ void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const { |
| } else { |
| Str << Name; |
| } |
| - if (Offset) |
| - Str << "+" << Offset; |
| + const RelocOffsetT Offset = getOffset(); |
| + if (Offset) { |
| + if (Offset >= 0) { |
| + Str << "+"; |
| + } |
| + Str << Offset; |
| + } |
| } |
| void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); } |