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

Unified Diff: lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp

Issue 321733002: PNaCl SIMD: allow element-aligned vector load/store (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: s/,/./ Created 6 years, 6 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 | « lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp ('k') | lib/Transforms/NaCl/StripAttributes.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp
diff --git a/lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp b/lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp
index 6bb55ac5731f7076933e37d779d8dc84ebc2c883..8a15b8d88d309afdb748e5e87f23b1802c5e4310 100644
--- a/lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp
+++ b/lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp
@@ -7,15 +7,18 @@
//
//===----------------------------------------------------------------------===//
//
-// Replace all vector load/store instructions by loads/stores of each
-// individual element since different architectures have different
-// faults on unaligned memory access. This pass pessimizes all vector
-// memory accesses. It's expected that backends with more liberal
-// alignment restrictions recognize this pattern and reconstruct the
-// original vector load/store.
+// Fix vector load/store alignment by:
+// - Leaving as-is if the alignment is equal to the vector's element width.
+// - Reducing the alignment to vector's element width if it's greater and the
+// current alignment is a factor of the element alignment.
+// - Scalarizing if the alignment is smaller than the element-wise alignment.
//
-// Volatile load/store are broken up as allowed by C/C++, and atomic
-// accesses cause errors at compile-time.
+// Volatile vector load/store are handled the same, and can therefore be broken
+// up as allowed by C/C++.
+//
+// TODO(jfb) Atomic accesses cause errors at compile-time. This could be
+// implemented as a call to the C++ runtime, since 128-bit atomics
+// aren't usually lock-free.
//
//===----------------------------------------------------------------------===//
@@ -81,37 +84,65 @@ private:
return false;
}
- void findVectorLoadStore(const BasicBlock &BB, Instructions &Loads,
- Instructions &Stores) const;
- void fixVectorLoadStoreAlignment(BasicBlock &BB, const Instructions &Loads,
- const Instructions &Stores) const;
+ /// Vectors are expected to be element-aligned. If they are, leave as-is; if
+ /// the alignment is too much then narrow the alignment (when possible);
+ /// otherwise return false.
+ template <typename InstTy>
+ static bool tryFixVectorAlignment(const DataLayout *DL, Instruction *I) {
+ InstTy *LoadStore = cast<InstTy>(I);
+ VectorType *VecTy =
+ cast<VectorType>(pointerOperandType(LoadStore)->getElementType());
+ Type *ElemTy = VecTy->getElementType();
+ uint64_t ElemBitSize = DL->getTypeSizeInBits(ElemTy);
+ uint64_t ElemByteSize = ElemBitSize / CHAR_BIT;
+ uint64_t CurrentByteAlign = LoadStore->getAlignment();
+ bool isABIAligned = CurrentByteAlign == 0;
+ uint64_t VecABIByteAlign = DL->getABITypeAlignment(VecTy);
+ CurrentByteAlign = isABIAligned ? VecABIByteAlign : CurrentByteAlign;
+
+ if (CHAR_BIT * ElemByteSize != ElemBitSize)
+ return false; // Minimum byte-size elements.
+ if (MinAlign(ElemByteSize, CurrentByteAlign) == ElemByteSize) {
+ // Element-aligned, or compatible over-aligned. Keep element-aligned.
+ LoadStore->setAlignment(ElemByteSize);
+ return true;
+ }
+ return false; // Under-aligned.
+ }
+
+ void visitVectorLoadStore(BasicBlock &BB, Instructions &Loads,
+ Instructions &Stores) const;
+ void scalarizeVectorLoadStore(BasicBlock &BB, const Instructions &Loads,
+ const Instructions &Stores) const;
};
} // anonymous namespace
char FixVectorLoadStoreAlignment::ID = 0;
INITIALIZE_PASS(FixVectorLoadStoreAlignment, "fix-vector-load-store-alignment",
- "Replace vector load/store by loads/stores of each element",
+ "Ensure vector load/store have element-size alignment",
false, false)
-void FixVectorLoadStoreAlignment::findVectorLoadStore(
- const BasicBlock &BB, Instructions &Loads, Instructions &Stores) const {
- for (BasicBlock::const_iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;
+void FixVectorLoadStoreAlignment::visitVectorLoadStore(
+ BasicBlock &BB, Instructions &Loads, Instructions &Stores) const {
+ for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;
++BBI) {
- Instruction *I = const_cast<Instruction *>(&*BBI);
+ Instruction *I = &*BBI;
// The following list of instructions is based on mayReadOrWriteMemory.
switch (I->getOpcode()) {
case Instruction::Load:
if (pointerOperandIsVectorPointer<LoadInst>(I)) {
if (cast<LoadInst>(I)->isAtomic())
report_fatal_error("unhandled: atomic vector store");
- Loads.push_back(I);
+ if (!tryFixVectorAlignment<LoadInst>(DL, I))
+ Loads.push_back(I);
}
break;
case Instruction::Store:
if (pointerOperandIsVectorPointer<StoreInst>(I)) {
if (cast<StoreInst>(I)->isAtomic())
report_fatal_error("unhandled: atomic vector store");
- Stores.push_back(I);
+ if (!tryFixVectorAlignment<StoreInst>(DL, I))
+ Stores.push_back(I);
}
break;
case Instruction::Alloca:
@@ -144,7 +175,7 @@ void FixVectorLoadStoreAlignment::findVectorLoadStore(
}
}
-void FixVectorLoadStoreAlignment::fixVectorLoadStoreAlignment(
+void FixVectorLoadStoreAlignment::scalarizeVectorLoadStore(
BasicBlock &BB, const Instructions &Loads,
const Instructions &Stores) const {
for (Instructions::const_iterator IB = Loads.begin(), IE = Loads.end();
@@ -222,10 +253,10 @@ bool FixVectorLoadStoreAlignment::runOnBasicBlock(BasicBlock &BB) {
DL = &getAnalysis<DataLayout>();
Instructions Loads;
Instructions Stores;
- findVectorLoadStore(BB, Loads, Stores);
+ visitVectorLoadStore(BB, Loads, Stores);
if (!(Loads.empty() && Stores.empty())) {
Changed = true;
- fixVectorLoadStoreAlignment(BB, Loads, Stores);
+ scalarizeVectorLoadStore(BB, Loads, Stores);
}
return Changed;
}
« no previous file with comments | « lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp ('k') | lib/Transforms/NaCl/StripAttributes.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698