From 7b0eb0e4ad4d9e95468b6a18e8a03cff51f54dca Mon Sep 17 00:00:00 2001 From: Vsevolod Livinskiy Date: Thu, 19 Feb 2015 17:22:17 +0300 Subject: [PATCH 1/3] Smear optimization was changed --- cbackend.cpp | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/cbackend.cpp b/cbackend.cpp index a6670bfb..49305a57 100644 --- a/cbackend.cpp +++ b/cbackend.cpp @@ -4625,7 +4625,7 @@ SmearCleanupPass::getInsertChainSmearValue(llvm::Instruction* inst) const { if (!insertInst) { return NULL; } - + // We consider only chians of vectorWidth length. if (ChainLength(insertInst) != vectorWidth) { return NULL; @@ -4669,14 +4669,18 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { return NULL; } + fprintf(stderr, "getShuffleSmearValue\n"); + shuffleInst->dump(); + llvm::Constant* mask = llvm::dyn_cast(shuffleInst->getOperand(2)); // Check that the shuffle is a broadcast of the first element of the first vector, - // i.e. mask vector is all-zeros vector of expected size. + // i.e. mask vector is all-zeros vector of expected size. if (!(mask && - mask->isNullValue() && + (mask->isNullValue() || (shuffleInst->getMask()->getSplatValue() != 0))&& llvm::dyn_cast(mask->getType())->getNumElements() == vectorWidth)) { + fprintf(stderr, "getShuffleSmearValue: mask\n"); return NULL; } @@ -4685,13 +4689,40 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { llvm::dyn_cast(shuffleInst->getOperand(0)); // Check that it's an InsertElementInst that inserts a value to first element. + llvm::Value *result = shuffleInst->getOperand(0); + if (!(insertInst && llvm::isa(insertInst->getOperand(2)) && llvm::dyn_cast(insertInst->getOperand(2))->isNullValue())) { - return NULL; + fprintf(stderr, "getShuffleSmearValue: inst\n"); + + llvm::Function *extractFunc = module->getFunction("__extract_element"); + + if (extractFunc == NULL) { + // Declare the __extract_element function if needed; it takes a vector and + // a scalar parameter and returns a scalar of the vector parameter type. + llvm::Constant *ef = + module->getOrInsertFunction("__extract_element", + shuffleInst->getOperand(0)->getType()->getVectorElementType(), + shuffleInst->getOperand(0)->getType(), + llvm::IntegerType::get(module->getContext(), 32), NULL); + fprintf(stderr, "getShuffleSmearValue: getOrInsertFunction\n"); + extractFunc = llvm::dyn_cast(ef); + assert(extractFunc != NULL); + extractFunc->setDoesNotThrow(); + extractFunc->setOnlyReadsMemory(); + } + + if (extractFunc == NULL) { + fprintf(stderr, "getShuffleSmearValue: no function in module\n"); + return NULL; + } + fprintf(stderr, "getShuffleSmearValue: function was found\n"); + llvm::Instruction *extractCall = llvm::ExtractElementInst::Create(shuffleInst->getOperand(0), mask->getSplatValue(), "__extract_element", inst); + return extractCall; } - llvm::Value *result = insertInst->getOperand(1); + result = insertInst->getOperand(1); return result; } @@ -4710,11 +4741,15 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) { continue; } + fprintf(stderr, "==========================================================\n"); + llvm::Type *smearType = smearValue->getType(); const char *smearFuncName = lGetTypedFunc("smear", smearType, vectorWidth); + fprintf(stderr, "smearFuncName: %s | %d\n", smearFuncName, smearFuncName != NULL); if (smearFuncName != NULL) { llvm::Function *smearFunc = module->getFunction(smearFuncName); if (smearFunc == NULL) { + fprintf(stderr, "Smear decl\n"); // Declare the smear function if needed; it takes a single // scalar parameter and returns a vector of the same // parameter type. From 8c4d339f25cebffd556e3f0e8c27834e36ed297f Mon Sep 17 00:00:00 2001 From: Vsevolod Livinskiy Date: Fri, 20 Feb 2015 16:50:53 +0300 Subject: [PATCH 2/3] Some codestyle changes --- cbackend.cpp | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/cbackend.cpp b/cbackend.cpp index 49305a57..fef86b60 100644 --- a/cbackend.cpp +++ b/cbackend.cpp @@ -4625,7 +4625,7 @@ SmearCleanupPass::getInsertChainSmearValue(llvm::Instruction* inst) const { if (!insertInst) { return NULL; } - + // We consider only chians of vectorWidth length. if (ChainLength(insertInst) != vectorWidth) { return NULL; @@ -4669,18 +4669,14 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { return NULL; } - fprintf(stderr, "getShuffleSmearValue\n"); - shuffleInst->dump(); - llvm::Constant* mask = llvm::dyn_cast(shuffleInst->getOperand(2)); - // Check that the shuffle is a broadcast of the first element of the first vector, - // i.e. mask vector is all-zeros vector of expected size. + // Check that the shuffle is a broadcast of the element of the first vector, + // i.e. mask vector is vector with equal elements of expected size. if (!(mask && (mask->isNullValue() || (shuffleInst->getMask()->getSplatValue() != 0))&& llvm::dyn_cast(mask->getType())->getNumElements() == vectorWidth)) { - fprintf(stderr, "getShuffleSmearValue: mask\n"); return NULL; } @@ -4689,12 +4685,11 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { llvm::dyn_cast(shuffleInst->getOperand(0)); // Check that it's an InsertElementInst that inserts a value to first element. - llvm::Value *result = shuffleInst->getOperand(0); - if (!(insertInst && llvm::isa(insertInst->getOperand(2)) && llvm::dyn_cast(insertInst->getOperand(2))->isNullValue())) { - fprintf(stderr, "getShuffleSmearValue: inst\n"); + + // Insert ExtractElementInstr to get value for smear llvm::Function *extractFunc = module->getFunction("__extract_element"); @@ -4706,7 +4701,6 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { shuffleInst->getOperand(0)->getType()->getVectorElementType(), shuffleInst->getOperand(0)->getType(), llvm::IntegerType::get(module->getContext(), 32), NULL); - fprintf(stderr, "getShuffleSmearValue: getOrInsertFunction\n"); extractFunc = llvm::dyn_cast(ef); assert(extractFunc != NULL); extractFunc->setDoesNotThrow(); @@ -4714,15 +4708,15 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { } if (extractFunc == NULL) { - fprintf(stderr, "getShuffleSmearValue: no function in module\n"); return NULL; } - fprintf(stderr, "getShuffleSmearValue: function was found\n"); - llvm::Instruction *extractCall = llvm::ExtractElementInst::Create(shuffleInst->getOperand(0), mask->getSplatValue(), "__extract_element", inst); + llvm::Instruction *extractCall = + llvm::ExtractElementInst::Create(shuffleInst->getOperand(0), mask->getSplatValue(), + "__extract_element", inst); return extractCall; } - result = insertInst->getOperand(1); + llvm::Value *result = insertInst->getOperand(1); return result; } @@ -4741,15 +4735,11 @@ SmearCleanupPass::runOnBasicBlock(llvm::BasicBlock &bb) { continue; } - fprintf(stderr, "==========================================================\n"); - llvm::Type *smearType = smearValue->getType(); const char *smearFuncName = lGetTypedFunc("smear", smearType, vectorWidth); - fprintf(stderr, "smearFuncName: %s | %d\n", smearFuncName, smearFuncName != NULL); if (smearFuncName != NULL) { llvm::Function *smearFunc = module->getFunction(smearFuncName); if (smearFunc == NULL) { - fprintf(stderr, "Smear decl\n"); // Declare the smear function if needed; it takes a single // scalar parameter and returns a vector of the same // parameter type. From f17deafc0aefdc1607fdd47bfedd6f5e8c4de26b Mon Sep 17 00:00:00 2001 From: Vsevolod Livinskiy Date: Fri, 20 Feb 2015 17:46:06 +0300 Subject: [PATCH 3/3] Some little bug was fixed --- cbackend.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cbackend.cpp b/cbackend.cpp index fef86b60..f99c1bfb 100644 --- a/cbackend.cpp +++ b/cbackend.cpp @@ -4689,6 +4689,11 @@ SmearCleanupPass::getShuffleSmearValue(llvm::Instruction* inst) const { llvm::isa(insertInst->getOperand(2)) && llvm::dyn_cast(insertInst->getOperand(2))->isNullValue())) { + // We can't extract element from vec1 + llvm::VectorType *operandVec = llvm::dyn_cast(shuffleInst->getOperand(0)->getType()); + if (operandVec && operandVec->getNumElements() == 1) + return NULL; + // Insert ExtractElementInstr to get value for smear llvm::Function *extractFunc = module->getFunction("__extract_element");