[llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Vector/Alloca2Realloc.cpp AltiVec.cpp LowerVectors.cpp RaiseVectors.cpp SSE.cpp
Robert Bocchino
bocchino at cs.uiuc.edu
Wed Nov 16 10:33:12 PST 2005
Changes in directory llvm/lib/Transforms/Vector:
Alloca2Realloc.cpp updated: 1.1.2.1 -> 1.1.2.2
AltiVec.cpp updated: 1.1.2.2 -> 1.1.2.3
LowerVectors.cpp updated: 1.1.2.2 -> 1.1.2.3
RaiseVectors.cpp updated: 1.1.2.2 -> 1.1.2.3
SSE.cpp updated: 1.1.2.2 -> 1.1.2.3
---
Log message:
Merged mainline into Vector LLVM branch
---
Diffs of the changes: (+503 -484)
Alloca2Realloc.cpp | 3
AltiVec.cpp | 3
LowerVectors.cpp | 5
RaiseVectors.cpp | 973 ++++++++++++++++++++++++++---------------------------
SSE.cpp | 3
5 files changed, 503 insertions(+), 484 deletions(-)
Index: llvm/lib/Transforms/Vector/Alloca2Realloc.cpp
diff -u llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.1 llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.2
--- llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005
+++ llvm/lib/Transforms/Vector/Alloca2Realloc.cpp Wed Nov 16 12:32:56 2005
@@ -28,6 +28,7 @@
#include "llvm/Pass.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Scalar.h"
using namespace llvm;
@@ -210,3 +211,5 @@
}
}
+
+FunctionPass *llvm::createAlloca2ReallocPass() { return new Alloca2Realloc(); }
Index: llvm/lib/Transforms/Vector/AltiVec.cpp
diff -u llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.2 llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.3
--- llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005
+++ llvm/lib/Transforms/Vector/AltiVec.cpp Wed Nov 16 12:32:56 2005
@@ -26,6 +26,7 @@
#include "llvm/ADT/hash_set"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Transforms/Scalar.h"
#include "VectorLLVM/Utils.h"
using namespace llvm;
@@ -521,3 +522,5 @@
}
}
+
+FunctionPass *llvm::createAltiVecPass() { return new AltiVec(); }
Index: llvm/lib/Transforms/Vector/LowerVectors.cpp
diff -u llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.2 llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.3
--- llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005
+++ llvm/lib/Transforms/Vector/LowerVectors.cpp Wed Nov 16 12:32:56 2005
@@ -78,7 +78,7 @@
RegisterOpt<LowerVectors> X("lowervectors",
"Lower vector operations to iterated scalar operations");
-
+
class VMemoryInstLowering {
protected:
BasicBlock *constructLoop(VMemoryInst*,BasicBlock*,std::vector<Value*>,Value*);
@@ -1103,3 +1103,6 @@
}
}
+
+FunctionPass *llvm::createLowerVectorsPass() { return new LowerVectors(); }
+
Index: llvm/lib/Transforms/Vector/RaiseVectors.cpp
diff -u llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.2 llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.3
--- llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005
+++ llvm/lib/Transforms/Vector/RaiseVectors.cpp Wed Nov 16 12:32:56 2005
@@ -19,6 +19,7 @@
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Type.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/hash_map"
#include "llvm/ADT/hash_set"
@@ -77,521 +78,527 @@
};
+
RegisterOpt<RaiseVectors> X("raisevectors",
"Raise Vector-C significant functions to Vector-LLVM");
+}
- //===----------------------------------------------------------------------===//
- // RaiseVectors implementation
- //===----------------------------------------------------------------------===//
+FunctionPass *llvm::createRaiseVectorsPass() { return new RaiseVectors(); }
- /// llvm-gcc is very permissive about function declarations --
- /// undeclared functions are treated as int(...). Here we require
- /// and check that the user has properly declared all Vector-C
- /// significant functions.
- ///
- bool RaiseVectors::doInitialization(Module &M) {
- for (Module::iterator I = M.begin(), E = M.end();
- I != E; ++I) {
- if (!VectorSignificantFunctions::isProperlyDeclared(I)) {
- std::cerr << "Significant function " << I->getName()
- << " was not declared or was improperly declared.\n";
- exit(1);
- }
+
+//===----------------------------------------------------------------------===//
+// RaiseVectors implementation
+//===----------------------------------------------------------------------===//
+
+/// llvm-gcc is very permissive about function declarations --
+/// undeclared functions are treated as int(...). Here we require
+/// and check that the user has properly declared all Vector-C
+/// significant functions.
+///
+bool RaiseVectors::doInitialization(Module &M) {
+ for (Module::iterator I = M.begin(), E = M.end();
+ I != E; ++I) {
+ if (!VectorSignificantFunctions::isProperlyDeclared(I)) {
+ std::cerr << "Significant function " << I->getName()
+ << " was not declared or was improperly declared.\n";
+ exit(1);
}
- return false;
}
+ return false;
+}
- /// Main function called by PassManager
- ///
- bool RaiseVectors::runOnFunction(Function &F) {
- DEBUG(std::cerr << "\nrunOnFunction(" << F.getName() << ")\n");
-
- raisingMap.clear();
- workList.clear();
- raisedInstructions.clear();
- bool changed = addDefsToWorklist(F);
-
- if (changed) {
- raiseInstructions();
- deleteRaisedInstructions();
- }
-
- return changed;
-
- }
+/// Main function called by PassManager
+///
+bool RaiseVectors::runOnFunction(Function &F) {
+ DEBUG(std::cerr << "\nrunOnFunction(" << F.getName() << ")\n");
+
+ raisingMap.clear();
+ workList.clear();
+ raisedInstructions.clear();
+ bool changed = addDefsToWorklist(F);
+
+ if (changed) {
+ raiseInstructions();
+ deleteRaisedInstructions();
+ }
+
+ return changed;
+
+}
- /// Add all vector definitions to the work list
- ///
- bool RaiseVectors::addDefsToWorklist(Function& F) {
- bool defFound = false;
- for (Function::iterator FI = F.begin(), FE = F.end();
- FI != FE; ++FI) {
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- if (CallInst *CI = dyn_cast<CallInst>(BI)) {
- if (Function* F = CI->getCalledFunction()) {
- VectorSignificantFunctions::ID id =
- VectorSignificantFunctions::getID(F->getName());
- if (id == VectorSignificantFunctions::vload ||
- id == VectorSignificantFunctions::vgather ||
- id == VectorSignificantFunctions::vloadi ||
- id == VectorSignificantFunctions::vimm ||
- id == VectorSignificantFunctions::fixed_vimm ||
- id == VectorSignificantFunctions::load ||
- id == VectorSignificantFunctions::constant) {
- workList.push_back(CI);
- defFound = true;
- }
+/// Add all vector definitions to the work list
+///
+bool RaiseVectors::addDefsToWorklist(Function& F) {
+ bool defFound = false;
+ for (Function::iterator FI = F.begin(), FE = F.end();
+ FI != FE; ++FI) {
+ for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
+ BI != BE; ++BI) {
+ if (CallInst *CI = dyn_cast<CallInst>(BI)) {
+ if (Function* F = CI->getCalledFunction()) {
+ VectorSignificantFunctions::ID id =
+ VectorSignificantFunctions::getID(F->getName());
+ if (id == VectorSignificantFunctions::vload ||
+ id == VectorSignificantFunctions::vgather ||
+ id == VectorSignificantFunctions::vloadi ||
+ id == VectorSignificantFunctions::vimm ||
+ id == VectorSignificantFunctions::fixed_vimm ||
+ id == VectorSignificantFunctions::load ||
+ id == VectorSignificantFunctions::constant) {
+ workList.push_back(CI);
+ defFound = true;
}
}
}
}
- return defFound;
-
}
+ return defFound;
+
+}
- /// Raise all instructions on the worklist.
- ///
- void RaiseVectors::raiseInstructions() {
- // Visit all the instructions to be raised. As uses are
- // encountered, they are added to the worklist.
- //
- while (workList.size() > 0) {
- Instruction *I = workList.back();
- workList.pop_back();
- if(raisedInstructions.insert(I).second) {
- DEBUG(std::cerr << "Raising " << *I);
- visit(*I);
- DEBUG(if (raisingMap[I]) {std::cerr << "Raised value is " << *raisingMap[I];});
- }
- }
- // Check for leftover dummy values indicating the program
- // attempted to combine a scalar with a vector
- //
- for (hash_map<Value*,Value*>::iterator I = raisingMap.begin(),
- E = raisingMap.end(); I != E; ++I) {
- if (I->second && isa<Argument>(I->second)) {
- std::cerr << "Value was never raised!\n";
- std::cerr << *(I->first) << "\n";
- std::cerr << "This is because you used a scalar value in a vector operation.\n";
- std::cerr << "Use vimm to promote scalars to vectors "
- << "before combining them with vectors.\n";
- exit(1);
- }
+/// Raise all instructions on the worklist.
+///
+void RaiseVectors::raiseInstructions() {
+ // Visit all the instructions to be raised. As uses are
+ // encountered, they are added to the worklist.
+ //
+ while (workList.size() > 0) {
+ Instruction *I = workList.back();
+ workList.pop_back();
+ if(raisedInstructions.insert(I).second) {
+ DEBUG(std::cerr << "Raising " << *I);
+ visit(*I);
+ DEBUG(if (raisingMap[I]) {std::cerr << "Raised value is " << *raisingMap[I];});
+ }
+ }
+ // Check for leftover dummy values indicating the program
+ // attempted to combine a scalar with a vector
+ //
+ for (hash_map<Value*,Value*>::iterator I = raisingMap.begin(),
+ E = raisingMap.end(); I != E; ++I) {
+ if (I->second && isa<Argument>(I->second)) {
+ std::cerr << "Value was never raised!\n";
+ std::cerr << *(I->first) << "\n";
+ std::cerr << "This is because you used a scalar value in a vector operation.\n";
+ std::cerr << "Use vimm to promote scalars to vectors "
+ << "before combining them with vectors.\n";
+ exit(1);
}
}
+}
- /// Delete all instructions that we have raised.
- ///
- void RaiseVectors::deleteRaisedInstructions() {
+/// Delete all instructions that we have raised.
+///
+void RaiseVectors::deleteRaisedInstructions() {
+
+ for (hash_set<Instruction*>::iterator I = raisedInstructions.begin(),
+ E = raisedInstructions.end(); I != E; ++I) {
+ DEBUG(std::cerr << "Dropping all references from " << **I);
+ (*I)->dropAllReferences();
+ }
+
+ for (hash_set<Instruction*>::iterator I = raisedInstructions.begin(),
+ E = raisedInstructions.end(); I != E; ++I) {
+ (*I)->getParent()->getInstList().erase(*I);
+ }
+}
- for (hash_set<Instruction*>::iterator I = raisedInstructions.begin(),
- E = raisedInstructions.end(); I != E; ++I) {
- DEBUG(std::cerr << "Dropping all references from " << **I);
- (*I)->dropAllReferences();
+/// Raise a significant function call
+///
+void RaiseVectors::visitCallInst(CallInst &CI) {
+ Function *F = CI.getCalledFunction();
+ if (!F) {
+ std::cerr << "Can't handle indirect function call " << CI;
+ exit(1);
+ }
+ std::string name = F->getName();
+ Value *raisedValue;
+ switch(VectorSignificantFunctions::getID(name)) {
+ case VectorSignificantFunctions::vload:
+ case VectorSignificantFunctions::vgather: {
+ std::vector<Value*> idx;
+ for (unsigned i = 2; i < CI.getNumOperands(); ++i) {
+ CastInst *castInst =
+ new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI);
+ idx.push_back(castInst);
}
-
- for (hash_set<Instruction*>::iterator I = raisedInstructions.begin(),
- E = raisedInstructions.end(); I != E; ++I) {
- (*I)->getParent()->getInstList().erase(*I);
+ raisedValue = new VGatherInst(CI.getOperand(1),
+ idx, "vgather", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::load: {
+ ConstantUInt *UIntVal = dyn_cast<ConstantUInt>(CI.getOperand(2));
+ assert(UIntVal && "Vector length must be a constant UInt!");
+ const PointerType *PointerTy =
+ dyn_cast<PointerType>(CI.getOperand(1)->getType());
+ assert(PointerTy && "Pointer operand must be pointer type!");
+ CastInst *cast =
+ new CastInst(CI.getOperand(1),
+ PointerType::get(FixedVectorType::get(PointerTy->getElementType(),
+ UIntVal->getValue())),
+ "cast", &CI);
+ std::vector<Value*> Idx;
+ Idx.push_back(CI.getOperand(3));
+ GetElementPtrInst *GEP =
+ new GetElementPtrInst(cast, Idx, "gep", &CI);
+ raisedValue = new LoadInst(GEP, "load", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::vimm:
+ case VectorSignificantFunctions::vloadi: {
+ raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), false,
+ "vimm", &CI);
+ const VectorType *VT = VectorType::get(CI.getOperand(1)->getType());
+ if (raisedValue->getType() != VT)
+ raisedValue = new CastInst(raisedValue, VT, "cast", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::constant: {
+ std::vector<Constant*> elements;
+ for (unsigned i = 1; i < CI.getNumOperands(); ++i) {
+ Constant *C = dyn_cast<Constant>(CI.getOperand(i));
+ assert(C && "Operands of constant must be constants!");
+ elements.push_back(ConstantExpr::getCast(C, CI.getType()));
}
+ raisedValue = ConstantVector::get(elements);
+ addUsesToWorklist(&CI);
+ break;
}
-
- /// Raise a significant function call
- ///
- void RaiseVectors::visitCallInst(CallInst &CI) {
- Function *F = CI.getCalledFunction();
- if (!F) {
- std::cerr << "Can't handle indirect function call " << CI;
+ case VectorSignificantFunctions::fixed_vimm: {
+ ConstantUInt *UIntVal = dyn_cast<ConstantUInt>(CI.getOperand(2));
+ assert(UIntVal && "Vector length must be a constant UInt!");
+ raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2),
+ true, "vimm", &CI);
+ const FixedVectorType *VT = FixedVectorType::get(CI.getType(), UIntVal->getValue());
+ if (raisedValue->getType() != VT)
+ raisedValue = new CastInst(raisedValue, VT, "cast", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::vstore:
+ case VectorSignificantFunctions::vscatter: {
+ std::vector<Value*> idx;
+ for (unsigned i = 3; i < CI.getNumOperands(); ++i) {
+ CastInst *castInst =
+ new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI);
+ idx.push_back(castInst);
+ }
+ Value *raisedOp = getRaisedValue(CI.getOperand(1), (unsigned) 0);
+ Value *ptr = CI.getOperand(2);
+ raisedValue = new VScatterInst(raisedOp, ptr, idx, &CI);
+ break;
+ }
+ case VectorSignificantFunctions::store: {
+ unsigned length = getVectorLength(&CI);
+ Value *op1 = getRaisedValue(CI.getOperand(1), length);
+ const PointerType *PointerTy =
+ dyn_cast<PointerType>(CI.getOperand(2)->getType());
+ assert(PointerTy && "Pointer operand must be pointer type!");
+ CastInst *cast =
+ new CastInst(CI.getOperand(2),
+ PointerType::get(FixedVectorType::get(PointerTy->getElementType(),
+ length)),
+ "cast", &CI);
+ std::vector<Value*> Idx;
+ Idx.push_back(CI.getOperand(3));
+ GetElementPtrInst *GEP =
+ new GetElementPtrInst(cast, Idx, "gep", &CI);
+ raisedValue = new StoreInst(op1, GEP, &CI);
+ break;
+ }
+ case VectorSignificantFunctions::vselect: {
+ unsigned numArgs = 3;
+ unsigned length = getVectorLength(&CI);
+ assert((CI.getNumOperands() == numArgs+1) &&
+ "Wrong number of arguments to _select!");
+ CastInst *cast = dyn_cast<CastInst>(CI.getOperand(1));
+ assert(cast && "First operand of vselect must be cast!");
+ assert(cast->getOperand(0)->getType() == Type::BoolTy &&
+ "First operand of vselect must be cast of bool to int!");
+ Value *raisedArgs[numArgs];
+ raisedArgs[0] = getRaisedValue(cast->getOperand(0), length);
+ for (unsigned i = 1; i < numArgs; ++i) {
+ Value *arg = CI.getOperand(i+1);
+ raisedArgs[i] = getRaisedValue(arg, length);
+ }
+ raisedValue =
+ new VSelectInst(raisedArgs[0], raisedArgs[1], raisedArgs[2], "vselect", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::extract: {
+ Value *raisedOp = getRaisedOperand(&CI, 1);
+ raisedValue = new ExtractInst(raisedOp, CI.getOperand(2),
+ CI.getOperand(3), CI.getOperand(4),
+ "extract", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::combine: {
+ unsigned length = getVectorLength(&CI);
+ Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length);
+ Value *raisedOp2 = getRaisedValue(CI.getOperand(2), length);
+ raisedValue = new CombineInst(raisedOp1, raisedOp2,
+ CI.getOperand(3), CI.getOperand(4),
+ "combine", &CI);
+ addUsesToWorklist(&CI);
+
+ break;
+ }
+ case VectorSignificantFunctions::fixed_combine: {
+ ConstantUInt *op2 = dyn_cast<ConstantUInt>(CI.getOperand(2));
+ ConstantUInt *op4 = dyn_cast<ConstantUInt>(CI.getOperand(4));
+ assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!");
+ unsigned length1 = op2->getValue();
+ unsigned length2 = op4->getValue();
+ Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1);
+ Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2);
+ raisedValue = new CombineInst(raisedOp1, raisedOp2,
+ CI.getOperand(5), CI.getOperand(6),
+ "combine", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::fixed_permute: {
+ ConstantUInt *op2 = dyn_cast<ConstantUInt>(CI.getOperand(2));
+ ConstantUInt *op4 = dyn_cast<ConstantUInt>(CI.getOperand(4));
+ assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!");
+ unsigned length1 = op2->getValue();
+ unsigned length2 = op4->getValue();
+ Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1);
+ Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2);
+ raisedValue = VectorUtils::getCallInst(raisedOp2->getType(), "vllvm_permute_" +
+ cast<FixedVectorType>(raisedOp2->getType())->getElementType()->getDescription(),
+ raisedOp1, raisedOp2, "permute", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ case VectorSignificantFunctions::extractelement: {
+ Value *raisedOp = getRaisedOperand(&CI, 1);
+ raisedValue =
+ new ExtractElementInst(raisedOp, CI.getOperand(2),
+ "extractelement", &CI);
+ CI.replaceAllUsesWith(raisedValue);
+ break;
+ }
+ case VectorSignificantFunctions::combineelement: {
+ Value *raisedOp1 = getRaisedOperand(&CI, 1);
+ raisedValue = new CombineElementInst(raisedOp1, CI.getOperand(2),
+ CI.getOperand(3), "combineelement", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ default:
+ if (name.substr(0, 7) == "vectorc") {
+ name.erase(0, 7);
+ name = "vllvm" + name;
+ }
+ else if (name.substr(0, 5) == "vllvm") {
+ name += "_vector";
+ } else {
+ std::cerr << "Can't handle instruction " << CI;
exit(1);
}
- std::string name = F->getName();
- Value *raisedValue;
- switch(VectorSignificantFunctions::getID(name)) {
- case VectorSignificantFunctions::vload:
- case VectorSignificantFunctions::vgather: {
- std::vector<Value*> idx;
- for (unsigned i = 2; i < CI.getNumOperands(); ++i) {
- CastInst *castInst =
- new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI);
- idx.push_back(castInst);
- }
- raisedValue = new VGatherInst(CI.getOperand(1),
- idx, "vgather", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::load: {
- ConstantUInt *UIntVal = dyn_cast<ConstantUInt>(CI.getOperand(2));
- assert(UIntVal && "Vector length must be a constant UInt!");
- const PointerType *PointerTy =
- dyn_cast<PointerType>(CI.getOperand(1)->getType());
- assert(PointerTy && "Pointer operand must be pointer type!");
- CastInst *cast =
- new CastInst(CI.getOperand(1),
- PointerType::get(FixedVectorType::get(PointerTy->getElementType(),
- UIntVal->getValue())),
- "cast", &CI);
- std::vector<Value*> Idx;
- Idx.push_back(CI.getOperand(3));
- GetElementPtrInst *GEP =
- new GetElementPtrInst(cast, Idx, "gep", &CI);
- raisedValue = new LoadInst(GEP, "load", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::vimm:
- case VectorSignificantFunctions::vloadi: {
- raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), false,
- "vimm", &CI);
- const VectorType *VT = VectorType::get(CI.getOperand(1)->getType());
- if (raisedValue->getType() != VT)
- raisedValue = new CastInst(raisedValue, VT, "cast", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::constant: {
- std::vector<Constant*> elements;
- for (unsigned i = 1; i < CI.getNumOperands(); ++i) {
- Constant *C = dyn_cast<Constant>(CI.getOperand(i));
- assert(C && "Operands of constant must be constants!");
- elements.push_back(ConstantExpr::getCast(C, CI.getType()));
- }
- raisedValue = ConstantVector::get(elements);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::fixed_vimm: {
- ConstantUInt *UIntVal = dyn_cast<ConstantUInt>(CI.getOperand(2));
- assert(UIntVal && "Vector length must be a constant UInt!");
- raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2),
- true, "vimm", &CI);
- const FixedVectorType *VT = FixedVectorType::get(CI.getType(), UIntVal->getValue());
- if (raisedValue->getType() != VT)
- raisedValue = new CastInst(raisedValue, VT, "cast", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::vstore:
- case VectorSignificantFunctions::vscatter: {
- std::vector<Value*> idx;
- for (unsigned i = 3; i < CI.getNumOperands(); ++i) {
- CastInst *castInst =
- new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI);
- idx.push_back(castInst);
- }
- Value *raisedOp = getRaisedValue(CI.getOperand(1), (unsigned) 0);
- Value *ptr = CI.getOperand(2);
- raisedValue = new VScatterInst(raisedOp, ptr, idx, &CI);
- break;
- }
- case VectorSignificantFunctions::store: {
- unsigned length = getVectorLength(&CI);
- Value *op1 = getRaisedValue(CI.getOperand(1), length);
- const PointerType *PointerTy =
- dyn_cast<PointerType>(CI.getOperand(2)->getType());
- assert(PointerTy && "Pointer operand must be pointer type!");
- CastInst *cast =
- new CastInst(CI.getOperand(2),
- PointerType::get(FixedVectorType::get(PointerTy->getElementType(),
- length)),
- "cast", &CI);
- std::vector<Value*> Idx;
- Idx.push_back(CI.getOperand(3));
- GetElementPtrInst *GEP =
- new GetElementPtrInst(cast, Idx, "gep", &CI);
- raisedValue = new StoreInst(op1, GEP, &CI);
- break;
- }
- case VectorSignificantFunctions::vselect: {
- unsigned numArgs = 3;
- unsigned length = getVectorLength(&CI);
- assert((CI.getNumOperands() == numArgs+1) &&
- "Wrong number of arguments to _select!");
- CastInst *cast = dyn_cast<CastInst>(CI.getOperand(1));
- assert(cast && "First operand of vselect must be cast!");
- assert(cast->getOperand(0)->getType() == Type::BoolTy &&
- "First operand of vselect must be cast of bool to int!");
- Value *raisedArgs[numArgs];
- raisedArgs[0] = getRaisedValue(cast->getOperand(0), length);
- for (unsigned i = 1; i < numArgs; ++i) {
- Value *arg = CI.getOperand(i+1);
- raisedArgs[i] = getRaisedValue(arg, length);
- }
- raisedValue =
- new VSelectInst(raisedArgs[0], raisedArgs[1], raisedArgs[2], "vselect", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::extract: {
- Value *raisedOp = getRaisedOperand(&CI, 1);
- raisedValue = new ExtractInst(raisedOp, CI.getOperand(2),
- CI.getOperand(3), CI.getOperand(4),
- "extract", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::combine: {
- unsigned length = getVectorLength(&CI);
- Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length);
- Value *raisedOp2 = getRaisedValue(CI.getOperand(2), length);
- raisedValue = new CombineInst(raisedOp1, raisedOp2,
- CI.getOperand(3), CI.getOperand(4),
- "combine", &CI);
- addUsesToWorklist(&CI);
-
- break;
- }
- case VectorSignificantFunctions::fixed_combine: {
- ConstantUInt *op2 = dyn_cast<ConstantUInt>(CI.getOperand(2));
- ConstantUInt *op4 = dyn_cast<ConstantUInt>(CI.getOperand(4));
- assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!");
- unsigned length1 = op2->getValue();
- unsigned length2 = op4->getValue();
- Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1);
- Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2);
- raisedValue = new CombineInst(raisedOp1, raisedOp2,
- CI.getOperand(5), CI.getOperand(6),
- "combine", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::fixed_permute: {
- ConstantUInt *op2 = dyn_cast<ConstantUInt>(CI.getOperand(2));
- ConstantUInt *op4 = dyn_cast<ConstantUInt>(CI.getOperand(4));
- assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!");
- unsigned length1 = op2->getValue();
- unsigned length2 = op4->getValue();
- Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1);
- Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2);
- raisedValue = VectorUtils::getCallInst(raisedOp2->getType(), "vllvm_permute_" +
- cast<FixedVectorType>(raisedOp2->getType())->getElementType()->getDescription(),
- raisedOp1, raisedOp2, "permute", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- case VectorSignificantFunctions::extractelement: {
- Value *raisedOp = getRaisedOperand(&CI, 1);
- raisedValue =
- new ExtractElementInst(raisedOp, CI.getOperand(2),
- "extractelement", &CI);
- CI.replaceAllUsesWith(raisedValue);
- break;
- }
- case VectorSignificantFunctions::combineelement: {
- Value *raisedOp1 = getRaisedOperand(&CI, 1);
- raisedValue = new CombineElementInst(raisedOp1, CI.getOperand(2),
- CI.getOperand(3), "combineelement", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- default:
- if (name.substr(0, 7) == "vectorc") {
- name.erase(0, 7);
- name = "vllvm" + name;
- }
- else if (name.substr(0, 5) == "vllvm") {
- name += "_vector";
+ unsigned length = getVectorLength(&CI);
+ std::vector<const Type*> formalArgs;
+ std::vector<Value*> args;
+ for (unsigned i = 1; i < CI.getNumOperands(); ++i) {
+ Value *op = CI.getOperand(i);
+ if (isa<Constant>(op)) {
+ formalArgs.push_back(op->getType());
+ args.push_back(op);
} else {
- std::cerr << "Can't handle instruction " << CI;
- exit(1);
- }
- unsigned length = getVectorLength(&CI);
- std::vector<const Type*> formalArgs;
- std::vector<Value*> args;
- for (unsigned i = 1; i < CI.getNumOperands(); ++i) {
- Value *op = CI.getOperand(i);
- if (isa<Constant>(op)) {
- formalArgs.push_back(op->getType());
- args.push_back(op);
- } else {
- formalArgs.push_back(getRaisedType(CI.getOperand(i)->getType(), length));
- args.push_back(getRaisedOperand(&CI, i));
- }
- }
- FunctionType *FType =
- FunctionType::get(getRaisedType(F->getReturnType(), length), formalArgs, false);
- Module *M = CI.getParent()->getParent()->getParent();
- Function *func = M->getOrInsertFunction(name, FType);
- raisedValue = new CallInst(func, args, "func", &CI);
- addUsesToWorklist(&CI);
- break;
- }
- setRaisedValue(&CI, raisedValue);
- }
-
- /// Raise a binary operator
- ///
- void RaiseVectors::visitBinaryOperator(BinaryOperator &BO) {
- unsigned length = getVectorLength(&BO);
- Value *newOp[2];
- for (unsigned i = 0; i < 2; ++i) {
- newOp[i] = getRaisedValue(BO.getOperand(i), length);
- }
- Instruction::BinaryOps raisedOp;
- if (SetCondInst *SI = dyn_cast<SetCondInst>(&BO))
- raisedOp = SI->getVectorOpcode();
- else raisedOp = BO.getOpcode();
- Instruction *raisedValue =
- BinaryOperator::create(raisedOp, newOp[0], newOp[1], "binop", &BO);
- setRaisedValue(&BO, raisedValue);
- addUsesToWorklist(&BO);
- }
-
- /// Raise a cast instruction
- ///
- void RaiseVectors::visitCastInst(CastInst &CI) {
- // Don't raise the cast if it's a cast of a bool to an int to get
- // it into a vselect significant function
- //
- if (CI.hasOneUse()) {
- User *use = *CI.use_begin();
- if (CallInst *I = dyn_cast<CallInst>(use)) {
- if (Function *F = I->getCalledFunction()) {
- if (VectorSignificantFunctions::getID(F->getName()) ==
- VectorSignificantFunctions::vselect)
- return;
- }
+ formalArgs.push_back(getRaisedType(CI.getOperand(i)->getType(), length));
+ args.push_back(getRaisedOperand(&CI, i));
}
}
- unsigned length = getVectorLength(&CI);
- Value *raisedOp = getRaisedValue(CI.getOperand(0), length);
- Instruction *raisedValue =
- new CastInst(raisedOp, getRaisedType(CI.getType(), length), "cast", &CI);
- setRaisedValue(&CI, raisedValue);
- addUsesToWorklist(&CI);
- }
-
- /// Raise a shift instruction
- ///
- void RaiseVectors::visitShiftInst(ShiftInst &SI) {
- Value *raisedOp = getRaisedOperand(&SI, 0);
- Instruction *raisedValue =
- new ShiftInst(SI.getOpcode(), raisedOp,
- SI.getOperand(1), "shift", &SI);
- setRaisedValue(&SI, raisedValue);
- addUsesToWorklist(&SI);
- }
-
- /// Raise a select instruction
- ///
- void RaiseVectors::visitSelectInst(SelectInst &SI) {
- Value *newOp[2];
- unsigned length = getVectorLength(&SI);
- for (unsigned i = 0; i < 2; ++i) {
- newOp[i] = getRaisedValue(SI.getOperand(i+1), length);
- }
- Instruction *raisedValue =
- new SelectInst(SI.getOperand(0), newOp[0], newOp[1],
- "select", &SI);
- setRaisedValue(&SI, raisedValue);
- addUsesToWorklist(&SI);
- }
-
- /// Raise a phi node
- ///
- void RaiseVectors::visitPHINode(PHINode &PN) {
- unsigned length = getVectorLength(&PN);
- const VectorType *VT = 0;
- if (length)
- VT = FixedVectorType::get(PN.getType(), length);
- else
- VT = VectorType::get(PN.getType());
- PHINode *raisedValue = new PHINode(VT, "phi", &PN);
- for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
- raisedValue->addIncoming(getRaisedValue(PN.getIncomingValue(i), length),
- PN.getIncomingBlock(i));
- setRaisedValue(&PN, raisedValue);
- addUsesToWorklist(&PN);
- }
-
- /// Get the raised type for a given scalar type or pointer to scalar
- /// type and vector length. Vector length of 0 means a non-fixed
- /// length vector.
- ///
- const Type *RaiseVectors::getRaisedType(const Type* Ty, unsigned length) {
- unsigned i = 0;
- while (isa<PointerType>(Ty)) {
- Ty = cast<PointerType>(Ty)->getElementType();
- ++i;
- }
- const Type *result =
- (length == 0) ? VectorType::get(Ty) : FixedVectorType::get(Ty, length);
- while (i-- > 0) {
- result = PointerType::get(result);
- }
- return result;
- }
-
- /// Get the (fixed) vector length of a raised instruction. Return 0
- /// if the vector is not a fixed-length vector.
- ///
- unsigned RaiseVectors::getVectorLength(Instruction *I) {
- for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
- OI != OE; ++OI) {
- if (Value *val = raisingMap[*OI]) {
- const Type *Ty = val->getType();
- while (isa<PointerType>(Ty))
- Ty = cast<PointerType>(Ty)->getElementType();
- if (const FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty))
- return VT->getNumElements();
- return 0;
+ FunctionType *FType =
+ FunctionType::get(getRaisedType(F->getReturnType(), length), formalArgs, false);
+ Module *M = CI.getParent()->getParent()->getParent();
+ Function *func = M->getOrInsertFunction(name, FType);
+ raisedValue = new CallInst(func, args, "func", &CI);
+ addUsesToWorklist(&CI);
+ break;
+ }
+ setRaisedValue(&CI, raisedValue);
+}
+
+/// Raise a binary operator
+///
+void RaiseVectors::visitBinaryOperator(BinaryOperator &BO) {
+ unsigned length = getVectorLength(&BO);
+ Value *newOp[2];
+ for (unsigned i = 0; i < 2; ++i) {
+ newOp[i] = getRaisedValue(BO.getOperand(i), length);
+ }
+ Instruction::BinaryOps raisedOp;
+ if (SetCondInst *SI = dyn_cast<SetCondInst>(&BO))
+ raisedOp = SI->getVectorOpcode();
+ else raisedOp = BO.getOpcode();
+ Instruction *raisedValue =
+ BinaryOperator::create(raisedOp, newOp[0], newOp[1], "binop", &BO);
+ setRaisedValue(&BO, raisedValue);
+ addUsesToWorklist(&BO);
+}
+
+/// Raise a cast instruction
+///
+void RaiseVectors::visitCastInst(CastInst &CI) {
+ // Don't raise the cast if it's a cast of a bool to an int to get
+ // it into a vselect significant function
+ //
+ if (CI.hasOneUse()) {
+ User *use = *CI.use_begin();
+ if (CallInst *I = dyn_cast<CallInst>(use)) {
+ if (Function *F = I->getCalledFunction()) {
+ if (VectorSignificantFunctions::getID(F->getName()) ==
+ VectorSignificantFunctions::vselect)
+ return;
}
}
- assert(0 && "Instruction has no raised operands!");
}
+ unsigned length = getVectorLength(&CI);
+ Value *raisedOp = getRaisedValue(CI.getOperand(0), length);
+ Instruction *raisedValue =
+ new CastInst(raisedOp, getRaisedType(CI.getType(), length), "cast", &CI);
+ setRaisedValue(&CI, raisedValue);
+ addUsesToWorklist(&CI);
+}
- /// Add the specified pair to the raising map, replacing dummy uses
- /// if necessary
- ///
- void RaiseVectors::setRaisedValue(Instruction *key, Value *newValue) {
- if (!newValue)
- return;
- Value*& oldValue = raisingMap[key];
- if (oldValue) {
- if (oldValue->getType() != newValue->getType())
- newValue = new CastInst(oldValue, newValue->getType(), "cast", key);
- oldValue->replaceAllUsesWith(newValue);
- delete oldValue;
- }
- oldValue = newValue;
- }
-
- /// Get the value for the specified key from the raising map. If no
- /// value is there, we haven't raised the value yet, so create a
- /// dummy value with the appropriate vector length and replace it
- /// when the value is raised.
- ///
- Value *RaiseVectors::getRaisedValue(Value *key, unsigned length) {
- const Type *Ty = getRaisedType(key->getType(), length);
- Value*& Val = raisingMap[key];
- if (!Val) {
- Val = Ty ? new Argument(Ty) : new Argument(VectorType::get(key->getType()));
- DEBUG(std::cerr << "Created dummy value " << *Val << "\n");
- }
- return Val;
- }
-
- /// Get the raised operand of an instruction
- ///
- Value *RaiseVectors::getRaisedOperand(Instruction *I, unsigned i) {
- Value *op = I->getOperand(i);
- unsigned length = getVectorLength(I);
- return getRaisedValue(op, length);
- }
-
- /// Add all uses of an instruction to the worklist
- ///
- void RaiseVectors::addUsesToWorklist(Instruction *I) {
- DEBUG(std::cerr << "Adding uses of " << *I);
- for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
- UI != UE; ++UI) {
- if (Instruction *II = dyn_cast<Instruction>(*UI)) {
- DEBUG(std::cerr << "Adding " << *II);
- workList.push_back(II);
- }
+/// Raise a shift instruction
+///
+void RaiseVectors::visitShiftInst(ShiftInst &SI) {
+ Value *raisedOp = getRaisedOperand(&SI, 0);
+ Instruction *raisedValue =
+ new ShiftInst(SI.getOpcode(), raisedOp,
+ SI.getOperand(1), "shift", &SI);
+ setRaisedValue(&SI, raisedValue);
+ addUsesToWorklist(&SI);
+}
+
+/// Raise a select instruction
+///
+void RaiseVectors::visitSelectInst(SelectInst &SI) {
+ Value *newOp[2];
+ unsigned length = getVectorLength(&SI);
+ for (unsigned i = 0; i < 2; ++i) {
+ newOp[i] = getRaisedValue(SI.getOperand(i+1), length);
+ }
+ Instruction *raisedValue =
+ new SelectInst(SI.getOperand(0), newOp[0], newOp[1],
+ "select", &SI);
+ setRaisedValue(&SI, raisedValue);
+ addUsesToWorklist(&SI);
+}
+
+/// Raise a phi node
+///
+void RaiseVectors::visitPHINode(PHINode &PN) {
+ unsigned length = getVectorLength(&PN);
+ const VectorType *VT = 0;
+ if (length)
+ VT = FixedVectorType::get(PN.getType(), length);
+ else
+ VT = VectorType::get(PN.getType());
+ PHINode *raisedValue = new PHINode(VT, "phi", &PN);
+ for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
+ raisedValue->addIncoming(getRaisedValue(PN.getIncomingValue(i), length),
+ PN.getIncomingBlock(i));
+ setRaisedValue(&PN, raisedValue);
+ addUsesToWorklist(&PN);
+}
+
+/// Get the raised type for a given scalar type or pointer to scalar
+/// type and vector length. Vector length of 0 means a non-fixed
+/// length vector.
+///
+const Type *RaiseVectors::getRaisedType(const Type* Ty, unsigned length) {
+ unsigned i = 0;
+ while (isa<PointerType>(Ty)) {
+ Ty = cast<PointerType>(Ty)->getElementType();
+ ++i;
+ }
+ const Type *result =
+ (length == 0) ? VectorType::get(Ty) : FixedVectorType::get(Ty, length);
+ while (i-- > 0) {
+ result = PointerType::get(result);
+ }
+ return result;
+}
+
+/// Get the (fixed) vector length of a raised instruction. Return 0
+/// if the vector is not a fixed-length vector.
+///
+unsigned RaiseVectors::getVectorLength(Instruction *I) {
+ for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
+ OI != OE; ++OI) {
+ if (Value *val = raisingMap[*OI]) {
+ const Type *Ty = val->getType();
+ while (isa<PointerType>(Ty))
+ Ty = cast<PointerType>(Ty)->getElementType();
+ if (const FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty))
+ return VT->getNumElements();
+ return 0;
}
}
+ assert(0 && "Instruction has no raised operands!");
+}
+/// Add the specified pair to the raising map, replacing dummy uses
+/// if necessary
+///
+void RaiseVectors::setRaisedValue(Instruction *key, Value *newValue) {
+ if (!newValue)
+ return;
+ Value*& oldValue = raisingMap[key];
+ if (oldValue) {
+ if (oldValue->getType() != newValue->getType())
+ newValue = new CastInst(oldValue, newValue->getType(), "cast", key);
+ oldValue->replaceAllUsesWith(newValue);
+ delete oldValue;
+ }
+ oldValue = newValue;
}
+
+/// Get the value for the specified key from the raising map. If no
+/// value is there, we haven't raised the value yet, so create a
+/// dummy value with the appropriate vector length and replace it
+/// when the value is raised.
+///
+Value *RaiseVectors::getRaisedValue(Value *key, unsigned length) {
+ const Type *Ty = getRaisedType(key->getType(), length);
+ Value*& Val = raisingMap[key];
+ if (!Val) {
+ Val = Ty ? new Argument(Ty) : new Argument(VectorType::get(key->getType()));
+ DEBUG(std::cerr << "Created dummy value " << *Val << "\n");
+ }
+ return Val;
+}
+
+/// Get the raised operand of an instruction
+///
+Value *RaiseVectors::getRaisedOperand(Instruction *I, unsigned i) {
+ Value *op = I->getOperand(i);
+ unsigned length = getVectorLength(I);
+ return getRaisedValue(op, length);
+}
+
+/// Add all uses of an instruction to the worklist
+///
+void RaiseVectors::addUsesToWorklist(Instruction *I) {
+ DEBUG(std::cerr << "Adding uses of " << *I);
+ for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
+ UI != UE; ++UI) {
+ if (Instruction *II = dyn_cast<Instruction>(*UI)) {
+ DEBUG(std::cerr << "Adding " << *II);
+ workList.push_back(II);
+ }
+ }
+}
+
+
+
Index: llvm/lib/Transforms/Vector/SSE.cpp
diff -u llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.2 llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.3
--- llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005
+++ llvm/lib/Transforms/Vector/SSE.cpp Wed Nov 16 12:32:56 2005
@@ -27,6 +27,7 @@
#include "llvm/ADT/hash_set"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Transforms/Scalar.h"
using namespace llvm;
@@ -516,3 +517,5 @@
}
}
+
+FunctionPass *llvm::createSSEPass() { return new SSE(); }
More information about the llvm-commits
mailing list