<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>