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

Unified Diff: src/IceGlobalContext.cpp

Issue 1069453003: Subzero: Deterministically sort constant pool entries. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Don't use memcpy for FP comparisons due to host endian-ness differences Created 5 years, 8 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
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/elf_container.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceGlobalContext.cpp
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index c710edf53ff0cf7316fa83a282caedf33b4da759..1c9e3c4eccdd52e0905dac1279e35dced6cd0e20 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -64,6 +64,54 @@ struct KeyCompare<KeyType, typename std::enable_if<
}
};
+// Define a key comparison function for sorting the constant pool's
+// values after they are dumped to a vector. This covers integer
+// types, floating point types, and ConstantRelocatable values.
+template <typename ValueType, class Enable = void> struct KeyCompareLess {};
+
+template <typename ValueType>
+struct KeyCompareLess<ValueType,
+ typename std::enable_if<std::is_floating_point<
+ typename ValueType::PrimType>::value>::type> {
+ bool operator()(const Constant *Const1, const Constant *Const2) const {
+ typedef uint64_t CompareType;
+ static_assert(sizeof(typename ValueType::PrimType) <= sizeof(CompareType),
+ "Expected floating-point type of width 64-bit or less");
+ typename ValueType::PrimType V1 = llvm::cast<ValueType>(Const1)->getValue();
+ typename ValueType::PrimType V2 = llvm::cast<ValueType>(Const2)->getValue();
+ // We avoid "V1<V2" because of NaN.
+ // We avoid "memcmp(&V1,&V2,sizeof(V1))<0" which depends on the
+ // endian-ness of the host system running Subzero.
+ // Instead, compare the result of bit_cast to uint64_t.
+ uint64_t I1 = 0, I2 = 0;
+ memcpy(&I1, &V1, sizeof(V1));
+ memcpy(&I2, &V2, sizeof(V2));
+ return I1 < I2;
+ }
+};
+template <typename ValueType>
+struct KeyCompareLess<ValueType,
+ typename std::enable_if<std::is_integral<
+ typename ValueType::PrimType>::value>::type> {
+ bool operator()(const Constant *Const1, const Constant *Const2) const {
+ typename ValueType::PrimType V1 = llvm::cast<ValueType>(Const1)->getValue();
+ typename ValueType::PrimType V2 = llvm::cast<ValueType>(Const2)->getValue();
+ return V1 < V2;
+ }
+};
+template <typename ValueType>
+struct KeyCompareLess<
+ ValueType, typename std::enable_if<
+ std::is_same<ValueType, ConstantRelocatable>::value>::type> {
+ bool operator()(const Constant *Const1, const Constant *Const2) const {
+ auto V1 = llvm::cast<ValueType>(Const1);
+ auto V2 = llvm::cast<ValueType>(Const2);
+ if (V1->getName() == V2->getName())
+ return V1->getOffset() < V2->getOffset();
+ return V1->getName() < V2->getName();
+ }
+};
+
// TypePool maps constants of type KeyType (e.g. float) to pointers to
// type ValueType (e.g. ConstantFloat).
template <Type Ty, typename KeyType, typename ValueType> class TypePool {
@@ -85,6 +133,10 @@ public:
Constants.reserve(Pool.size());
for (auto &I : Pool)
Constants.push_back(I.second);
+ // The sort (and its KeyCompareLess machinery) is not strictly
+ // necessary, but is desirable for producing output that is
+ // deterministic across unordered_map::iterator implementations.
+ std::sort(Constants.begin(), Constants.end(), KeyCompareLess<ValueType>());
return Constants;
}
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/elf_container.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698