@@ -41,10 +41,6 @@ static cl::opt<bool> UseFixedSizeArrayHeuristic(
4141 cl::desc(" When printing analysis, use the heuristic for fixed-size arrays "
4242 " if the default delinearizetion fails." ));
4343
44- static cl::opt<bool > useGEPToDelinearize (
45- " use-gep-to-delinearize" , cl::init(true ), cl::Hidden,
46- cl::desc(" validate both delinearization methods match." ));
47-
4844// Return true when S contains at least an undef value.
4945static inline bool containsUndefs (const SCEV *S) {
5046 return SCEVExprContains (S, [](const SCEV *S) {
@@ -848,56 +844,6 @@ bool llvm::delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
848844 return !Subscripts.empty ();
849845}
850846
851- bool llvm::getIndexExpressionsFromGEP (ScalarEvolution &SE,
852- const GetElementPtrInst *GEP,
853- SmallVectorImpl<const SCEV *> &Subscripts,
854- SmallVectorImpl<int > &Sizes) {
855- assert (Subscripts.empty () && Sizes.empty () &&
856- " Expected output lists to be empty on entry to this function." );
857- assert (GEP && " getIndexExpressionsFromGEP called with a null GEP" );
858- LLVM_DEBUG (dbgs () << " \n GEP to delinearize: " << *GEP << " \n " );
859- Type *Ty = nullptr ;
860- bool DroppedFirstDim = false ;
861- for (unsigned i = 1 ; i < GEP->getNumOperands (); i++) {
862- const SCEV *Expr = SE.getSCEV (GEP->getOperand (i));
863- if (i == 1 ) {
864- Ty = GEP->getSourceElementType ();
865- if (auto *Const = dyn_cast<SCEVConstant>(Expr))
866- if (Const->getValue ()->isZero ()) {
867- DroppedFirstDim = true ;
868- continue ;
869- }
870- Subscripts.push_back (Expr);
871- LLVM_DEBUG (dbgs () << " Subscripts push_back: " << *Expr << " \n " );
872- continue ;
873- }
874-
875- auto *ArrayTy = dyn_cast<ArrayType>(Ty);
876- if (!ArrayTy) {
877- LLVM_DEBUG (dbgs () << " GEP delinearize failed: " << *Ty
878- << " is not an array type.\n " );
879- Subscripts.clear ();
880- Sizes.clear ();
881- return false ;
882- }
883-
884- Subscripts.push_back (Expr);
885- LLVM_DEBUG (dbgs () << " Subscripts push_back: " << *Expr << " \n " );
886- if (!(DroppedFirstDim && i == 2 ))
887- Sizes.push_back (ArrayTy->getNumElements ());
888-
889- Ty = ArrayTy->getElementType ();
890- }
891- LLVM_DEBUG ({
892- dbgs () << " Subscripts:\n " ;
893- for (const SCEV *S : Subscripts)
894- dbgs () << *S << " \n " ;
895- dbgs () << " \n " ;
896- });
897-
898- return !Subscripts.empty ();
899- }
900-
901847bool llvm::tryDelinearizeFixedSizeImpl (
902848 ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn,
903849 SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<int > &Sizes) {
@@ -943,133 +889,15 @@ bool llvm::tryDelinearizeFixedSizeImpl(
943889 // Array_info delinearization.
944890 SmallVector<const SCEV *, 4 > SCEVSizes;
945891 const SCEV *ElementSize = SE->getElementSize (Inst);
946- bool ArrayInfoSuccess = delinearizeUsingArrayInfo (
947- *SE, AccessFn, ArrayInfoSubscripts, SCEVSizes, ElementSize);
892+ if (!delinearizeUsingArrayInfo (*SE, AccessFn, Subscripts, SCEVSizes,
893+ ElementSize))
894+ return false ;
948895
949896 // TODO: Remove the following code. Convert SCEV sizes to int sizes. This
950897 // conversion is only needed as long as getIndexExpressionsFromGEP is still
951898 // around. Remove this code and change the interface of
952899 // tryDelinearizeFixedSizeImpl to take a SmallVectorImpl<const SCEV *> &Sizes.
953- if (ArrayInfoSuccess)
954- convertSCEVSizesToIntSizes (SCEVSizes, ArrayInfoSizes);
955-
956- // Validate consistency between methods.
957- if (GEPSuccess && ArrayInfoSuccess) {
958- // If both methods succeeded, validate they produce the same results.
959- // Compare sizes arrays.
960- if (GEPSizes.size () + 2 != ArrayInfoSizes.size ()) {
961- LLVM_DEBUG ({
962- dbgs () << " WARN: Size arrays have different lengths!\n " ;
963- dbgs () << " GEP sizes count: " << GEPSizes.size () << " \n "
964- << " ArrayInfo sizes count: " << ArrayInfoSizes.size () << " \n " ;
965- });
966- }
967-
968- for (size_t i = 0 ; i < GEPSizes.size (); ++i) {
969- if (GEPSizes[i] != ArrayInfoSizes[i + 1 ]) {
970- LLVM_DEBUG ({
971- dbgs () << " WARN: Size arrays differ at index " << i << " !\n " ;
972- dbgs () << " GEP size[" << i << " ]: " << GEPSizes[i] << " \n "
973- << " ArrayInfo size[" << i + 1 << " ]: " << ArrayInfoSizes[i + 1 ]
974- << " \n " ;
975- });
976- }
977- }
978-
979- // Compare subscripts arrays.
980- if (GEPSubscripts.size () != ArrayInfoSubscripts.size ()) {
981- LLVM_DEBUG ({
982- dbgs () << " WARN: Subscript arrays have different lengths!\n " ;
983- dbgs () << " GEP subscripts count: " << GEPSubscripts.size () << " \n "
984- << " ArrayInfo subscripts count: " << ArrayInfoSubscripts.size ()
985- << " \n " ;
986-
987- dbgs () << " GEP subscripts:\n " ;
988- for (size_t i = 0 ; i < GEPSubscripts.size (); ++i)
989- dbgs () << " subscript[" << i << " ]: " << *GEPSubscripts[i] << " \n " ;
990-
991- dbgs () << " ArrayInfo subscripts:\n " ;
992- for (size_t i = 0 ; i < ArrayInfoSubscripts.size (); ++i)
993- dbgs () << " subscript[" << i << " ]: " << *ArrayInfoSubscripts[i]
994- << " \n " ;
995- });
996- }
997-
998- for (size_t i = 0 ; i < GEPSubscripts.size (); ++i) {
999- const SCEV *GEPS = GEPSubscripts[i];
1000- const SCEV *AIS = ArrayInfoSubscripts[i];
1001- // FIXME: there's no good way to compare two scevs: don't abort, warn.
1002- if (GEPS != AIS || !SE->getMinusSCEV (GEPS, AIS)->isZero ()) {
1003- LLVM_DEBUG ({
1004- dbgs () << " WARN: Subscript arrays differ at index " << i << " !\n " ;
1005- dbgs () << " GEP subscript[" << i << " ]: " << *GEPSubscripts[i]
1006- << " \n "
1007- << " ArrayInfo subscript[" << i
1008- << " ]: " << *ArrayInfoSubscripts[i] << " \n " ;
1009- });
1010- }
1011- }
1012-
1013- LLVM_DEBUG (dbgs () << " SUCCESS: Both delinearization methods produced "
1014- " identical results\n " );
1015- } else if (GEPSuccess && !ArrayInfoSuccess) {
1016- LLVM_DEBUG ({
1017- dbgs () << " WARNING: array_info failed and GEP analysis succeeded.\n " ;
1018- dbgs () << " Instruction: " << *Inst << " \n " ;
1019- dbgs () << " Using GEP analysis results despite array_info failure\n " ;
1020- });
1021- } else if (!GEPSuccess && ArrayInfoSuccess) {
1022- LLVM_DEBUG ({
1023- dbgs () << " WARNING: GEP failed and array_info analysis succeeded.\n " ;
1024- dbgs () << " Instruction: " << *Inst << " \n " ;
1025- dbgs () << " Using array_info analysis results despite GEP failure\n " ;
1026- });
1027- } else if (!GEPSuccess && !ArrayInfoSuccess) {
1028- LLVM_DEBUG ({
1029- dbgs () << " WARNING: both GEP and array_info analysis failed.\n " ;
1030- dbgs () << " Instruction: " << *Inst << " \n " ;
1031- });
1032- }
1033-
1034- // Choose which result to use.
1035- // Prefer array_info when available.
1036- if (ArrayInfoSuccess) {
1037- Subscripts = std::move (ArrayInfoSubscripts);
1038- Sizes = std::move (ArrayInfoSizes);
1039- return true ;
1040- }
1041-
1042- // Both failed.
1043- if (!GEPSuccess)
1044- return false ;
1045-
1046- // Return GEP-based delinearization.
1047- Subscripts = std::move (GEPSubscripts);
1048- Sizes = std::move (GEPSizes);
1049-
1050- // Check that the two size arrays are non-empty and equal in length and
1051- // value.
1052- // TODO: it would be better to let the caller to clear Subscripts, similar
1053- // to how we handle Sizes.
1054- if (Sizes.empty () || Subscripts.size () <= 1 ) {
1055- Subscripts.clear ();
1056- return false ;
1057- }
1058-
1059- // Check that for identical base pointers we do not miss index offsets
1060- // that have been added before this GEP is applied.
1061- Value *SrcBasePtr = SrcGEP->getOperand (0 )->stripPointerCasts ();
1062- const SCEVUnknown *SrcBase =
1063- dyn_cast<SCEVUnknown>(SE->getPointerBase (AccessFn));
1064- if (!SrcBase || SrcBasePtr != SrcBase->getValue ()) {
1065- Subscripts.clear ();
1066- return false ;
1067- }
1068-
1069- assert (Subscripts.size () == Sizes.size () + 1 &&
1070- " Expected equal number of entries in the list of size and "
1071- " subscript." );
1072-
900+ convertSCEVSizesToIntSizes (SCEVSizes, Sizes);
1073901 return true ;
1074902}
1075903
0 commit comments