diff --git a/polly/docs/ReleaseNotes.rst b/polly/docs/ReleaseNotes.rst index 15b108c51594f..5c3d37b80e272 100644 --- a/polly/docs/ReleaseNotes.rst +++ b/polly/docs/ReleaseNotes.rst @@ -21,3 +21,7 @@ In Polly 14 the following important changes have been incorporated. This will agressively try to fuse any loop regardless of profitability. The is what users might have expected what -polly-opt-fusion=max would do. + +- Support for gfortran-generated code has been removed. This includes + Fortran Array Descriptors (-polly-detect-fortran-arrays) and the + -polly-rewrite-byref-params pass. diff --git a/polly/include/polly/CodeGen/IslNodeBuilder.h b/polly/include/polly/CodeGen/IslNodeBuilder.h index 450d63c286e90..2dc7f019e84cf 100644 --- a/polly/include/polly/CodeGen/IslNodeBuilder.h +++ b/polly/include/polly/CodeGen/IslNodeBuilder.h @@ -78,13 +78,6 @@ class IslNodeBuilder { void addParameters(__isl_take isl_set *Context); - /// Create Values which hold the sizes of the outermost dimension of all - /// Fortran arrays in the current scop. - /// - /// @returns False, if a problem occurred and a Fortran array was not - /// materialized. True otherwise. - bool materializeFortranArrayOutermostDimension(); - /// Generate code that evaluates @p Condition at run-time. /// /// This function is typically called to generate the LLVM-IR for the diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h index ccda4ef650f21..4f57e60d7ca0b 100644 --- a/polly/include/polly/LinkAllPasses.h +++ b/polly/include/polly/LinkAllPasses.h @@ -43,7 +43,6 @@ llvm::Pass *createPolyhedralInfoPass(); llvm::Pass *createScopDetectionWrapperPassPass(); llvm::Pass *createScopInfoRegionPassPass(); llvm::Pass *createScopInfoWrapperPassPass(); -llvm::Pass *createRewriteByrefParamsWrapperPass(); llvm::Pass *createIslAstInfoWrapperPassPass(); llvm::Pass *createCodeGenerationPass(); #ifdef GPU_CODEGEN @@ -88,7 +87,6 @@ struct PollyForcePassLinking { polly::createScopInfoRegionPassPass(); polly::createPollyCanonicalizePass(); polly::createPolyhedralInfoPass(); - polly::createRewriteByrefParamsWrapperPass(); polly::createIslAstInfoWrapperPassPass(); polly::createCodeGenerationPass(); #ifdef GPU_CODEGEN @@ -117,7 +115,6 @@ void initializeJSONExporterPass(llvm::PassRegistry &); void initializeJSONImporterPass(llvm::PassRegistry &); void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &); void initializeCodeGenerationPass(llvm::PassRegistry &); -void initializeRewriteByrefParamsWrapperPassPass(llvm::PassRegistry &); #ifdef GPU_CODEGEN void initializePPCGCodeGenerationPass(llvm::PassRegistry &); void initializeManagedMemoryRewritePassPass(llvm::PassRegistry &); diff --git a/polly/include/polly/RewriteByReferenceParameters.h b/polly/include/polly/RewriteByReferenceParameters.h deleted file mode 100644 index 10e5e20787b87..0000000000000 --- a/polly/include/polly/RewriteByReferenceParameters.h +++ /dev/null @@ -1,38 +0,0 @@ -//===- RewriteByReferenceParameters.h -------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -//===----------------------------------------------------------------------===// - -#ifndef POLLY_REWRITEBYREFERENCEPARAMETERS_H -#define POLLY_REWRITEBYREFERENCEPARAMETERS_H - -#include "polly/ScopPass.h" - -namespace llvm { -class PassRegistry; -class Pass; -class raw_ostream; -} // namespace llvm - -namespace polly { -llvm::Pass *createRewriteByrefParamsWrapperPass(); - -struct RewriteByrefParamsPass : llvm::PassInfoMixin { - RewriteByrefParamsPass() {} - - llvm::PreservedAnalyses run(llvm::Function &F, - llvm::FunctionAnalysisManager &FAM); -}; - -} // namespace polly - -namespace llvm { -void initializeRewriteByrefParamsWrapperPassPass(llvm::PassRegistry &); -} // namespace llvm - -#endif /* POLLY_REWRITEBYREFERENCEPARAMETERS_H */ diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h index 7c3a944dd5c97..dbfc3dcff122a 100644 --- a/polly/include/polly/ScopBuilder.h +++ b/polly/include/polly/ScopBuilder.h @@ -74,65 +74,6 @@ class ScopBuilder { /// only be simplified later on. RecordedAssumptionsTy RecordedAssumptions; - // Methods for pattern matching against Fortran code generated by dragonegg. - // @{ - - /// Try to match for the descriptor of a Fortran array whose allocation - /// is not visible. That is, we can see the load/store into the memory, but - /// we don't actually know where the memory is allocated. If ALLOCATE had been - /// called on the Fortran array, then we will see the lowered malloc() call. - /// If not, this is dubbed as an "invisible allocation". - /// - /// "" is the descriptor of the Fortran array. - /// - /// Pattern match for "@descriptor": - /// 1. %mem = load double*, double** bitcast (%"struct.array1_real(kind=8)"* - /// to double**), align 32 - /// - /// 2. [%slot = getelementptr inbounds i8, i8* %mem, i64 ] - /// 2 is optional because if you are writing to the 0th index, you don't - /// need a GEP. - /// - /// 3.1 store/load , * %slot - /// 3.2 store/load , * %mem - /// - /// @see polly::MemoryAccess, polly::ScopArrayInfo - /// - /// @note assumes -polly-canonicalize has been run. - /// - /// @param Inst The LoadInst/StoreInst that accesses the memory. - /// - /// @returns Reference to on success, nullptr on failure. - Value *findFADAllocationInvisible(MemAccInst Inst); - - /// Try to match for the descriptor of a Fortran array whose allocation - /// call is visible. When we have a Fortran array, we try to look for a - /// Fortran array where we can see the lowered ALLOCATE call. ALLOCATE - /// is materialized as a malloc(...) which we pattern match for. - /// - /// Pattern match for "%untypedmem": - /// 1. %untypedmem = i8* @malloc(...) - /// - /// 2. %typedmem = bitcast i8* %untypedmem to - /// - /// 3. [%slot = getelementptr inbounds i8, i8* %typedmem, i64 ] - /// 3 is optional because if you are writing to the 0th index, you don't - /// need a GEP. - /// - /// 4.1 store/load , * %slot, align 8 - /// 4.2 store/load , * %mem, align 8 - /// - /// @see polly::MemoryAccess, polly::ScopArrayInfo - /// - /// @note assumes -polly-canonicalize has been run. - /// - /// @param Inst The LoadInst/StoreInst that accesses the memory. - /// - /// @returns Reference to %untypedmem on success, nullptr on failure. - Value *findFADAllocationVisible(MemAccInst Inst); - - // @} - // Build the SCoP for Region @p R. void buildScop(Region &R, AssumptionCache &AC); @@ -417,9 +358,6 @@ class ScopBuilder { /// all memory accesses have been modeled and canonicalized. void assumeNoOutOfBounds(); - /// Mark arrays that have memory accesses with FortranArrayDescriptor. - void markFortranArrays(); - /// Build the alias checks for this SCoP. bool buildAliasChecks(); diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 7f07af3d8d16e..5eff6eb3e8d20 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -264,16 +264,6 @@ class ScopArrayInfo { /// with old sizes bool updateSizes(ArrayRef Sizes, bool CheckConsistency = true); - /// Make the ScopArrayInfo model a Fortran array. - /// It receives the Fortran array descriptor and stores this. - /// It also adds a piecewise expression for the outermost dimension - /// since this information is available for Fortran arrays at runtime. - void applyAndSetFAD(Value *FAD); - - /// Get the FortranArrayDescriptor corresponding to this array if it exists, - /// nullptr otherwise. - Value *getFortranArrayDescriptor() const { return this->FAD; } - /// Set the base pointer to @p BP. void setBasePtr(Value *BP) { BasePtr = BP; } @@ -440,10 +430,6 @@ class ScopArrayInfo { /// The scop this SAI object belongs to. Scop &S; - - /// If this array models a Fortran array, then this points - /// to the Fortran array descriptor. - Value *FAD = nullptr; }; /// Represent memory accesses in statements. @@ -636,13 +622,6 @@ class MemoryAccess { /// Updated access relation read from JSCOP file. isl::map NewAccessRelation; - - /// Fortran arrays whose sizes are not statically known are stored in terms - /// of a descriptor struct. This maintains a raw pointer to the memory, - /// along with auxiliary fields with information such as dimensions. - /// We hold a reference to the descriptor corresponding to a MemoryAccess - /// into a Fortran array. FAD for "Fortran Array Descriptor" - AssertingVH FAD; // @} isl::basic_map createBasicAccessMap(ScopStmt *Statement); @@ -935,10 +914,6 @@ class MemoryAccess { /// the dimension of the innermost loop containing the statement. isl::set getStride(isl::map Schedule) const; - /// Get the FortranArrayDescriptor corresponding to this memory access if - /// it exists, and nullptr otherwise. - Value *getFortranArrayDescriptor() const { return this->FAD; } - /// Is the stride of the access equal to a certain width? Schedule is a map /// from the statement to a schedule where the innermost dimension is the /// dimension of the innermost loop containing the statement. @@ -1061,10 +1036,6 @@ class MemoryAccess { /// Get the reduction type of this access ReductionType getReductionType() const { return RedType; } - /// Set the array descriptor corresponding to the Array on which the - /// memory access is performed. - void setFortranArrayDescriptor(Value *FAD); - /// Update the original access relation. /// /// We need to update the original access relation during scop construction, diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp index 35e91b4423d6d..2cb6f37441e8d 100644 --- a/polly/lib/Analysis/ScopBuilder.cpp +++ b/polly/lib/Analysis/ScopBuilder.cpp @@ -129,11 +129,6 @@ static cl::opt UserContextStr( cl::desc("Provide additional constraints on the context parameters"), cl::init(""), cl::cat(PollyCategory)); -static cl::opt DetectFortranArrays( - "polly-detect-fortran-arrays", - cl::desc("Detect Fortran arrays and use this for code generation"), - cl::Hidden, cl::init(false), cl::cat(PollyCategory)); - static cl::opt DetectReductions("polly-detect-reductions", cl::desc("Detect and exploit reductions"), cl::Hidden, cl::ZeroOrMore, @@ -1333,189 +1328,6 @@ void ScopBuilder::buildEscapingDependences(Instruction *Inst) { ensureValueWrite(Inst); } -/// Check that a value is a Fortran Array descriptor. -/// -/// We check if V has the following structure: -/// %"struct.array1_real(kind=8)" = type { i8*, i, i, -/// [ x %struct.descriptor_dimension] } -/// -/// -/// %struct.descriptor_dimension = type { i, i, i } -/// -/// 1. V's type name starts with "struct.array" -/// 2. V's type has layout as shown. -/// 3. Final member of V's type has name "struct.descriptor_dimension", -/// 4. "struct.descriptor_dimension" has layout as shown. -/// 5. Consistent use of i where is some fixed integer number. -/// -/// We are interested in such types since this is the code that dragonegg -/// generates for Fortran array descriptors. -/// -/// @param V the Value to be checked. -/// -/// @returns True if V is a Fortran array descriptor, False otherwise. -bool isFortranArrayDescriptor(Value *V) { - PointerType *PTy = dyn_cast(V->getType()); - - if (!PTy) - return false; - - Type *Ty = PTy->getElementType(); - assert(Ty && "Ty expected to be initialized"); - auto *StructArrTy = dyn_cast(Ty); - - if (!(StructArrTy && StructArrTy->hasName())) - return false; - - if (!StructArrTy->getName().startswith("struct.array")) - return false; - - if (StructArrTy->getNumElements() != 4) - return false; - - const ArrayRef ArrMemberTys = StructArrTy->elements(); - - // i8* match - if (ArrMemberTys[0] != Type::getInt8PtrTy(V->getContext())) - return false; - - // Get a reference to the int type and check that all the members - // share the same int type - Type *IntTy = ArrMemberTys[1]; - if (ArrMemberTys[2] != IntTy) - return false; - - // type: [ x %struct.descriptor_dimension] - ArrayType *DescriptorDimArrayTy = dyn_cast(ArrMemberTys[3]); - if (!DescriptorDimArrayTy) - return false; - - // type: %struct.descriptor_dimension := type { ixx, ixx, ixx } - StructType *DescriptorDimTy = - dyn_cast(DescriptorDimArrayTy->getElementType()); - - if (!(DescriptorDimTy && DescriptorDimTy->hasName())) - return false; - - if (DescriptorDimTy->getName() != "struct.descriptor_dimension") - return false; - - if (DescriptorDimTy->getNumElements() != 3) - return false; - - for (auto MemberTy : DescriptorDimTy->elements()) { - if (MemberTy != IntTy) - return false; - } - - return true; -} - -Value *ScopBuilder::findFADAllocationVisible(MemAccInst Inst) { - // match: 4.1 & 4.2 store/load - if (!isa(Inst) && !isa(Inst)) - return nullptr; - - // match: 4 - if (Inst.getAlignment() != 8) - return nullptr; - - Value *Address = Inst.getPointerOperand(); - - const BitCastInst *Bitcast = nullptr; - // [match: 3] - if (auto *Slot = dyn_cast(Address)) { - Value *TypedMem = Slot->getPointerOperand(); - // match: 2 - Bitcast = dyn_cast(TypedMem); - } else { - // match: 2 - Bitcast = dyn_cast(Address); - } - - if (!Bitcast) - return nullptr; - - auto *MallocMem = Bitcast->getOperand(0); - - // match: 1 - auto *MallocCall = dyn_cast(MallocMem); - if (!MallocCall) - return nullptr; - - Function *MallocFn = MallocCall->getCalledFunction(); - if (!(MallocFn && MallocFn->hasName() && MallocFn->getName() == "malloc")) - return nullptr; - - // Find all uses the malloc'd memory. - // We are looking for a "store" into a struct with the type being the Fortran - // descriptor type - for (auto user : MallocMem->users()) { - /// match: 5 - auto *MallocStore = dyn_cast(user); - if (!MallocStore) - continue; - - auto *DescriptorGEP = - dyn_cast(MallocStore->getPointerOperand()); - if (!DescriptorGEP) - continue; - - // match: 5 - auto DescriptorType = - dyn_cast(DescriptorGEP->getSourceElementType()); - if (!(DescriptorType && DescriptorType->hasName())) - continue; - - Value *Descriptor = dyn_cast(DescriptorGEP->getPointerOperand()); - - if (!Descriptor) - continue; - - if (!isFortranArrayDescriptor(Descriptor)) - continue; - - return Descriptor; - } - - return nullptr; -} - -Value *ScopBuilder::findFADAllocationInvisible(MemAccInst Inst) { - // match: 3 - if (!isa(Inst) && !isa(Inst)) - return nullptr; - - Value *Slot = Inst.getPointerOperand(); - - LoadInst *MemLoad = nullptr; - // [match: 2] - if (auto *SlotGEP = dyn_cast(Slot)) { - // match: 1 - MemLoad = dyn_cast(SlotGEP->getPointerOperand()); - } else { - // match: 1 - MemLoad = dyn_cast(Slot); - } - - if (!MemLoad) - return nullptr; - - auto *BitcastOperator = - dyn_cast(MemLoad->getPointerOperand()); - if (!BitcastOperator) - return nullptr; - - Value *Descriptor = dyn_cast(BitcastOperator->getOperand(0)); - if (!Descriptor) - return nullptr; - - if (!isFortranArrayDescriptor(Descriptor)) - return nullptr; - - return Descriptor; -} - void ScopBuilder::addRecordedAssumptions() { for (auto &AS : llvm::reverse(RecordedAssumptions)) { @@ -2350,17 +2162,8 @@ void ScopBuilder::addArrayAccess(ScopStmt *Stmt, MemAccInst MemAccInst, ArrayRef Sizes, Value *AccessValue) { ArrayBasePointers.insert(BaseAddress); - auto *MemAccess = addMemoryAccess(Stmt, MemAccInst, AccType, BaseAddress, - ElementType, IsAffine, AccessValue, - Subscripts, Sizes, MemoryKind::Array); - - if (!DetectFortranArrays) - return; - - if (Value *FAD = findFADAllocationInvisible(MemAccInst)) - MemAccess->setFortranArrayDescriptor(FAD); - else if (Value *FAD = findFADAllocationVisible(MemAccInst)) - MemAccess->setFortranArrayDescriptor(FAD); + addMemoryAccess(Stmt, MemAccInst, AccType, BaseAddress, ElementType, IsAffine, + AccessValue, Subscripts, Sizes, MemoryKind::Array); } /// Check if @p Expr is divisible by @p Size. @@ -2490,29 +2293,11 @@ void ScopBuilder::foldSizeConstantsToRight() { } } -void ScopBuilder::markFortranArrays() { - for (ScopStmt &Stmt : *scop) { - for (MemoryAccess *MemAcc : Stmt) { - Value *FAD = MemAcc->getFortranArrayDescriptor(); - if (!FAD) - continue; - - // TODO: const_cast-ing to edit - ScopArrayInfo *SAI = - const_cast(MemAcc->getLatestScopArrayInfo()); - assert(SAI && "memory access into a Fortran array does not " - "have an associated ScopArrayInfo"); - SAI->applyAndSetFAD(FAD); - } - } -} - void ScopBuilder::finalizeAccesses() { updateAccessDimensionality(); foldSizeConstantsToRight(); foldAccessRelations(); assumeNoOutOfBounds(); - markFortranArrays(); } void ScopBuilder::updateAccessDimensionality() { diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 60a54f1ccb80c..dc2d4848ba3bc 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -298,32 +298,6 @@ void ScopArrayInfo::updateElementType(Type *NewElementType) { } } -/// Make the ScopArrayInfo model a Fortran Array -void ScopArrayInfo::applyAndSetFAD(Value *FAD) { - assert(FAD && "got invalid Fortran array descriptor"); - if (this->FAD) { - assert(this->FAD == FAD && - "receiving different array descriptors for same array"); - return; - } - - assert(DimensionSizesPw.size() > 0 && DimensionSizesPw[0].is_null()); - assert(!this->FAD); - this->FAD = FAD; - - isl::space Space(S.getIslCtx(), 1, 0); - - std::string param_name = getName(); - param_name += "_fortranarr_size"; - isl::id IdPwAff = isl::id::alloc(S.getIslCtx(), param_name, this); - - Space = Space.set_dim_id(isl::dim::param, 0, IdPwAff); - isl::pw_aff PwAff = - isl::aff::var_on_domain(isl::local_space(Space), isl::dim::param, 0); - - DimensionSizesPw[0] = PwAff; -} - bool ScopArrayInfo::updateSizes(ArrayRef NewSizes, bool CheckConsistency) { int SharedDims = std::min(NewSizes.size(), DimensionSizes.size()); @@ -372,12 +346,8 @@ LLVM_DUMP_METHOD void ScopArrayInfo::dump() const { print(errs()); } void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const { OS.indent(8) << *getElementType() << " " << getName(); unsigned u = 0; - // If this is a Fortran array, then we can print the outermost dimension - // as a isl_pw_aff even though there is no SCEV information. - bool IsOutermostSizeKnown = SizeAsPwAff && FAD; - if (!IsOutermostSizeKnown && getNumberOfDimensions() > 0 && - !getDimensionSize(0)) { + if (getNumberOfDimensions() > 0 && !getDimensionSize(0)) { OS << "[*]"; u++; } @@ -894,7 +864,7 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst), AccessValue(AccessValue), IsAffine(Affine), Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(), - NewAccessRelation(), FAD(nullptr) { + NewAccessRelation() { static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"}; const std::string Access = TypeStrings[AccType] + utostr(Stmt->size()); @@ -904,8 +874,7 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst, MemoryAccess::MemoryAccess(ScopStmt *Stmt, AccessType AccType, isl::map AccRel) : Kind(MemoryKind::Array), AccType(AccType), Statement(Stmt), - InvalidDomain(), AccessRelation(), NewAccessRelation(AccRel), - FAD(nullptr) { + InvalidDomain(), AccessRelation(), NewAccessRelation(AccRel) { isl::id ArrayInfoId = NewAccessRelation.get_tuple_id(isl::dim::out); auto *SAI = ScopArrayInfo::getFromId(ArrayInfoId); Sizes.push_back(nullptr); @@ -949,8 +918,6 @@ raw_ostream &polly::operator<<(raw_ostream &OS, return OS; } -void MemoryAccess::setFortranArrayDescriptor(Value *FAD) { this->FAD = FAD; } - void MemoryAccess::print(raw_ostream &OS) const { switch (AccType) { case READ: @@ -966,11 +933,6 @@ void MemoryAccess::print(raw_ostream &OS) const { OS << "[Reduction Type: " << getReductionType() << "] "; - if (FAD) { - OS << "[Fortran array descriptor: " << FAD->getName(); - OS << "] "; - }; - OS << "[Scalar: " << isScalarKind() << "]\n"; OS.indent(16) << getOriginalAccessRelationStr() << ";\n"; if (hasNewAccessRelation()) @@ -1539,41 +1501,6 @@ void Scop::addParameterBounds() { intersectDefinedBehavior(Context, AS_ASSUMPTION); } -static std::vector getFortranArrayIds(Scop::array_range Arrays) { - std::vector OutermostSizeIds; - for (auto Array : Arrays) { - // To check if an array is a Fortran array, we check if it has a isl_pw_aff - // for its outermost dimension. Fortran arrays will have this since the - // outermost dimension size can be picked up from their runtime description. - // TODO: actually need to check if it has a FAD, but for now this works. - if (Array->getNumberOfDimensions() > 0) { - isl::pw_aff PwAff = Array->getDimensionSizePw(0); - if (PwAff.is_null()) - continue; - - isl::id Id = PwAff.get_dim_id(isl::dim::param, 0); - assert(!Id.is_null() && - "Invalid Id for PwAff expression in Fortran array"); - OutermostSizeIds.push_back(Id); - } - } - return OutermostSizeIds; -} - -// The FORTRAN array size parameters are known to be non-negative. -static isl::set boundFortranArrayParams(isl::set Context, - Scop::array_range Arrays) { - std::vector OutermostSizeIds; - OutermostSizeIds = getFortranArrayIds(Arrays); - - for (isl::id Id : OutermostSizeIds) { - int dim = Context.find_dim_by_id(isl::dim::param, Id); - Context = Context.lower_bound_si(isl::dim::param, dim, 0); - } - - return Context; -} - void Scop::realignParams() { if (PollyIgnoreParamBounds) return; @@ -1586,9 +1513,6 @@ void Scop::realignParams() { AssumedContext = AssumedContext.align_params(Space); InvalidContext = InvalidContext.align_params(Space); - // Bound the size of the fortran array dimensions. - Context = boundFortranArrayParams(Context, arrays()); - // As all parameters are known add bounds to them. addParameterBounds(); @@ -1901,11 +1825,8 @@ isl::set Scop::getContext() const { return Context; } isl::space Scop::getParamSpace() const { return getContext().get_space(); } isl::space Scop::getFullParamSpace() const { - std::vector FortranIDs; - FortranIDs = getFortranArrayIds(arrays()); - isl::space Space = isl::space::params_alloc( - getIslCtx(), ParameterIds.size() + FortranIDs.size()); + isl::space Space = isl::space::params_alloc(getIslCtx(), ParameterIds.size()); unsigned PDim = 0; for (const SCEV *Parameter : Parameters) { @@ -1913,9 +1834,6 @@ isl::space Scop::getFullParamSpace() const { Space = Space.set_dim_id(isl::dim::param, PDim++, Id); } - for (isl::id Id : FortranIDs) - Space = Space.set_dim_id(isl::dim::param, PDim++, Id); - return Space; } diff --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt index 9a967b106ea65..c6c1a18e90046 100644 --- a/polly/lib/CMakeLists.txt +++ b/polly/lib/CMakeLists.txt @@ -97,7 +97,6 @@ add_llvm_pass_plugin(Polly Transform/ZoneAlgo.cpp Transform/Simplify.cpp Transform/MaximalStaticExpansion.cpp - Transform/RewriteByReferenceParameters.cpp Transform/ScopInliner.cpp Transform/ManualOptimizer.cpp Transform/MatmulOptimizer.cpp diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index 06fb1c775f695..36864dbe51fa9 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -1160,84 +1160,6 @@ bool IslNodeBuilder::materializeParameters() { return true; } -/// Generate the computation of the size of the outermost dimension from the -/// Fortran array descriptor (in this case, `@g_arr`). The final `%size` -/// contains the size of the array. -/// -/// %arrty = type { i8*, i64, i64, [3 x %desc.dimensionty] } -/// %desc.dimensionty = type { i64, i64, i64 } -/// @g_arr = global %arrty zeroinitializer, align 32 -/// ... -/// %0 = load i64, i64* getelementptr inbounds -/// (%arrty, %arrty* @g_arr, i64 0, i32 3, i64 0, i32 2) -/// %1 = load i64, i64* getelementptr inbounds -/// (%arrty, %arrty* @g_arr, i64 0, i32 3, i64 0, i32 1) -/// %2 = sub nsw i64 %0, %1 -/// %size = add nsw i64 %2, 1 -static Value *buildFADOutermostDimensionLoad(Value *GlobalDescriptor, - PollyIRBuilder &Builder, - std::string ArrayName) { - assert(GlobalDescriptor && "invalid global descriptor given"); - Type *Ty = GlobalDescriptor->getType()->getPointerElementType(); - - Value *endIdx[4] = {Builder.getInt64(0), Builder.getInt32(3), - Builder.getInt64(0), Builder.getInt32(2)}; - Value *endPtr = Builder.CreateInBoundsGEP(Ty, GlobalDescriptor, endIdx, - ArrayName + "_end_ptr"); - Type *type = cast(endPtr)->getResultElementType(); - assert(isa(type) && "expected type of end to be integral"); - - Value *end = Builder.CreateLoad(type, endPtr, ArrayName + "_end"); - - Value *beginIdx[4] = {Builder.getInt64(0), Builder.getInt32(3), - Builder.getInt64(0), Builder.getInt32(1)}; - Value *beginPtr = Builder.CreateInBoundsGEP(Ty, GlobalDescriptor, beginIdx, - ArrayName + "_begin_ptr"); - Value *begin = Builder.CreateLoad(type, beginPtr, ArrayName + "_begin"); - - Value *size = - Builder.CreateNSWSub(end, begin, ArrayName + "_end_begin_delta"); - - size = Builder.CreateNSWAdd( - end, ConstantInt::get(type, 1, /* signed = */ true), ArrayName + "_size"); - - return size; -} - -bool IslNodeBuilder::materializeFortranArrayOutermostDimension() { - for (ScopArrayInfo *Array : S.arrays()) { - if (Array->getNumberOfDimensions() == 0) - continue; - - Value *FAD = Array->getFortranArrayDescriptor(); - if (!FAD) - continue; - - isl_pw_aff *ParametricPwAff = Array->getDimensionSizePw(0).release(); - assert(ParametricPwAff && "parametric pw_aff corresponding " - "to outermost dimension does not " - "exist"); - - isl_id *Id = isl_pw_aff_get_dim_id(ParametricPwAff, isl_dim_param, 0); - isl_pw_aff_free(ParametricPwAff); - - assert(Id && "pw_aff is not parametric"); - - if (IDToValue.count(Id)) { - isl_id_free(Id); - continue; - } - - Value *FinalValue = - buildFADOutermostDimensionLoad(FAD, Builder, Array->getName()); - assert(FinalValue && "unable to build Fortran array " - "descriptor load of outermost dimension"); - IDToValue[Id] = FinalValue; - isl_id_free(Id); - } - return true; -} - Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange, isl_ast_build *Build, Instruction *AccInst) { @@ -1569,12 +1491,6 @@ void IslNodeBuilder::addParameters(__isl_take isl_set *Context) { // Materialize values for the parameters of the SCoP. materializeParameters(); - // materialize the outermost dimension parameters for a Fortran array. - // NOTE: materializeParameters() does not work since it looks through - // the SCEVs. We don't have a corresponding SCEV for the array size - // parameter - materializeFortranArrayOutermostDimension(); - // Generate values for the current loop iteration for all surrounding loops. // // We may also reference loops outside of the scop which do not contain the diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp index ebc0a7ee41ebe..e546525e1388f 100644 --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -264,7 +264,6 @@ void initializePollyPasses(PassRegistry &Registry) { initializeScopInlinerPass(Registry); initializeScopInfoRegionPassPass(Registry); initializeScopInfoWrapperPassPass(Registry); - initializeRewriteByrefParamsWrapperPassPass(Registry); initializeCodegenCleanupPass(Registry); initializeFlattenSchedulePass(Registry); initializeForwardOpTreeWrapperPassPass(Registry); diff --git a/polly/lib/Transform/Canonicalization.cpp b/polly/lib/Transform/Canonicalization.cpp index 8dc26b3047819..d65d626df0c5b 100644 --- a/polly/lib/Transform/Canonicalization.cpp +++ b/polly/lib/Transform/Canonicalization.cpp @@ -15,7 +15,6 @@ #include "polly/Canonicalization.h" #include "polly/LinkAllPasses.h" #include "polly/Options.h" -#include "polly/RewriteByReferenceParameters.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/IR/LegacyPassManager.h" @@ -42,7 +41,6 @@ static cl::opt void polly::registerCanonicalicationPasses(llvm::legacy::PassManagerBase &PM) { bool UseMemSSA = true; - PM.add(polly::createRewriteByrefParamsWrapperPass()); PM.add(llvm::createPromoteMemoryToRegisterPass()); PM.add(llvm::createEarlyCSEPass(UseMemSSA)); PM.add(llvm::createInstructionCombiningPass()); @@ -98,7 +96,6 @@ polly::buildCanonicalicationPassesForNPM(llvm::ModulePassManager &MPM, FunctionPassManager FPM; bool UseMemSSA = true; - FPM.addPass(RewriteByrefParamsPass()); FPM.addPass(PromotePass()); FPM.addPass(EarlyCSEPass(UseMemSSA)); FPM.addPass(InstCombinePass()); diff --git a/polly/lib/Transform/RewriteByReferenceParameters.cpp b/polly/lib/Transform/RewriteByReferenceParameters.cpp deleted file mode 100644 index 2cf4764cd6217..0000000000000 --- a/polly/lib/Transform/RewriteByReferenceParameters.cpp +++ /dev/null @@ -1,112 +0,0 @@ -//===------ RewriteByReferenceParameters.cpp --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This pass introduces separate 'alloca' instructions for read-only -// by-reference function parameters to indicate that these paramters are -// read-only. After this transformation -mem2reg has more freedom to promote -// variables to registers, which allows SCEV to work in more cases. -// -//===----------------------------------------------------------------------===// - -#include "polly/RewriteByReferenceParameters.h" -#include "polly/LinkAllPasses.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" -#include "llvm/Pass.h" - -#define DEBUG_TYPE "polly-rewrite-byref-params" - -using namespace llvm; - -namespace { -static void tryRewriteInstruction(Instruction &Inst) { - BasicBlock *Entry = &Inst.getParent()->getParent()->getEntryBlock(); - - auto *Call = dyn_cast(&Inst); - - if (!Call) - return; - - llvm::Function *F = Call->getCalledFunction(); - - if (!F) - return; - - // We currently match for a very specific function. In case this proves - // useful, we can make this code dependent on readonly metadata. - if (!F->hasName() || F->getName() != "_gfortran_transfer_integer_write") - return; - - auto *BitCast = dyn_cast(Call->getOperand(1)); - - if (!BitCast) - return; - - auto *Alloca = dyn_cast(BitCast->getOperand(0)); - - if (!Alloca) - return; - - std::string InstName = Alloca->getName().str(); - - auto NewAlloca = - new AllocaInst(Alloca->getAllocatedType(), 0, - "polly_byref_alloca_" + InstName, &*Entry->begin()); - - auto *LoadedVal = new LoadInst(Alloca->getAllocatedType(), Alloca, - "polly_byref_load_" + InstName, &Inst); - - new StoreInst(LoadedVal, NewAlloca, &Inst); - auto *NewBitCast = new BitCastInst(NewAlloca, BitCast->getType(), - "polly_byref_cast_" + InstName, &Inst); - Call->setOperand(1, NewBitCast); -} - -static void runRewriteByrefParams(Function &F) { - for (BasicBlock &BB : F) - for (Instruction &Inst : BB) - tryRewriteInstruction(Inst); -} - -class RewriteByrefParamsWrapperPass : public FunctionPass { -private: - RewriteByrefParamsWrapperPass(const RewriteByrefParamsWrapperPass &) = delete; - const RewriteByrefParamsWrapperPass & - operator=(const RewriteByrefParamsWrapperPass &) = delete; - -public: - static char ID; - explicit RewriteByrefParamsWrapperPass() : FunctionPass(ID) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const override {} - - virtual bool runOnFunction(Function &F) override { - runRewriteByrefParams(F); - return true; - } -}; - -char RewriteByrefParamsWrapperPass::ID; -} // anonymous namespace - -Pass *polly::createRewriteByrefParamsWrapperPass() { - return new RewriteByrefParamsWrapperPass(); -} - -llvm::PreservedAnalyses -polly ::RewriteByrefParamsPass::run(llvm::Function &F, - llvm::FunctionAnalysisManager &FAM) { - runRewriteByrefParams(F); - return PreservedAnalyses::none(); -} - -INITIALIZE_PASS_BEGIN(RewriteByrefParamsWrapperPass, - "polly-rewrite-byref-params", - "Polly - Rewrite by reference parameters", false, false) -INITIALIZE_PASS_END(RewriteByrefParamsWrapperPass, "polly-rewrite-byref-params", - "Polly - Rewrite by reference parameters", false, false) diff --git a/polly/test/CodeGen/fortran_array_runtime_size_generation.ll b/polly/test/CodeGen/fortran_array_runtime_size_generation.ll deleted file mode 100644 index 29eeb1ce4dd28..0000000000000 --- a/polly/test/CodeGen/fortran_array_runtime_size_generation.ll +++ /dev/null @@ -1,77 +0,0 @@ -; Check that the runtime size computation is generated for Fortran arrays. - -; Regular code generation backend: -; RUN: opt %loadPolly -S -polly-detect-fortran-arrays \ -; RUN: -polly-codegen < %s | FileCheck %s - -; What the input fortran code should look like. NOTE: this is fake, the -; .ll file was hand-written. -; -; MODULE testmod -; USE data_parameters, ONLY : & -; IMPLICIT NONE -; -; INTEGER (KIND=iintegers), ALLOCATABLE, PRIVATE :: & -; arrin(:), arrout(:) -; CONTAINS -; -; SUBROUTINE test() -; INTEGER (KIND=iintegers) :: i -; -; DO i = 1, 100 -; arrout(i) = arrin(i) * arrin(i) -; END DO -; END SUBROUTINE test -; END MODULE testmod - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i32:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_real(kind=8)" = type { i8*, i32, i32, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i32, i32, i32 } - -@arrin = unnamed_addr global %"struct.array1_real(kind=8)" zeroinitializer, align 32 -@arrout = unnamed_addr global %"struct.array1_real(kind=8)" zeroinitializer, align 32 - -; Function Attrs: nounwind uwtable -define void @__src_soil_MOD_terra1() unnamed_addr #0 { -entry: - br label %entry.split - -entry.split: ; preds = %entry - %rawmemin1 = load i32*, i32** bitcast (%"struct.array1_real(kind=8)"* @arrin to i32**), align 32, !tbaa !0 - %rawmemout2 = load i32*, i32** bitcast (%"struct.array1_real(kind=8)"* @arrout to i32**), align 32, !tbaa !0 - br label %for.body - -for.body: ; preds = %entry.split, %for.body - %indvars.iv = phi i64 [ 1, %entry.split ], [ %indvars.iv.next4, %for.body ] - %inslot = getelementptr inbounds i32, i32* %rawmemin1, i64 %indvars.iv - %inval = load i32, i32* %inslot, align 8 - %outslot = getelementptr inbounds i32, i32* %rawmemout2, i64 %indvars.iv - %out = mul nsw i32 %inval, %inval - store i32 %out, i32* %outslot, align 8 - %indvars.iv.next4 = add nuw nsw i64 %indvars.iv, 1 - %exitcond = icmp eq i64 %indvars.iv.next4, 100 - br i1 %exitcond, label %return, label %for.body - -return: ; preds = %for.body - ret void -} - -attributes #0 = { nounwind uwtable } - -!0 = !{!1, !1, i32 0} -!1 = !{!"alias set 3: void*", !2} -!2 = distinct !{!2} - - -; CHECK: %MemRef_rawmemin1_end = load i32, i32* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @arrin, i64 0, i32 3, i64 0, i32 2) -; CHECK-NEXT: %MemRef_rawmemin1_begin = load i32, i32* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @arrin, i64 0, i32 3, i64 0, i32 1) -; CHECK-NEXT: %MemRef_rawmemin1_end_begin_delta = sub nsw i32 %MemRef_rawmemin1_end, %MemRef_rawmemin1_begin -; CHECK-NEXT: %MemRef_rawmemin1_size = add nsw i32 %MemRef_rawmemin1_end, 1 -; CHECK-NEXT: %MemRef_rawmemout2_end = load i32, i32* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @arrout, i64 0, i32 3, i64 0, i32 2) -; CHECK-NEXT: %MemRef_rawmemout2_begin = load i32, i32* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @arrout, i64 0, i32 3, i64 0, i32 1) -; CHECK-NEXT: %MemRef_rawmemout2_end_begin_delta = sub nsw i32 %MemRef_rawmemout2_end, %MemRef_rawmemout2_begin -; CHECK-NEXT: %MemRef_rawmemout2_size = add nsw i32 %MemRef_rawmemout2_end, 1 diff --git a/polly/test/GPGPU/check-unused-fortran-array-size-param-offloaded-to-kernel.ll b/polly/test/GPGPU/check-unused-fortran-array-size-param-offloaded-to-kernel.ll deleted file mode 100644 index d7ef8cec86c5a..0000000000000 --- a/polly/test/GPGPU/check-unused-fortran-array-size-param-offloaded-to-kernel.ll +++ /dev/null @@ -1,103 +0,0 @@ -; RUN: opt %loadPolly -analyze -polly-scops \ -; RUN: -polly-detect-fortran-arrays \ -; RUN: -polly-invariant-load-hoisting \ -; RUN: -polly-use-llvm-names \ -; RUN: -polly-stmt-granularity=bb \ -; RUN: < %s | FileCheck %s --check-prefix=SCOP - -; RUN: opt %loadPolly -S \ -; RUN: -polly-detect-fortran-arrays \ -; RUN: -polly-codegen-ppcg \ -; RUN: -polly-invariant-load-hoisting \ -; RUN: -polly-use-llvm-names \ -; RUN: -polly-acc-fail-on-verify-module-failure \ -; RUN: < %s | FileCheck %s --check-prefix=HOST-IR - -; REQUIRES: pollyacc - -; In Polly, we specifically add a parameter to represent the outermost dimension -; size of fortran arrays. We do this because this information is statically -; available from the fortran metadata generated by dragonegg. -; However, we were only materializing these parameters (meaning, creating an -; llvm::Value to back the isl_id) from *memory accesses*. This is wrong, -; we should materialize parameters from *scop array info*. - -; It is wrong because if there is a case where we detect 2 fortran arrays, -; but only one of them is accessed, we may not materialize the other array's -; dimensions at all. - -; This test case checks that we do not fail if there is an array that does -; not have an access (In this case, `memory`), we still generate the -; parameter. - -; Check that we detect the function as a Scop. -; SCOP: Function: f -; SCOP-NEXT: Region: %loop.prepare---%for.exit -; SCOP-NEXT: Max Loop Depth: 1 - -; Check that we detect fortran arrays. -; SCOP: Arrays (Bounds as pw_affs) { -; SCOP: double* MemRef_global_arr[*]; // Element size 8 -; SCOP-NEXT: double MemRef_memory[ [MemRef_memory_fortranarr_size] -> { [] -> [(MemRef_memory_fortranarr_size)] } ]; [BasePtrOrigin: MemRef_global_arr] // Element size 8 -; SCOP-NEXT: double MemRef_memory2[ [MemRef_memory2_fortranarr_size] -> { [] -> [(MemRef_memory2_fortranarr_size)] } ]; [BasePtrOrigin: MemRef_global_arr] // Element size 8 -; SCOP-NEXT: } - -; Check that we have writes *only* into memory2, not into memory. -; SCOP: Statements { -; SCOP: Stmt_for_body -; SCOP: MustWriteAccess := [Reduction Type: NONE] [Fortran array descriptor: global_arr] [Scalar: 0] -; SCOP-NEXT: [start_val, end_val, offset, MemRef_memory_fortranarr_size, MemRef_memory2_fortranarr_size] -> { Stmt_for_body[i0] -> MemRef_memory2[start_val + offset + i0] }; -; SCOP-NEXT: ReadAccess := [Reduction Type: NONE] [Fortran array descriptor: global_arr] [Scalar: 0] -; SCOP-NEXT: [start_val, end_val, offset, MemRef_memory_fortranarr_size, MemRef_memory2_fortranarr_size] -> { Stmt_for_body[i0] -> MemRef_memory2[start_val + offset + i0] }; -; SCOP-NEXT: } - -; Check that we materialize the sizes and send it across to the kernel. -; HOST-IR: store i64 %MemRef_memory_size, i64* %polly_launch_0_param_4 -; HOST-IR: store i64 %MemRef_memory2_size, i64* %polly_launch_0_param_5 -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_real(kind=8)" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i64, i64, i64 } - -@global_arr = external unnamed_addr global %"struct.array1_real(kind=8)", align 32 - -; Function Attrs: nounwind uwtable -define void @f(i32* noalias %ipstart, i32* noalias %ipend) unnamed_addr #0 { -entry: - br label %loop.prepare - - -loop.prepare: ; preds = %"6", %"3.preheader" - %start.val = load i32, i32* %ipstart, align 4 - %end.val = load i32, i32* %ipend, align 4 - %should.loop = icmp sgt i32 %start.val, %end.val - br i1 %should.loop, label %for.exit, label %for.body - - -for.body: ; preds = %for.body, %"4.preheader" - %i = phi i32 [ %i.next, %for.body ], [ %start.val, %loop.prepare ] - %i.sext = sext i32 %i to i64 - %memory = load double*, double** bitcast (%"struct.array1_real(kind=8)"* @global_arr to double**), align 32 - %offset = load i64, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @global_arr, i64 0, i32 1), align 8 - %idx = add i64 %offset, %i.sext - %slot = getelementptr double, double* %memory, i64 %idx - store double 1.0, double* %slot, align 8 - - %memory2 = load double*, double** bitcast (%"struct.array1_real(kind=8)"* @global_arr to double**), align 32 - %offset2 = load i64, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @global_arr, i64 0, i32 1), align 8 - %idx2 = add i64 %offset2, %i.sext - %slot2 = getelementptr double, double* %memory2, i64 %idx2 - %val = load double, double* %slot2, align 8 - - %should.loopexit = icmp eq i32 %i, %end.val - %i.next = add i32 %i, 1 - br i1 %should.loopexit, label %for.exit, label %for.body - -for.exit: ; preds = %for.body - ret void -} - -attributes #0 = { nounwind uwtable } diff --git a/polly/test/RewriteByReferenceParameters/fortran_io.ll b/polly/test/RewriteByReferenceParameters/fortran_io.ll deleted file mode 100644 index bc372c4754c0f..0000000000000 --- a/polly/test/RewriteByReferenceParameters/fortran_io.ll +++ /dev/null @@ -1,40 +0,0 @@ -; RUN: opt %loadPolly -polly-rewrite-byref-params -S < %s \ -; RUN: | FileCheck %s - - -; Verify that we rewrite the read-only by-reference into a separate alloca slot. -; This is useful in case %j3 is an induction variable, which should be promoted -; by -mem2reg into a register. - -; CHECK: define void @foo(%struct.__st_parameter_dt* %p) { -; CHECK-NEXT: entry: -; CHECK-NEXT: %polly_byref_alloca_j3 = alloca i32 -; CHECK-NEXT: %j3 = alloca i32, align 4 -; CHECK-NEXT: %tmp = bitcast i32* %j3 to i8* -; CHECK-NEXT: br label %bb - -; CHECK: bb: ; preds = %entry -; CHECK-NEXT: %polly_byref_load_j3 = load i32, i32* %j3 -; CHECK-NEXT: store i32 %polly_byref_load_j3, i32* %polly_byref_alloca_j3 -; CHECK-NEXT: %polly_byref_cast_j3 = bitcast i32* %polly_byref_alloca_j3 to i8* -; CHECK-NEXT: call void @_gfortran_transfer_integer_write(%struct.__st_parameter_dt* %p, i8* %polly_byref_cast_j3, i32 4) -; CHECK-NEXT: ret void -; CHECK-NEXT: } - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -%struct.__st_parameter_dt = type { } - -declare void @_gfortran_transfer_integer_write(%struct.__st_parameter_dt*, i8*, i32) - -define void @foo(%struct.__st_parameter_dt* %p) { -entry: - %j3 = alloca i32, align 4 - %tmp = bitcast i32* %j3 to i8* - br label %bb - -bb: - call void @_gfortran_transfer_integer_write(%struct.__st_parameter_dt* %p, i8* %tmp, i32 4) - ret void -} diff --git a/polly/test/ScopInfo/fortran_array_global_malloc_nonvectored.ll b/polly/test/ScopInfo/fortran_array_global_malloc_nonvectored.ll deleted file mode 100644 index eceef8b752371..0000000000000 --- a/polly/test/ScopInfo/fortran_array_global_malloc_nonvectored.ll +++ /dev/null @@ -1,116 +0,0 @@ -; RUN: opt %loadPolly -analyze -S -polly-detect-fortran-arrays \ -; RUN: -polly-process-unprofitable -polly-scops < %s | FileCheck %s - -; MODULE src_soil -; USE data_parameters, ONLY : & -; wp, & ! KIND-type parameter for real variables -; iintegers ! KIND-type parameter for standard integer variables -; IMPLICIT NONE -; REAL (KIND = wp), ALLOCATABLE, PRIVATE :: & -; xdzs (:) -; CONTAINS -; SUBROUTINE terra1(n) -; INTEGER, intent(in) :: n -; INTEGER (KIND=iintegers) :: & -; j -; Allocate(xdzs(n)); -; DO j = 2, n -; xdzs(j) = xdzs(j) * xdzs(j) + xdzs(j - 1) -; END DO -; END SUBROUTINE terra1 -; END MODULE src_soil - - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_real(kind=8)" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i64, i64, i64 } - -@__src_soil_MOD_xdzs = unnamed_addr global %"struct.array1_real(kind=8)" zeroinitializer, align 32 -@.cst = private unnamed_addr constant [67 x i8] c"Integer overflow when calculating the amount of memory to allocate\00", align 64 -@.cst1 = private unnamed_addr constant [37 x i8] c"Allocation would exceed memory limit\00", align 64 -@.cst2 = private unnamed_addr constant [93 x i8] c"At line 23 of file /home/siddhart/cosmo-self-installation/cosmo-pompa/cosmo/src/src_soil.f90\00", align 64 -@.cst3 = private unnamed_addr constant [55 x i8] c"Attempting to allocate already allocated variable '%s'\00", align 64 -@.cst4 = private unnamed_addr constant [5 x i8] c"xdzs\00", align 8 - -; Function Attrs: nounwind uwtable -define void @__src_soil_MOD_terra1(i32* noalias nocapture %n) unnamed_addr #0 { -entry: - br label %entry.split - -entry.split: ; preds = %entry - store i64 537, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 2), align 16, !tbaa !0 - store i64 1, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 3, i64 0, i32 1), align 8, !tbaa !0 - %tmp = load i32, i32* %n, align 4, !tbaa !3 - %tmp1 = sext i32 %tmp to i64 - store i64 %tmp1, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 3, i64 0, i32 2), align 8, !tbaa !0 - store i64 1, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 3, i64 0, i32 0), align 8, !tbaa !0 - %tmp2 = icmp slt i32 %tmp, 1 - %tmp3 = zext i32 %tmp to i64 - %tmp4 = shl nuw nsw i64 %tmp3, 3 - %.24 = select i1 %tmp2, i64 0, i64 %tmp4 - %tmp5 = icmp ne i64 %.24, 0 - %tmp6 = select i1 %tmp5, i64 %.24, i64 1 - %tmp7 = tail call noalias i8* @malloc(i64 %tmp6) #2 - store i8* %tmp7, i8** getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 0), align 32, !tbaa !5 - store i64 -1, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 1), align 8, !tbaa !0 - %tmp8 = icmp sgt i32 %tmp, 1 - br i1 %tmp8, label %"21.preheader", label %return - -"21.preheader": ; preds = %entry.split - %tmp9 = bitcast i8* %tmp7 to double* - %tmp10 = add i32 %tmp, 1 - br label %"21" - -"21": ; preds = %"21", %"21.preheader" - %tmp11 = phi double [ undef, %"21.preheader" ], [ %tmp16, %"21" ] - %indvars.iv = phi i64 [ 2, %"21.preheader" ], [ %indvars.iv.next, %"21" ] - %tmp12 = add nsw i64 %indvars.iv, -1 - %tmp13 = getelementptr inbounds double, double* %tmp9, i64 %tmp12 - %tmp14 = load double, double* %tmp13, align 8, !tbaa !7 - %tmp15 = fmul double %tmp14, %tmp14 - %tmp16 = fadd double %tmp11, %tmp15 - store double %tmp16, double* %tmp13, align 8, !tbaa !7 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32 - %exitcond2 = icmp eq i32 %lftr.wideiv1, %tmp10 - br i1 %exitcond2, label %return.loopexit, label %"21" - -return.loopexit: ; preds = %"21" - br label %return - -return: ; preds = %return.loopexit, %entry.split - ret void -} - -; Function Attrs: noreturn -declare void @_gfortran_runtime_error(i8*, ...) #1 - -; Function Attrs: nounwind -declare noalias i8* @malloc(i64) #2 - -; Function Attrs: noreturn -declare void @_gfortran_os_error(i8*) #1 - -; Function Attrs: noreturn -declare void @_gfortran_runtime_error_at(i8*, i8*, ...) #1 - -attributes #0 = { nounwind uwtable } -attributes #1 = { noreturn } -attributes #2 = { nounwind } - -!0 = !{!1, !1, i64 0} -!1 = !{!"alias set 4: integer(kind=8)", !2} -!2 = distinct !{!2} -!3 = !{!4, !4, i64 0} -!4 = !{!"alias set 11: integer(kind=4)", !2} -!5 = !{!6, !6, i64 0} -!6 = !{!"alias set 3: void*", !2} -!7 = !{!8, !8, i64 0} -!8 = !{!"alias set 18: real(kind=8)", !2} - -; CHECK: ReadAccess := [Reduction Type: NONE] [Fortran array descriptor: __src_soil_MOD_xdzs] [Scalar: 0] -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Fortran array descriptor: __src_soil_MOD_xdzs] [Scalar: 0] diff --git a/polly/test/ScopInfo/fortran_array_global_nonmalloc_nonvectored.ll b/polly/test/ScopInfo/fortran_array_global_nonmalloc_nonvectored.ll deleted file mode 100644 index 9e7e37b49ecb8..0000000000000 --- a/polly/test/ScopInfo/fortran_array_global_nonmalloc_nonvectored.ll +++ /dev/null @@ -1,89 +0,0 @@ -; RUN: opt %loadPolly -analyze -S -polly-detect-fortran-arrays \ -; RUN: -polly-process-unprofitable -polly-scops < %s | FileCheck %s - -; MODULE src_soil -; USE data_parameters, ONLY : & -; wp, & ! KIND-type parameter for real variables -; iintegers ! KIND-type parameter for standard integer variables -; IMPLICIT NONE -; REAL (KIND = wp), ALLOCATABLE, PRIVATE :: & -; xdzs (:) -; CONTAINS -; -; SUBROUTINE terra1(n) -; INTEGER, intent(in) :: n -; -; INTEGER (KIND=iintegers) :: & -; j -; -; DO j = 22, n -; xdzs(j) = xdzs(j) * xdzs(j) + xdzs(j - 1) -; END DO -; END SUBROUTINE terra1 -; END MODULE src_soil - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_real(kind=8)" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i64, i64, i64 } - -@__src_soil_MOD_xdzs = unnamed_addr global %"struct.array1_real(kind=8)" zeroinitializer, align 32 - -; Function Attrs: nounwind uwtable -define void @__src_soil_MOD_terra1(i32* noalias nocapture %n) unnamed_addr #0 { -entry: - br label %entry.split - -entry.split: ; preds = %entry - %tmp = load i32, i32* %n, align 4, !tbaa !0 - %tmp1 = icmp sgt i32 %tmp, 21 - br i1 %tmp1, label %"3.preheader", label %return - -"3.preheader": ; preds = %entry.split - %tmp2 = load i64, i64* getelementptr inbounds (%"struct.array1_real(kind=8)", %"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs, i64 0, i32 1), align 8, !tbaa !3 - %tmp3 = load double*, double** bitcast (%"struct.array1_real(kind=8)"* @__src_soil_MOD_xdzs to double**), align 32, !tbaa !5 - %tmp4 = add i32 %tmp, 1 - br label %"3" - -"3": ; preds = %"3", %"3.preheader" - %indvars.iv = phi i64 [ 22, %"3.preheader" ], [ %indvars.iv.next, %"3" ] - %tmp5 = add nsw i64 %indvars.iv, %tmp2 - %tmp6 = getelementptr inbounds double, double* %tmp3, i64 %tmp5 - %tmp7 = load double, double* %tmp6, align 8, !tbaa !7 - %tmp8 = fmul double %tmp7, %tmp7 - %tmp9 = add i64 %tmp2, -1 - %tmp10 = add i64 %tmp9, %indvars.iv - %tmp11 = getelementptr inbounds double, double* %tmp3, i64 %tmp10 - %tmp12 = load double, double* %tmp11, align 8, !tbaa !7 - %tmp13 = fadd double %tmp8, %tmp12 - store double %tmp13, double* %tmp6, align 8, !tbaa !7 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32 - %exitcond2 = icmp eq i32 %lftr.wideiv1, %tmp4 - br i1 %exitcond2, label %return.loopexit, label %"3" - -return.loopexit: ; preds = %"3" - br label %return - -return: ; preds = %return.loopexit, %entry.split - ret void -} - -attributes #0 = { nounwind uwtable } - -!0 = !{!1, !1, i64 0} -!1 = !{!"alias set 11: integer(kind=4)", !2} -!2 = distinct !{!2} -!3 = !{!4, !4, i64 0} -!4 = !{!"alias set 4: integer(kind=8)", !2} -!5 = !{!6, !6, i64 0} -!6 = !{!"alias set 3: void*", !2} -!7 = !{!8, !8, i64 0} -!8 = !{!"alias set 18: real(kind=8)", !2} - -; CHECK: ReadAccess := [Reduction Type: NONE] [Fortran array descriptor: __src_soil_MOD_xdzs] [Scalar: 0] -; CHECK: ReadAccess := [Reduction Type: NONE] [Fortran array descriptor: __src_soil_MOD_xdzs] [Scalar: 0] -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Fortran array descriptor: __src_soil_MOD_xdzs] [Scalar: 0] diff --git a/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored.ll b/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored.ll deleted file mode 100644 index 6e86bcea0e550..0000000000000 --- a/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored.ll +++ /dev/null @@ -1,68 +0,0 @@ -; RUN: opt %loadPolly -analyze -polly-detect-fortran-arrays \ -; RUN: -polly-scops -polly-allow-nonaffine -polly-invariant-load-hoisting < %s | FileCheck %s - -; This testcase is the corresponding LLVM for testfunc: -; PROGRAM main -; INTEGER, DIMENSION(1) :: xs -; -; CALL testfunc(xs, 10) -; CONTAINS -; SUBROUTINE func(xs, n) -; IMPLICIT NONE -; INTEGER, DIMENSION(:), INTENT(INOUT) :: xs -; INTEGER, INTENT(IN) :: n -; INTEGER :: i - -; DO i = 1, n -; xs(i) = 1 -; END DO -; -; END SUBROUTINE func -; END PROGRAM - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_integer(kind=4)" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i64, i64, i64 } - -define internal void @testfunc(%"struct.array1_integer(kind=4)"* noalias %xs, i32* noalias %n) { -entry: - br label %entry.split - -entry.split: ; preds = %entry - %tmp = getelementptr inbounds %"struct.array1_integer(kind=4)", %"struct.array1_integer(kind=4)"* %xs, i64 0, i32 3, i64 0, i32 0 - %tmp1 = load i64, i64* %tmp, align 8 - %tmp2 = icmp eq i64 %tmp1, 0 - %tmp3 = select i1 %tmp2, i64 1, i64 %tmp1 - %tmp4 = bitcast %"struct.array1_integer(kind=4)"* %xs to i32** - %tmp5 = load i32*, i32** %tmp4, align 8 - %tmp6 = load i32, i32* %n, align 4 - %tmp7 = icmp sgt i32 %tmp6, 0 - br i1 %tmp7, label %"6.preheader", label %return - -"6.preheader": ; preds = %entry.split - br label %"6" - -"6": ; preds = %"6", %"6.preheader" - %tmp8 = phi i32 [ %tmp14, %"6" ], [ 1, %"6.preheader" ] - %tmp9 = sext i32 %tmp8 to i64 - %tmp10 = mul i64 %tmp3, %tmp9 - %tmp11 = sub i64 %tmp10, %tmp3 - %tmp12 = getelementptr i32, i32* %tmp5, i64 %tmp11 - ; store - store i32 1, i32* %tmp12, align 4 - %tmp13 = icmp eq i32 %tmp8, %tmp6 - %tmp14 = add i32 %tmp8, 1 - br i1 %tmp13, label %return.loopexit, label %"6" - -return.loopexit: ; preds = %"6" - br label %return - -return: ; preds = %return.loopexit, %entry.split - ret void -} - -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Fortran array descriptor: xs] [Scalar: 0] diff --git a/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored_read_and_write.ll b/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored_read_and_write.ll deleted file mode 100644 index 480eb2ed5774e..0000000000000 --- a/polly/test/ScopInfo/fortran_array_param_nonmalloc_nonvectored_read_and_write.ll +++ /dev/null @@ -1,93 +0,0 @@ -; RUN: opt %loadPolly -analyze -polly-detect-fortran-arrays \ -; RUN: -polly-scops -polly-allow-nonaffine -polly-ignore-aliasing < %s | FileCheck %s - -; PROGRAM main -; ... -; CONTAINS -; SUBROUTINE copy(xs, ys, n) -; IMPLICIT NONE -; INTEGER, DIMENSION(:), INTENT(INOUT) :: xs, ys -; INTEGER, INTENT(IN) :: n -; INTEGER :: i -; -; DO i = 1, n -; ys(i * i) = xs(i * i) -; END DO -; -; END SUBROUTINE copy -; END PROGRAM - -target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-unknown-linux-gnu" - -module asm "\09.ident\09\22GCC: (GNU) 4.6.4 LLVM: 3.3.1\22" - -%"struct.array1_integer(kind=4)" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.descriptor_dimension = type { i64, i64, i64 } -%"struct.array1_integer(kind=4).0" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%"struct.array1_integer(kind=4).1" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%"struct.array1_integer(kind=4).2" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } -%struct.__st_parameter_dt = type { %struct.__st_parameter_common, i64, i64*, i64*, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, [256 x i8], i32*, i64, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, [4 x i8] } -%struct.__st_parameter_common = type { i32, i32, i8*, i32, i32, i8*, i32* } -%"struct.array1_integer(kind=4).3" = type { i8*, i64, i64, [1 x %struct.descriptor_dimension] } - -@0 = internal constant i32 10 -@.cst = private constant [12 x i8] c"program.f90\00", align 8 -@options.12.1603 = internal constant [8 x i32] [i32 68, i32 511, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1], align 32 - -; Function Attrs: nounwind uwtable -define internal void @copy.1550(%"struct.array1_integer(kind=4)"* noalias %xs, %"struct.array1_integer(kind=4).0"* noalias %ys, i32* noalias %n) { -entry: - br label %entry.split - -entry.split: ; preds = %entry - %0 = getelementptr inbounds %"struct.array1_integer(kind=4).0", %"struct.array1_integer(kind=4).0"* %ys, i64 0, i32 3, i64 0, i32 0 - %1 = load i64, i64* %0, align 8 - %2 = icmp eq i64 %1, 0 - %3 = select i1 %2, i64 1, i64 %1 - %4 = bitcast %"struct.array1_integer(kind=4).0"* %ys to i32** - %5 = load i32*, i32** %4, align 8 - %6 = getelementptr inbounds %"struct.array1_integer(kind=4)", %"struct.array1_integer(kind=4)"* %xs, i64 0, i32 3, i64 0, i32 0 - %7 = load i64, i64* %6, align 8 - %8 = icmp eq i64 %7, 0 - %. = select i1 %8, i64 1, i64 %7 - %9 = bitcast %"struct.array1_integer(kind=4)"* %xs to i32** - %10 = load i32*, i32** %9, align 8 - %11 = load i32, i32* %n, align 4 - %12 = icmp sgt i32 %11, 0 - br i1 %12, label %"9.preheader", label %return - -"9.preheader": ; preds = %entry.split - br label %"9" - -"9": ; preds = %"9.preheader", %"9" - %13 = phi i32 [ %26, %"9" ], [ 1, %"9.preheader" ] - %14 = mul i32 %13, %13 - %15 = sext i32 %14 to i64 - %16 = mul i64 %3, %15 - %17 = sub i64 %16, %3 - %18 = mul i32 %13, %13 - %19 = sext i32 %18 to i64 - %20 = mul i64 %., %19 - %21 = sub i64 %20, %. - %22 = getelementptr i32, i32* %10, i64 %21 - ; load - %23 = load i32, i32* %22, align 4 - %24 = getelementptr i32, i32* %5, i64 %17 - ; write - store i32 %23, i32* %24, align 4 - %25 = icmp eq i32 %13, %11 - %26 = add i32 %13, 1 - br i1 %25, label %return.loopexit, label %"9" - -return.loopexit: ; preds = %"9" - br label %return - -return: ; preds = %return.loopexit, %entry.split - ret void -} - -; CHECK: ReadAccess := [Reduction Type: NONE] [Fortran array descriptor: xs] [Scalar: 0] -; CHECK-NEXT: [p_0_loaded_from_n, MemRef0_fortranarr_size, MemRef1_fortranarr_size] -> { Stmt_9[i0] -> MemRef0[o0] }; -; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Fortran array descriptor: ys] [Scalar: 0] -; CHECK-NEXT: [p_0_loaded_from_n, MemRef0_fortranarr_size, MemRef1_fortranarr_size] -> { Stmt_9[i0] -> MemRef1[o0] };