CodeGen: Allow function parameters to be rewritten in getNewValue()
When deriving new values for the statements of a SCoP, we assumed that parameter values are constant within the SCoP and consquently do not need to be rewritten. For OpenMP code generation this assumption is wrong, as such values are not available in the OpenMP subfunction and consequently also may need to be rewritten. Committed with some changes. Contributed-By: Johannes Doerfert <s9jodoer@stud.uni-saarland.de> llvm-svn: 153838
This commit is contained in:
parent
12af4285d1
commit
89339067b0
|
@ -283,12 +283,11 @@ BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
|
|||
|
||||
Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
|
||||
ValueMapT &GlobalMap) {
|
||||
const Instruction *Inst = dyn_cast<Instruction>(Old);
|
||||
|
||||
if (!Inst)
|
||||
// We assume constants never change.
|
||||
// This avoids map lookups for many calls to this function.
|
||||
if (isa<Constant>(Old))
|
||||
return const_cast<Value*>(Old);
|
||||
|
||||
// OldOperand was redefined outside of this BasicBlock.
|
||||
if (GlobalMap.count(Old)) {
|
||||
Value *New = GlobalMap[Old];
|
||||
|
||||
|
@ -299,17 +298,22 @@ Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
|
|||
return New;
|
||||
}
|
||||
|
||||
// OldOperand was recalculated within this BasicBlock.
|
||||
if (BBMap.count(Old)) {
|
||||
return BBMap[Old];
|
||||
}
|
||||
|
||||
// OldOperand is SCoP invariant.
|
||||
if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
|
||||
return const_cast<Value*>(Old);
|
||||
// 'Old' is within the original SCoP, but was not rewritten.
|
||||
//
|
||||
// Such values appear, if they only calculate information already available in
|
||||
// the polyhedral description (e.g. an induction variable increment). They
|
||||
// can be safely ignored.
|
||||
if (const Instruction *Inst = dyn_cast<Instruction>(Old))
|
||||
if (Statement.getParent()->getRegion().contains(Inst->getParent()))
|
||||
return NULL;
|
||||
|
||||
// We could not find any valid new operand.
|
||||
return NULL;
|
||||
// Everything else is probably a scop-constant value defined as global,
|
||||
// function parameter or an instruction not within the scop.
|
||||
return const_cast<Value*>(Old);
|
||||
}
|
||||
|
||||
void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* =============================================================================
|
||||
*
|
||||
* Filename: 20120330-argument-use.c
|
||||
*
|
||||
* Description: Polly OpenMP test case
|
||||
*
|
||||
* Test if the OpenMP subfunction uses the argument copy in
|
||||
* the OpenMP struct not the original one only available in
|
||||
* the original function.
|
||||
*
|
||||
* Run with -polly-codegen -enable-polly-openmp
|
||||
*
|
||||
* Author: Johannes Doerfert johannes@jdoerfert.de
|
||||
*
|
||||
* Created: 2012-03-30
|
||||
* Modified: 2012-03-30
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
void f(int * restrict A, int * restrict B, int n) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
A[i] = B[i] * 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp %s -S | FileCheck %s
|
||||
; ModuleID = '20120330-argument-lookup.s'
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @f(i32* noalias %A, i32* noalias %B, i32 %n) nounwind uwtable {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.inc, %entry
|
||||
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
|
||||
%tmp = trunc i64 %indvars.iv to i32
|
||||
%cmp = icmp slt i32 %tmp, %n
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
%arrayidx = getelementptr inbounds i32* %B, i64 %indvars.iv
|
||||
%tmp1 = load i32* %arrayidx, align 4
|
||||
%mul = shl nsw i32 %tmp1, 1
|
||||
%arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
|
||||
store i32 %mul, i32* %arrayidx2, align 4
|
||||
br label %for.inc
|
||||
|
||||
for.inc: ; preds = %for.body
|
||||
%indvars.iv.next = add i64 %indvars.iv, 1
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: %omp.userContext1 = bitcast i8* %omp.userContext to { i32, i32, i32*, i32* }*
|
||||
; CHECK: %0 = getelementptr inbounds { i32, i32, i32*, i32* }* %omp.userContext1, i32 0, i32 0
|
||||
; CHECK: %1 = load i32* %0
|
||||
; CHECK: %2 = getelementptr inbounds { i32, i32, i32*, i32* }* %omp.userContext1, i32 0, i32 1
|
||||
; CHECK: %3 = load i32* %2
|
||||
; CHECK: %4 = getelementptr inbounds { i32, i32, i32*, i32* }* %omp.userContext1, i32 0, i32 2
|
||||
; CHECK: %5 = load i32** %4
|
||||
; CHECK: %6 = getelementptr inbounds { i32, i32, i32*, i32* }* %omp.userContext1, i32 0, i32 3
|
||||
; CHECK: %7 = load i32** %6
|
||||
|
Loading…
Reference in New Issue