Mercurial > hg > CbC > CbC_llvm
comparison polly/lib/Support/ScopHelper.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 79ff65ed7e25 |
children | 1f2b6ac9f198 |
comparison
equal
deleted
inserted
replaced
232:70dce7da266c | 236:c4bab56944e8 |
---|---|
25 using namespace llvm; | 25 using namespace llvm; |
26 using namespace polly; | 26 using namespace polly; |
27 | 27 |
28 #define DEBUG_TYPE "polly-scop-helper" | 28 #define DEBUG_TYPE "polly-scop-helper" |
29 | 29 |
30 static cl::opt<bool> PollyAllowErrorBlocks( | |
31 "polly-allow-error-blocks", | |
32 cl::desc("Allow to speculate on the execution of 'error blocks'."), | |
33 cl::Hidden, cl::init(true), cl::ZeroOrMore, cl::cat(PollyCategory)); | |
34 | |
35 static cl::list<std::string> DebugFunctions( | 30 static cl::list<std::string> DebugFunctions( |
36 "polly-debug-func", | 31 "polly-debug-func", |
37 cl::desc("Allow calls to the specified functions in SCoPs even if their " | 32 cl::desc("Allow calls to the specified functions in SCoPs even if their " |
38 "side-effects are unknown. This can be used to do debug output in " | 33 "side-effects are unknown. This can be used to do debug output in " |
39 "Polly-transformed code."), | 34 "Polly-transformed code."), |
40 cl::Hidden, cl::ZeroOrMore, cl::CommaSeparated, cl::cat(PollyCategory)); | 35 cl::Hidden, cl::CommaSeparated, cl::cat(PollyCategory)); |
41 | 36 |
42 // Ensures that there is just one predecessor to the entry node from outside the | 37 // Ensures that there is just one predecessor to the entry node from outside the |
43 // region. | 38 // region. |
44 // The identity of the region entry node is preserved. | 39 // The identity of the region entry node is preserved. |
45 static void simplifyRegionEntry(Region *R, DominatorTree *DT, LoopInfo *LI, | 40 static void simplifyRegionEntry(Region *R, DominatorTree *DT, LoopInfo *LI, |
236 /// instruction but just use it, if it is referenced as a SCEVUnknown. We want | 231 /// instruction but just use it, if it is referenced as a SCEVUnknown. We want |
237 /// however to generate new code if the instruction is in the analyzed region | 232 /// however to generate new code if the instruction is in the analyzed region |
238 /// and we generate code outside/in front of that region. Hence, we generate the | 233 /// and we generate code outside/in front of that region. Hence, we generate the |
239 /// code for the SDiv/SRem operands in front of the analyzed region and then | 234 /// code for the SDiv/SRem operands in front of the analyzed region and then |
240 /// create a new SDiv/SRem operation there too. | 235 /// create a new SDiv/SRem operation there too. |
241 struct ScopExpander : SCEVVisitor<ScopExpander, const SCEV *> { | 236 struct ScopExpander final : SCEVVisitor<ScopExpander, const SCEV *> { |
242 friend struct SCEVVisitor<ScopExpander, const SCEV *>; | 237 friend struct SCEVVisitor<ScopExpander, const SCEV *>; |
243 | 238 |
244 explicit ScopExpander(const Region &R, ScalarEvolution &SE, | 239 explicit ScopExpander(const Region &R, ScalarEvolution &SE, |
245 const DataLayout &DL, const char *Name, ValueMapT *VMap, | 240 const DataLayout &DL, const char *Name, ValueMapT *VMap, |
246 BasicBlock *RTCBB) | 241 BasicBlock *RTCBB) |
394 SmallVector<const SCEV *, 4> NewOps; | 389 SmallVector<const SCEV *, 4> NewOps; |
395 for (const SCEV *Op : E->operands()) | 390 for (const SCEV *Op : E->operands()) |
396 NewOps.push_back(visit(Op)); | 391 NewOps.push_back(visit(Op)); |
397 return SE.getSMinExpr(NewOps); | 392 return SE.getSMinExpr(NewOps); |
398 } | 393 } |
394 const SCEV *visitSequentialUMinExpr(const SCEVSequentialUMinExpr *E) { | |
395 SmallVector<const SCEV *, 4> NewOps; | |
396 for (const SCEV *Op : E->operands()) | |
397 NewOps.push_back(visit(Op)); | |
398 return SE.getUMinExpr(NewOps, /*Sequential=*/true); | |
399 } | |
399 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) { | 400 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) { |
400 SmallVector<const SCEV *, 4> NewOps; | 401 SmallVector<const SCEV *, 4> NewOps; |
401 for (const SCEV *Op : E->operands()) | 402 for (const SCEV *Op : E->operands()) |
402 NewOps.push_back(visit(Op)); | 403 NewOps.push_back(visit(Op)); |
403 return SE.getAddRecExpr(NewOps, E->getLoop(), E->getNoWrapFlags()); | 404 return SE.getAddRecExpr(NewOps, E->getLoop(), E->getNoWrapFlags()); |
409 const char *Name, const SCEV *E, Type *Ty, | 410 const char *Name, const SCEV *E, Type *Ty, |
410 Instruction *IP, ValueMapT *VMap, | 411 Instruction *IP, ValueMapT *VMap, |
411 BasicBlock *RTCBB) { | 412 BasicBlock *RTCBB) { |
412 ScopExpander Expander(S.getRegion(), SE, DL, Name, VMap, RTCBB); | 413 ScopExpander Expander(S.getRegion(), SE, DL, Name, VMap, RTCBB); |
413 return Expander.expandCodeFor(E, Ty, IP); | 414 return Expander.expandCodeFor(E, Ty, IP); |
414 } | |
415 | |
416 bool polly::isErrorBlock(BasicBlock &BB, const Region &R, LoopInfo &LI, | |
417 const DominatorTree &DT) { | |
418 if (!PollyAllowErrorBlocks) | |
419 return false; | |
420 | |
421 if (isa<UnreachableInst>(BB.getTerminator())) | |
422 return true; | |
423 | |
424 if (LI.isLoopHeader(&BB)) | |
425 return false; | |
426 | |
427 // Basic blocks that are always executed are not considered error blocks, | |
428 // as their execution can not be a rare event. | |
429 bool DominatesAllPredecessors = true; | |
430 if (R.isTopLevelRegion()) { | |
431 for (BasicBlock &I : *R.getEntry()->getParent()) | |
432 if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I)) | |
433 DominatesAllPredecessors = false; | |
434 } else { | |
435 for (auto Pred : predecessors(R.getExit())) | |
436 if (R.contains(Pred) && !DT.dominates(&BB, Pred)) | |
437 DominatesAllPredecessors = false; | |
438 } | |
439 | |
440 if (DominatesAllPredecessors) | |
441 return false; | |
442 | |
443 for (Instruction &Inst : BB) | |
444 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) { | |
445 if (isDebugCall(CI)) | |
446 continue; | |
447 | |
448 if (isIgnoredIntrinsic(CI)) | |
449 continue; | |
450 | |
451 // memset, memcpy and memmove are modeled intrinsics. | |
452 if (isa<MemSetInst>(CI) || isa<MemTransferInst>(CI)) | |
453 continue; | |
454 | |
455 if (!CI->doesNotAccessMemory()) | |
456 return true; | |
457 if (CI->doesNotReturn()) | |
458 return true; | |
459 } | |
460 | |
461 return false; | |
462 } | 415 } |
463 | 416 |
464 Value *polly::getConditionFromTerminator(Instruction *TI) { | 417 Value *polly::getConditionFromTerminator(Instruction *TI) { |
465 if (BranchInst *BR = dyn_cast<BranchInst>(TI)) { | 418 if (BranchInst *BR = dyn_cast<BranchInst>(TI)) { |
466 if (BR->isUnconditional()) | 419 if (BR->isUnconditional()) |
792 } | 745 } |
793 llvm_unreachable("unexpected number of options"); | 746 llvm_unreachable("unexpected number of options"); |
794 } | 747 } |
795 | 748 |
796 bool polly::getBooleanLoopAttribute(MDNode *LoopID, StringRef Name) { | 749 bool polly::getBooleanLoopAttribute(MDNode *LoopID, StringRef Name) { |
797 return getOptionalBoolLoopAttribute(LoopID, Name).getValueOr(false); | 750 return getOptionalBoolLoopAttribute(LoopID, Name).value_or(false); |
798 } | 751 } |
799 | 752 |
800 llvm::Optional<int> polly::getOptionalIntLoopAttribute(MDNode *LoopID, | 753 llvm::Optional<int> polly::getOptionalIntLoopAttribute(MDNode *LoopID, |
801 StringRef Name) { | 754 StringRef Name) { |
802 const MDOperand *AttrMD = | 755 const MDOperand *AttrMD = |
803 findNamedMetadataArg(LoopID, Name).getValueOr(nullptr); | 756 findNamedMetadataArg(LoopID, Name).value_or(nullptr); |
804 if (!AttrMD) | 757 if (!AttrMD) |
805 return None; | 758 return None; |
806 | 759 |
807 ConstantInt *IntMD = mdconst::extract_or_null<ConstantInt>(AttrMD->get()); | 760 ConstantInt *IntMD = mdconst::extract_or_null<ConstantInt>(AttrMD->get()); |
808 if (!IntMD) | 761 if (!IntMD) |