forked from OSchip/llvm-project
				
			BlockGenerator: Recompute values from SCEV before handing back the original values
This patch moves the SCEV based (re)generation of values before the checking for scop-constant terms. It enables us to provide SCEV based replacements, which are necessary to correctly generate OpenMP subfunctions when using the SCEV based code generation. When recomputing a new value for a value used in the code of the original scop, we previously directly returned the same original value for all scop-constant expressions without even trying to regenerate these values using our SCEV expression. This is correct when the newly generated code remains fully in the same function, however in case we want to outline parts of the newly generated scop into subfunctions, this approach means we do not have any opportunity to update these values in the SCEV based code generation. (In the non-SCEV based code generation, we can provide such updates through the GlobalMap). To ensure we have this opportunity, we first try to regenerate scalar terms with our SCEV builder and will only return scop-constant expressions if SCEV based code generation was not possible. This change should not affect the results of the existing code generation passes. It only impacts the upcoming OpenMP based code generation. This commit also adds a test case. This test case passes before and after this commit. It was added to ensure test coverage for the changed code. llvm-svn: 221393
This commit is contained in:
		
							parent
							
								
									68a79a790c
								
							
						
					
					
						commit
						16371acdc4
					
				| 
						 | 
					@ -103,10 +103,11 @@ protected:
 | 
				
			||||||
  /// @brief Get the new version of a value.
 | 
					  /// @brief Get the new version of a value.
 | 
				
			||||||
  ///
 | 
					  ///
 | 
				
			||||||
  /// Given an old value, we first check if a new version of this value is
 | 
					  /// Given an old value, we first check if a new version of this value is
 | 
				
			||||||
  /// available in the BBMap or GlobalMap. If the value is scop constant, we
 | 
					  /// available in the BBMap or GlobalMap. In case it is not and the value can
 | 
				
			||||||
  /// assume it is a parameter and return the old value. In case it is not and
 | 
					  /// be recomputed using SCEV, we do so. If we can not recompute a value
 | 
				
			||||||
  /// the value can be recomputed using SCEV, we do so. If the value can still
 | 
					  /// using SCEV, but we understand that the value is constant within the scop,
 | 
				
			||||||
  /// not be derived, this function will assert.
 | 
					  /// we return the old value.  If the value can still not be derived, this
 | 
				
			||||||
 | 
					  /// function will assert.
 | 
				
			||||||
  ///
 | 
					  ///
 | 
				
			||||||
  /// @param Old       The old Value.
 | 
					  /// @param Old       The old Value.
 | 
				
			||||||
  /// @param BBMap     A mapping from old values to their new values
 | 
					  /// @param BBMap     A mapping from old values to their new values
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,15 +88,6 @@ Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
 | 
				
			||||||
    return New;
 | 
					    return New;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Or it is probably a scop-constant value defined as global, function
 | 
					 | 
				
			||||||
  // parameter or an instruction not within the scop.
 | 
					 | 
				
			||||||
  if (isa<GlobalValue>(Old) || isa<Argument>(Old))
 | 
					 | 
				
			||||||
    return const_cast<Value *>(Old);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (const Instruction *Inst = dyn_cast<Instruction>(Old))
 | 
					 | 
				
			||||||
    if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
 | 
					 | 
				
			||||||
      return const_cast<Value *>(Old);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (Value *New = BBMap.lookup(Old))
 | 
					  if (Value *New = BBMap.lookup(Old))
 | 
				
			||||||
    return New;
 | 
					    return New;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,8 +108,16 @@ Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Now the scalar dependence is neither available nor SCEVCodegenable, this
 | 
					  // A scop-constant value defined by a global or a function parameter.
 | 
				
			||||||
  // should never happen in the current code generator.
 | 
					  if (isa<GlobalValue>(Old) || isa<Argument>(Old))
 | 
				
			||||||
 | 
					    return const_cast<Value *>(Old);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // A scop-constant value defined by an instruction executed outside the scop.
 | 
				
			||||||
 | 
					  if (const Instruction *Inst = dyn_cast<Instruction>(Old))
 | 
				
			||||||
 | 
					    if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
 | 
				
			||||||
 | 
					      return const_cast<Value *>(Old);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The scalar dependence is neither available nor SCEVCodegenable.
 | 
				
			||||||
  llvm_unreachable("Unexpected scalar dependence in region!");
 | 
					  llvm_unreachable("Unexpected scalar dependence in region!");
 | 
				
			||||||
  return nullptr;
 | 
					  return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; Test the code generation in the presence of a scalar out-of-scop value being
 | 
				
			||||||
 | 
					; used from within the SCoP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; CHECH-LABEL: @scalar-function-argument
 | 
				
			||||||
 | 
					; CHECK: polly.split_new_and_old
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 | 
				
			||||||
 | 
					target triple = "x86_64-unknown-linux-gnu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define void @scalar-function-argument(float* %A, float %sqrinv) {
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
					  br label %for.body
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.body:
 | 
				
			||||||
 | 
					  %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
 | 
				
			||||||
 | 
					  %mul104 = fmul float 1.0, %sqrinv
 | 
				
			||||||
 | 
					  %rp107 = getelementptr float* %A, i64 %indvar
 | 
				
			||||||
 | 
					  store float %mul104, float* %rp107, align 4
 | 
				
			||||||
 | 
					  %indvar.next = add nsw i64 %indvar, 1
 | 
				
			||||||
 | 
					  %cmp = icmp slt i64 1024, %indvar.next
 | 
				
			||||||
 | 
					  br i1 %cmp, label %for.end, label %for.body
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.end:
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; CHECH-LABEL: @scalar-outside-of-scop
 | 
				
			||||||
 | 
					; CHECK: polly.split_new_and_old
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define void @scalar-outside-of-scop(float* %A) {
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
					  %sqrinv = call float @getFloat()
 | 
				
			||||||
 | 
					  br label %for.body
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.body:
 | 
				
			||||||
 | 
					  %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
 | 
				
			||||||
 | 
					  %mul104 = fmul float 1.0, %sqrinv
 | 
				
			||||||
 | 
					  %rp107 = getelementptr float* %A, i64 %indvar
 | 
				
			||||||
 | 
					  store float %mul104, float* %rp107, align 4
 | 
				
			||||||
 | 
					  %indvar.next = add nsw i64 %indvar, 1
 | 
				
			||||||
 | 
					  %cmp = icmp slt i64 1024, %indvar.next
 | 
				
			||||||
 | 
					  br i1 %cmp, label %for.end, label %for.body
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.end:
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare float @getFloat()
 | 
				
			||||||
		Loading…
	
		Reference in New Issue