From 4284049dcc3ddf9cf30f110007641596de4b265c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 31 Jul 2017 09:00:52 +0000 Subject: [PATCH] [LoopInterchange] Do not interchange loops with function calls. Summary: Without any information about the called function, we cannot be sure that it is safe to interchange loops which contain function calls. For example there could be dependences that prevent interchanging between accesses in the called function and the loops. Even functions without any parameters could cause problems, as they could access memory using global pointers. For now, I think it is only safe to interchange loops with calls marked as readnone. With this patch, the LLVM test suite passes with `-O3 -mllvm -enable-loopinterchange` and LoopInterchangeProfitability::isProfitable returning true for all loops. check-llvm and check-clang also pass when bootstrapped in a similar fashion, although only 3 loops got interchanged. Reviewers: karthikthecool, blitz.opensource, hfinkel, mcrosier, mkuper Reviewed By: mcrosier Subscribers: mzolotukhin, llvm-commits Differential Revision: https://reviews.llvm.org/D35489 llvm-svn: 309547 --- .../lib/Transforms/Scalar/LoopInterchange.cpp | 12 ++ .../LoopInterchange/call-instructions.ll | 158 ++++++++++++++++++ .../interchange-flow-dep-outer.ll | 4 +- .../not-interchanged-tightly-nested.ll | 2 +- 4 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/LoopInterchange/call-instructions.ll diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index d4ad66fc9df0..2f05ec2b329b 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -958,6 +958,18 @@ bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId, return false; } + // Check if outer and inner loop contain legal instructions only. + for (auto *BB : OuterLoop->blocks()) + for (Instruction &I : *BB) + if (CallInst *CI = dyn_cast(&I)) { + // readnone functions do not prevent interchanging. + if (CI->doesNotReadMemory()) + continue; + DEBUG(dbgs() << "Loops with call instructions cannot be interchanged " + << "safely."); + return false; + } + // Create unique Preheaders if we already do not have one. BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader(); BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader(); diff --git a/llvm/test/Transforms/LoopInterchange/call-instructions.ll b/llvm/test/Transforms/LoopInterchange/call-instructions.ll new file mode 100644 index 000000000000..e2428ac53fc2 --- /dev/null +++ b/llvm/test/Transforms/LoopInterchange/call-instructions.ll @@ -0,0 +1,158 @@ +; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s +;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@A = common global [100 x [100 x i32]] zeroinitializer + +declare void @foo(i64 %a) +declare void @bar(i64 %a) readnone + +;;--------------------------------------Test case 01------------------------------------ +;; Not safe to interchange, because the called function `foo` is not marked as +;; readnone, so it could introduce dependences. +;; +;; for(int i=0;i