1818#include " llvm/ADT/PostOrderIterator.h"
1919#include " llvm/ADT/SmallVector.h"
2020#include " llvm/ADT/Twine.h"
21+ #include " llvm/Analysis/TargetTransformInfo.h"
2122#include " llvm/Analysis/VectorUtils.h"
2223#include " llvm/IR/Argument.h"
2324#include " llvm/IR/BasicBlock.h"
@@ -281,17 +282,20 @@ T getWithDefaultOverride(const cl::opt<T> &ClOption,
281282
282283class ScalarizerVisitor : public InstVisitor <ScalarizerVisitor, bool > {
283284public:
284- ScalarizerVisitor (DominatorTree *DT, ScalarizerPassOptions Options)
285- : DT(DT), ScalarizeVariableInsertExtract(getWithDefaultOverride(
286- ClScalarizeVariableInsertExtract,
287- Options.ScalarizeVariableInsertExtract)),
285+ ScalarizerVisitor (DominatorTree *DT, const TargetTransformInfo *TTI,
286+ ScalarizerPassOptions Options)
287+ : DT(DT), TTI(TTI), ScalarizeVariableInsertExtract(getWithDefaultOverride(
288+ ClScalarizeVariableInsertExtract,
289+ Options.ScalarizeVariableInsertExtract)),
288290 ScalarizeLoadStore (getWithDefaultOverride(ClScalarizeLoadStore,
289291 Options.ScalarizeLoadStore)),
290292 ScalarizeMinBits(getWithDefaultOverride(ClScalarizeMinBits,
291293 Options.ScalarizeMinBits)) {}
292294
293295 bool visit (Function &F);
294296
297+ bool isTriviallyScalarizable (Intrinsic::ID ID);
298+
295299 // InstVisitor methods. They return true if the instruction was scalarized,
296300 // false if nothing changed.
297301 bool visitInstruction (Instruction &I) { return false ; }
@@ -335,6 +339,7 @@ class ScalarizerVisitor : public InstVisitor<ScalarizerVisitor, bool> {
335339 SmallVector<WeakTrackingVH, 32 > PotentiallyDeadInstrs;
336340
337341 DominatorTree *DT;
342+ const TargetTransformInfo *TTI;
338343
339344 const bool ScalarizeVariableInsertExtract;
340345 const bool ScalarizeLoadStore;
@@ -358,6 +363,7 @@ ScalarizerLegacyPass::ScalarizerLegacyPass(const ScalarizerPassOptions &Options)
358363
359364void ScalarizerLegacyPass::getAnalysisUsage (AnalysisUsage &AU) const {
360365 AU.addRequired <DominatorTreeWrapperPass>();
366+ AU.addRequired <TargetTransformInfoWrapperPass>();
361367 AU.addPreserved <DominatorTreeWrapperPass>();
362368}
363369
@@ -445,7 +451,9 @@ bool ScalarizerLegacyPass::runOnFunction(Function &F) {
445451 return false ;
446452
447453 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
448- ScalarizerVisitor Impl (DT, Options);
454+ const TargetTransformInfo *TTI =
455+ &getAnalysis<TargetTransformInfoWrapperPass>().getTTI (F);
456+ ScalarizerVisitor Impl (DT, TTI, Options);
449457 return Impl.visit (F);
450458}
451459
@@ -689,8 +697,11 @@ bool ScalarizerVisitor::splitBinary(Instruction &I, const Splitter &Split) {
689697 return true ;
690698}
691699
692- static bool isTriviallyScalariable (Intrinsic::ID ID) {
693- return isTriviallyVectorizable (ID);
700+ bool ScalarizerVisitor::isTriviallyScalarizable (Intrinsic::ID ID) {
701+ if (isTriviallyVectorizable (ID))
702+ return true ;
703+ return Function::isTargetIntrinsic (ID) &&
704+ TTI->isTargetIntrinsicTriviallyScalarizable (ID);
694705}
695706
696707// / If a call to a vector typed intrinsic function, split into a scalar call per
@@ -705,7 +716,8 @@ bool ScalarizerVisitor::splitCall(CallInst &CI) {
705716 return false ;
706717
707718 Intrinsic::ID ID = F->getIntrinsicID ();
708- if (ID == Intrinsic::not_intrinsic || !isTriviallyScalariable (ID))
719+
720+ if (ID == Intrinsic::not_intrinsic || !isTriviallyScalarizable (ID))
709721 return false ;
710722
711723 // unsigned NumElems = VT->getNumElements();
@@ -1249,7 +1261,8 @@ bool ScalarizerVisitor::finish() {
12491261
12501262PreservedAnalyses ScalarizerPass::run (Function &F, FunctionAnalysisManager &AM) {
12511263 DominatorTree *DT = &AM.getResult <DominatorTreeAnalysis>(F);
1252- ScalarizerVisitor Impl (DT, Options);
1264+ const TargetTransformInfo *TTI = &AM.getResult <TargetIRAnalysis>(F);
1265+ ScalarizerVisitor Impl (DT, TTI, Options);
12531266 bool Changed = Impl.visit (F);
12541267 PreservedAnalyses PA;
12551268 PA.preserve <DominatorTreeAnalysis>();
0 commit comments