Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3209)

Unified Diff: src/IceOperand.cpp

Issue 1651163002: Subzero. Enables moar complex relocation offsets. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fixes Absolute Relocation Type for x86-64. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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); }
« src/IceOperand.h ('K') | « src/IceOperand.h ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698