{
public:
typedef hash_map<std::string, Function*> FunctionSet;
- typedef std::pair<void*, uint32_t> ValueIndex;
/*! Create an empty unit */
Unit(PointerSize pointerSize = POINTER_32_BITS);
/*! Release everything (*including* the function pointers) */
ConstantSet& getConstantSet(void) { return constantSet; }
/*! Return the constant set */
const ConstantSet& getConstantSet(void) const { return constantSet; }
-
- /*! Some values will not be allocated. For example a vector extract and
- * a vector insertion when scalarize the vector load/store
- */
- void newValueProxy(void *real,
- void *fake,
- uint32_t realIndex = 0u,
- uint32_t fakeIndex = 0u) {
- const ValueIndex key(fake, fakeIndex);
- const ValueIndex value(real, realIndex);
- GBE_ASSERT(valueMap.find(key) == valueMap.end()); // Do not insert twice
- valueMap[key] = value;
- }
-
- void clearValueMap() { valueMap.clear(); }
-
- /*! Return the value map */
- const map<ValueIndex, ValueIndex> &getValueMap(void) const { return valueMap; }
private:
friend class ContextInterface; //!< Can free modify the unit
hash_map<std::string, Function*> functions; //!< All the defined functions
ConstantSet constantSet; //!< All the constants defined in the unit
PointerSize pointerSize; //!< Size shared by all pointers
- map<ValueIndex, ValueIndex> valueMap; //!< fake to real value map for vector load/store
GBE_CLASS(Unit);
};
GBE_ASSERT(valueMap.find(key) == valueMap.end()); // Do not insert twice
valueMap[key] = value;
}
- /*! After scalarize pass, there are some valueMap in unit,
- * use this function to copy from unit valueMap */
- void initValueMap(const map<ir::Unit::ValueIndex, ir::Unit::ValueIndex> &vMap) {
- for(auto &it : vMap)
- newValueProxy((Value*)it.second.first, (Value*)it.first.first,
- it.second.second, it.first.second);
- }
/*! Mostly used for the preallocated registers (lids, gids) */
void newScalarProxy(ir::Register reg, Value *value, uint32_t index = 0u) {
const ValueIndex key(value, index);
ctx.startFunction(F.getName());
this->regTranslator.clear();
- this->regTranslator.initValueMap(unit.getValueMap());
this->labelMap.clear();
this->emitFunctionPrototype(F);
/*! Because there are still fake insert/extract instruction for
* load/store, so keep empty function here */
void GenWriter::regAllocateInsertElement(InsertElementInst &I) {}
- void GenWriter::emitInsertElement(InsertElementInst &I) {}
+ void GenWriter::emitInsertElement(InsertElementInst &I) {
+ const VectorType *type = dyn_cast<VectorType>(I.getType());
+ GBE_ASSERT(type);
+ const int elemNum = type->getNumElements();
+
+ Value *vec = I.getOperand(0);
+ Value *value = I.getOperand(1);
+ const Value *index = I.getOperand(2);
+ const ConstantInt *c = dyn_cast<ConstantInt>(index);
+ int i = c->getValue().getSExtValue();
+
+ for(int j=0; j<elemNum; j++) {
+ if(i == j)
+ regTranslator.newValueProxy(value, &I, 0, i);
+ else
+ regTranslator.newValueProxy(vec, &I, j, j);
+ }
+ }
void GenWriter::regAllocateExtractElement(ExtractElementInst &I) {}
- void GenWriter::emitExtractElement(ExtractElementInst &I) {}
+ void GenWriter::emitExtractElement(ExtractElementInst &I) {
+ Value *vec = I.getVectorOperand();
+ const Value *index = I.getIndexOperand();
+ const ConstantInt *c = dyn_cast<ConstantInt>(index);
+ GBE_ASSERT(c);
+ int i = c->getValue().getSExtValue();
+ regTranslator.newValueProxy(vec, &I, i, 0);
+ }
void GenWriter::regAllocateShuffleVectorInst(ShuffleVectorInst &I) {}
void GenWriter::emitShuffleVectorInst(ShuffleVectorInst &I) {}
/*! Remove the GEP instructions */
llvm::BasicBlockPass *createRemoveGEPPass(const ir::Unit &unit);
- llvm::FunctionPass* createScalarizePass(ir::Unit &unit);
+ llvm::FunctionPass* createScalarizePass();
} /* namespace gbe */
#include "llvm/Support/raw_ostream.h"
#include "llvm/llvm_gen_backend.hpp"
-#include "ir/unit.hpp"
#include "sys/map.hpp"
// Standard pass stuff
static char ID;
- Scalarize(ir::Unit& unit) : FunctionPass(ID), unit(unit)
+ Scalarize() : FunctionPass(ID)
{
initializeLoopInfoPass(*PassRegistry::getPassRegistry());
initializeDominatorTreePass(*PassRegistry::getPassRegistry());
Type* intTy;
Type* floatTy;
- ir::Unit &unit;
std::vector<Instruction*> deadList;
Value *cv = ConstantInt::get(intTy, i);
Value *EI = builder->CreateExtractElement(insn, cv);
vVals.setComponent(i, EI);
- //unit.fakeInsnMap[EI] = insn;
- unit.newValueProxy(insn, EI, i, 0);
}
}
Value* Scalarize::InsertToVector(Value * insn, Value* vecValue) {
//VectorValues& vVals = vectorVals[writeValue];
- //unit.vecValuesMap[call] = vectorVals[writeValue];
//add fake insert instructions to avoid removed
Value *II = NULL;
Value *vec = II ? II : UndefValue::get(vecValue->getType());
Value *cv = ConstantInt::get(intTy, i);
II = builder->CreateInsertElement(vec, getComponent(i, vecValue), cv);
- //unit.vecValuesMap[insn].setComponent(i, getComponent(i, writeValue));
- //unit.newValueProxy(getComponent(i, vecValue), vecValue, 0, i);
- //unit.fakeInsnMap[II] = insn;
}
- for (int i = 0; i < GetComponentCount(vecValue); ++i) {
- unit.newValueProxy(getComponent(i, vecValue), II, 0, i);
- }
return II;
}
intTy = IntegerType::get(module->getContext(), 32);
floatTy = Type::getFloatTy(module->getContext());
builder = new IRBuilder<>(module->getContext());
- unit.clearValueMap();
scalarizeArgs(F);
typedef ReversePostOrderTraversal<Function*> RPOTType;
{
return;
}
- FunctionPass* createScalarizePass(ir::Unit &unit)
+ FunctionPass* createScalarizePass()
{
- return new Scalarize(unit);
+ return new Scalarize();
}
char Scalarize::ID = 0;
// Print the code before further optimizations
if (OCL_OUTPUT_LLVM_BEFORE_EXTRA_PASS)
passes.add(createPrintModulePass(&*o));
- passes.add(createScalarizePass(unit)); // Expand all vector ops
+ passes.add(createScalarizePass()); // Expand all vector ops
passes.add(createScalarReplAggregatesPass()); // Break up allocas
passes.add(createRemoveGEPPass(unit));
passes.add(createConstantPropagationPass());