Skip to content

Commit

Permalink
[PPC64LE] Remove unnecessary swaps from lane-insensitive vector compu…
Browse files Browse the repository at this point in the history
…tations

This patch adds a new SSA MI pass that runs on little-endian PPC64
code with VSX enabled. Loads and stores of 4x32 and 2x64 vectors
without alignment constraints are accomplished for little-endian using
lxvd2x/xxswapd and xxswapd/stxvd2x. The existence of the additional
xxswapd instructions hurts performance in comparison with big-endian
code, but they are necessary in the general case to support correct
semantics.

However, the general case does not apply to most vector code. Many
vector instructions are lane-insensitive; they do not "care" which
lanes the parallel computations are performed within, provided that
the resulting data is stored into the correct locations. Thus this
pass looks for computations that perform only lane-insensitive
operations, and remove the unnecessary swaps from loads and stores in
such computations.

Future improvements will allow computations using certain
lane-sensitive operations to also be optimized in this manner, by
modifying the lane-sensitive operations to account for the permuted
order of the lanes. However, this patch only adds the infrastructure
to permit this; no lane-sensitive operations are optimized at this
time.

This code is heavily exercised by the various vectorizing applications
in the projects/test-suite tree. For the time being, I have only added
one simple test case to demonstrate what the pass is doing. Although
it is quite simple, it provides coverage for much of the code,
including the special case handling of copies and subreg-to-reg
operations feeding the swaps. I plan to add additional tests in the
future as I fill in more of the "special handling" code.

Two existing tests were affected, because they expected the swaps to
be present, but they are now removed.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235910 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
wschmidt-ibm committed Apr 27, 2015
1 parent 267cdc0 commit dcc4f72
Show file tree
Hide file tree
Showing 9 changed files with 971 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/Target/PowerPC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ add_llvm_target(PowerPCCodeGen
PPCTLSDynamicCall.cpp
PPCVSXCopy.cpp
PPCVSXFMAMutate.cpp
PPCVSXSwapRemoval.cpp
)

add_subdirectory(AsmParser)
Expand Down
1 change: 1 addition & 0 deletions lib/Target/PowerPC/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace llvm {
FunctionPass *createPPCEarlyReturnPass();
FunctionPass *createPPCVSXCopyPass();
FunctionPass *createPPCVSXFMAMutatePass();
FunctionPass *createPPCVSXSwapRemovalPass();
FunctionPass *createPPCBranchSelectionPass();
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
FunctionPass *createPPCTLSDynamicCallPass();
Expand Down
15 changes: 15 additions & 0 deletions lib/Target/PowerPC/PPCInstrAltivec.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
//
//===----------------------------------------------------------------------===//

// *********************************** NOTE ***********************************
// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing **
// ** which VMX and VSX instructions are lane-sensitive and which are not. **
// ** A lane-sensitive instruction relies, implicitly or explicitly, on **
// ** whether lanes are numbered from left to right. An instruction like **
// ** VADDFP is not lane-sensitive, because each lane of the result vector **
// ** relies only on the corresponding lane of the source vectors. However, **
// ** an instruction like VMULESB is lane-sensitive, because "even" and **
// ** "odd" lanes are different for big-endian and little-endian numbering. **
// ** **
// ** When adding new VMX and VSX instructions, please consider whether they **
// ** are lane-sensitive. If so, they must be added to a switch statement **
// ** in PPCVSXSwapRemoval::gatherVectorInstructions(). **
// ****************************************************************************

//===----------------------------------------------------------------------===//
// Altivec transformation functions and pattern fragments.
//
Expand Down
15 changes: 15 additions & 0 deletions lib/Target/PowerPC/PPCInstrVSX.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
//
//===----------------------------------------------------------------------===//

// *********************************** NOTE ***********************************
// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing **
// ** which VMX and VSX instructions are lane-sensitive and which are not. **
// ** A lane-sensitive instruction relies, implicitly or explicitly, on **
// ** whether lanes are numbered from left to right. An instruction like **
// ** VADDFP is not lane-sensitive, because each lane of the result vector **
// ** relies only on the corresponding lane of the source vectors. However, **
// ** an instruction like VMULESB is lane-sensitive, because "even" and **
// ** "odd" lanes are different for big-endian and little-endian numbering. **
// ** **
// ** When adding new VMX and VSX instructions, please consider whether they **
// ** are lane-sensitive. If so, they must be added to a switch statement **
// ** in PPCVSXSwapRemoval::gatherVectorInstructions(). **
// ****************************************************************************

def PPCRegVSRCAsmOperand : AsmOperandClass {
let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
}
Expand Down
14 changes: 14 additions & 0 deletions lib/Target/PowerPC/PPCTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ static cl::opt<bool>
VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early",
cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early"));

static cl::
opt<bool> DisableVSXSwapRemoval("disable-ppc-vsx-swap-removal", cl::Hidden,
cl::desc("Disable VSX Swap Removal for PPC"));

static cl::opt<bool>
EnableGEPOpt("ppc-gep-opt", cl::Hidden,
cl::desc("Enable optimizations on complex GEPs"),
Expand Down Expand Up @@ -239,6 +243,7 @@ class PPCPassConfig : public TargetPassConfig {
bool addPreISel() override;
bool addILPOpts() override;
bool addInstSelector() override;
void addMachineSSAOptimization() override;
void addPreRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
Expand Down Expand Up @@ -306,6 +311,15 @@ bool PPCPassConfig::addInstSelector() {
return false;
}

void PPCPassConfig::addMachineSSAOptimization() {
TargetPassConfig::addMachineSSAOptimization();
// For little endian, remove where possible the vector swap instructions
// introduced at code generation to normalize vector element order.
if (Triple(TM->getTargetTriple()).getArch() == Triple::ppc64le &&
!DisableVSXSwapRemoval)
addPass(createPPCVSXSwapRemovalPass());
}

void PPCPassConfig::addPreRegAlloc() {
initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry());
insertPass(VSXFMAMutateEarly ? &RegisterCoalescerID : &MachineSchedulerID,
Expand Down
Loading

0 comments on commit dcc4f72

Please sign in to comment.