<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Ugh, you’re right, I somehow managed to typo this. I thought I had written cast_or_null. Fixing.<div class=""><br class=""></div><div class="">Fiona</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 29, 2016, at 3:00 PM, Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com" class="">sanjoy@playingwithpointers.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Fiona Glaser via llvm-commits wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Author: escha<br class="">Date: Fri Jan 29 16:35:36 2016<br class="">New Revision: 259256<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=259256&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=259256&view=rev</a><br class="">Log:<br class="">Add LoopSimplifyCFG pass<br class=""><br class="">Loop transformations can sometimes fail because the loop, while in<br class="">valid rotated LCSSA form, is not in a canonical CFG form. This is<br class="">an extremely simple pass that just merges obviously redundant<br class="">blocks, which can be used to fix some known failure cases. In the<br class="">future, it may be enhanced with more cases (and have code shared with<br class="">SimplifyCFG).<br class=""><br class="">This allows us to run LoopSimplifyCFG -> LoopRotate -> LoopUnroll,<br class="">so that SimplifyCFG cleans up the loop before Rotate tries to run.<br class=""><br class="">Not currently used in the pass manager, since this pass doesn't do<br class="">anything unless you can hook it up in an LPM with other loop passes.<br class="">It'll be added once Chandler cleans up things to allow this.<br class=""><br class="">Tested in a custom pipeline out of tree to confirm it works in<br class="">practice (in addition to the included trivial test).<br class=""><br class="">Added:<br class=""> llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp<br class=""> llvm/trunk/test/Transforms/LoopSimplifyCFG/<br class=""> llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll<br class="">Modified:<br class=""> llvm/trunk/include/llvm/InitializePasses.h<br class=""> llvm/trunk/include/llvm/LinkAllPasses.h<br class=""> llvm/trunk/include/llvm/Transforms/Scalar.h<br class=""> llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt<br class=""> llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br class=""><br class="">Modified: llvm/trunk/include/llvm/InitializePasses.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=259256&r1=259255&r2=259256&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=259256&r1=259255&r2=259256&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/InitializePasses.h (original)<br class="">+++ llvm/trunk/include/llvm/InitializePasses.h Fri Jan 29 16:35:36 2016<br class="">@@ -170,6 +170,7 @@ void initializeLoopInterchangePass(PassR<br class=""> void initializeLoopInstSimplifyPass(PassRegistry&);<br class=""> void initializeLoopRotatePass(PassRegistry&);<br class=""> void initializeLoopSimplifyPass(PassRegistry&);<br class="">+void initializeLoopSimplifyCFGPass(PassRegistry&);<br class=""> void initializeLoopStrengthReducePass(PassRegistry&);<br class=""> void initializeGlobalMergePass(PassRegistry&);<br class=""> void initializeLoopRerollPass(PassRegistry&);<br class=""><br class="">Modified: llvm/trunk/include/llvm/LinkAllPasses.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=259256&r1=259255&r2=259256&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=259256&r1=259255&r2=259256&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/LinkAllPasses.h (original)<br class="">+++ llvm/trunk/include/llvm/LinkAllPasses.h Fri Jan 29 16:35:36 2016<br class="">@@ -106,6 +106,7 @@ namespace {<br class=""> (void) llvm::createLoopExtractorPass();<br class=""> (void) llvm::createLoopInterchangePass();<br class=""> (void) llvm::createLoopSimplifyPass();<br class="">+ (void) llvm::createLoopSimplifyCFGPass();<br class=""> (void) llvm::createLoopStrengthReducePass();<br class=""> (void) llvm::createLoopRerollPass();<br class=""> (void) llvm::createLoopUnrollPass();<br class=""><br class="">Modified: llvm/trunk/include/llvm/Transforms/Scalar.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=259256&r1=259255&r2=259256&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=259256&r1=259255&r2=259256&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/Transforms/Scalar.h (original)<br class="">+++ llvm/trunk/include/llvm/Transforms/Scalar.h Fri Jan 29 16:35:36 2016<br class="">@@ -476,6 +476,13 @@ FunctionPass *createLoopDistributePass()<br class=""> //<br class=""> FunctionPass *createLoopLoadEliminationPass();<br class=""><br class="">+//===----------------------------------------------------------------------===//<br class="">+//<br class="">+// LoopSimplifyCFG - This pass performs basic CFG simplification on loops,<br class="">+// primarily to help other loop passes.<br class="">+//<br class="">+Pass *createLoopSimplifyCFGPass();<br class="">+<br class=""> } // End llvm namespace<br class=""><br class=""> #endif<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=259256&r1=259255&r2=259256&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=259256&r1=259255&r2=259256&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original)<br class="">+++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Fri Jan 29 16:35:36 2016<br class="">@@ -24,6 +24,7 @@ add_llvm_library(LLVMScalarOpts<br class=""> LoopLoadElimination.cpp<br class=""> LoopRerollPass.cpp<br class=""> LoopRotation.cpp<br class="">+ LoopSimplifyCFG.cpp<br class=""> LoopStrengthReduce.cpp<br class=""> LoopUnrollPass.cpp<br class=""> LoopUnswitch.cpp<br class=""><br class="">Added: llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp?rev=259256&view=auto" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp?rev=259256&view=auto</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp (added)<br class="">+++ llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp Fri Jan 29 16:35:36 2016<br class="">@@ -0,0 +1,111 @@<br class="">+//===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===//<br class="">+//<br class="">+// The LLVM Compiler Infrastructure<br class="">+//<br class="">+// This file is distributed under the University of Illinois Open Source<br class="">+// License. See LICENSE.TXT for details.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+//<br class="">+// This file implements the Loop SimplifyCFG Pass. This pass is responsible for<br class="">+// basic loop CFG cleanup, primarily to assist other loop passes. If you<br class="">+// encounter a noncanonical CFG construct that causes another loop pass to<br class="">+// perform suboptimally, this is the place to fix it up.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+#include "llvm/Transforms/Scalar.h"<br class="">+#include "llvm/ADT/SmallVector.h"<br class="">+#include "llvm/ADT/Statistic.h"<br class="">+#include "llvm/Analysis/AliasAnalysis.h"<br class="">+#include "llvm/Analysis/BasicAliasAnalysis.h"<br class="">+#include "llvm/Analysis/AssumptionCache.h"<br class="">+#include "llvm/Analysis/DependenceAnalysis.h"<br class="">+#include "llvm/Analysis/GlobalsModRef.h"<br class="">+#include "llvm/Analysis/LoopInfo.h"<br class="">+#include "llvm/Analysis/LoopPass.h"<br class="">+#include "llvm/Analysis/ScalarEvolution.h"<br class="">+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"<br class="">+#include "llvm/Analysis/TargetTransformInfo.h"<br class="">+#include "llvm/IR/Dominators.h"<br class="">+#include "llvm/Transforms/Utils/Local.h"<br class="">+using namespace llvm;<br class="">+<br class="">+#define DEBUG_TYPE "loop-simplifycfg"<br class="">+<br class="">+namespace {<br class="">+class LoopSimplifyCFG : public LoopPass {<br class="">+public:<br class="">+ static char ID; // Pass ID, replacement for typeid<br class="">+ LoopSimplifyCFG() : LoopPass(ID) {<br class="">+ initializeLoopSimplifyCFGPass(*PassRegistry::getPassRegistry());<br class="">+ }<br class="">+<br class="">+ bool runOnLoop(Loop *L, LPPassManager&) override;<br class="">+<br class="">+ void getAnalysisUsage(AnalysisUsage&AU) const override {<br class="">+ AU.addRequired<DominatorTreeWrapperPass>();<br class="">+ AU.addRequired<LoopInfoWrapperPass>();<br class="">+<br class="">+ AU.addPreserved<DominatorTreeWrapperPass>();<br class="">+ AU.addPreserved<LoopInfoWrapperPass>();<br class="">+ AU.addPreserved<GlobalsAAWrapperPass>();<br class="">+ AU.addPreserved<BasicAAWrapperPass>();<br class="">+ AU.addPreserved<AAResultsWrapperPass>();<br class="">+ AU.addPreserved<ScalarEvolutionWrapperPass>();<br class="">+ AU.addPreserved<SCEVAAWrapperPass>();<br class="">+ AU.addPreserved<DependenceAnalysis>();<br class="">+ AU.addPreservedID(LoopSimplifyID);<br class="">+ AU.addPreservedID(LCSSAID);<br class="">+ }<br class="">+};<br class="">+}<br class="">+<br class="">+char LoopSimplifyCFG::ID = 0;<br class="">+INITIALIZE_PASS_BEGIN(LoopSimplifyCFG, "loop-simplifycfg", "Simplify loop CFG",<br class="">+ false, false)<br class="">+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)<br class="">+INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)<br class="">+INITIALIZE_PASS_END(LoopSimplifyCFG, "loop-simplifycfg", "Simplify loop CFG",<br class="">+ false, false)<br class="">+<br class="">+Pass *llvm::createLoopSimplifyCFGPass() { return new LoopSimplifyCFG(); }<br class="">+<br class="">+static bool simplifyLoopCFG(Loop *L, DominatorTree *DT, LoopInfo *LI) {<br class="">+ bool Changed = false;<br class="">+ // Copy blocks into a temporary array to avoid iterator invalidation issues<br class="">+ // as we remove them.<br class="">+ SmallVector<WeakVH, 16> Blocks(L->blocks());<br class="">+<br class="">+ for (auto&Block : Blocks) {<br class="">+ // Attempt to merge blocks in the trivial case. Don't modify blocks which<br class="">+ // belong to other loops.<br class="">+ BasicBlock *Succ = cast<BasicBlock>(Block);<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">cast<> does not allow a null argument, I think you want cast_or_null<> here.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">+ if (!Succ)<br class="">+ continue;<br class="">+<br class="">+ BasicBlock *Pred = Succ->getSinglePredecessor();<br class="">+ if (!Pred || !Pred->getSingleSuccessor() || LI->getLoopFor(Pred) != L)<br class="">+ continue;<br class="">+<br class="">+ // Pred is going to disappear, so we need to update the loop info.<br class="">+ if (L->getHeader() == Pred)<br class="">+ L->moveToHeader(Succ);<br class="">+ LI->removeBlock(Pred);<br class="">+ MergeBasicBlockIntoOnlyPred(Succ, DT);<br class="">+ Changed = true;<br class="">+ }<br class="">+<br class="">+ return Changed;<br class="">+}<br class="">+<br class="">+/// runOnLoop - Perform basic CFG simplifications to assist other loop passes.<br class="">+/// For now, this only attempts to merge blocks in the trivial case.<br class="">+bool LoopSimplifyCFG::runOnLoop(Loop *L, LPPassManager&) {<br class="">+ if (skipOptnoneFunction(L))<br class="">+ return false;<br class="">+<br class="">+ DominatorTree *DT =&getAnalysis<DominatorTreeWrapperPass>().getDomTree();<br class="">+ LoopInfo *LI =&getAnalysis<LoopInfoWrapperPass>().getLoopInfo();<br class="">+ return simplifyLoopCFG(L, DT, LI);<br class="">+}<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=259256&r1=259255&r2=259256&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=259256&r1=259255&r2=259256&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)<br class="">+++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Fri Jan 29 16:35:36 2016<br class="">@@ -84,6 +84,7 @@ void llvm::initializeScalarOpts(PassRegi<br class=""> initializeFloat2IntPass(Registry);<br class=""> initializeLoopDistributePass(Registry);<br class=""> initializeLoopLoadEliminationPass(Registry);<br class="">+ initializeLoopSimplifyCFGPass(Registry);<br class=""> }<br class=""><br class=""> void LLVMInitializeScalarOpts(LLVMPassRegistryRef R) {<br class="">@@ -154,6 +155,10 @@ void LLVMAddLoopRerollPass(LLVMPassManag<br class=""> unwrap(PM)->add(createLoopRerollPass());<br class=""> }<br class=""><br class="">+void LLVMAddLoopSimplifyCFGPass(LLVMPassManagerRef PM) {<br class="">+ unwrap(PM)->add(createLoopSimplifyCFGPass());<br class="">+}<br class="">+<br class=""> void LLVMAddLoopUnrollPass(LLVMPassManagerRef PM) {<br class=""> unwrap(PM)->add(createLoopUnrollPass());<br class=""> }<br class=""><br class="">Added: llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll?rev=259256&view=auto" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll?rev=259256&view=auto</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll (added)<br class="">+++ llvm/trunk/test/Transforms/LoopSimplifyCFG/merge-header.ll Fri Jan 29 16:35:36 2016<br class="">@@ -0,0 +1,34 @@<br class="">+; RUN: opt -S -loop-simplifycfg< %s | FileCheck %s<br class="">+<br class="">+; CHECK-LABEL: foo<br class="">+; CHECK: entry:<br class="">+; CHECK-NEXT: br label %[[LOOP:[a-z]+]]<br class="">+; CHECK: [[LOOP]]:<br class="">+; CHECK-NEXT: phi<br class="">+; CHECK-NOT: br label<br class="">+; CHECK: br i1<br class="">+define i32 @foo(i32* %P, i64* %Q) {<br class="">+entry:<br class="">+ br label %outer<br class="">+<br class="">+outer: ; preds = %outer.latch2, %entry<br class="">+ %y.2 = phi i32 [ 0, %entry ], [ %y.inc2, %outer.latch2 ]<br class="">+ br label %inner<br class="">+<br class="">+inner: ; preds = %outer<br class="">+ store i32 0, i32* %P<br class="">+ store i32 1, i32* %P<br class="">+ store i32 2, i32* %P<br class="">+ %y.inc2 = add nsw i32 %y.2, 1<br class="">+ %exitcond.outer = icmp eq i32 %y.inc2, 3<br class="">+ store i32 %y.2, i32* %P<br class="">+ br i1 %exitcond.outer, label %exit, label %outer.latch2<br class="">+<br class="">+outer.latch2: ; preds = %inner<br class="">+ %t = sext i32 %y.inc2 to i64<br class="">+ store i64 %t, i64* %Q<br class="">+ br label %outer<br class="">+<br class="">+exit: ; preds = %inner<br class="">+ ret i32 0<br class="">+}<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</blockquote></div></blockquote></div><br class=""></div></body></html>