X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.cpp;h=9244cf6ceb6d9002add6f455281f4b7e993ba3b0;hb=d538e249224a91f85bd4297c71b2bfa71113a9ad;hp=5e1d3ae9dc455aee267f3287eaf891ea4a6029d7;hpb=6032269837c08a94b70b0e36f8e473c293ff5fd4;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 5e1d3ae9dc4..9244cf6ceb6 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -344,52 +344,155 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { if (!hasVectorTypes()) MadeChange |= EnforceScalar(TP); - // This code does not currently handle nodes which have multiple types, - // where some types are integer, and some are fp. Assert that this is not - // the case. - assert(!(hasIntegerTypes() && hasFloatingPointTypes()) && - !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && - "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); + if (TypeVec.size() == 1 && Other.TypeVec.size() == 1) { + // If we are down to concrete types, this code does not currently + // handle nodes which have multiple types, where some types are + // integer, and some are fp. Assert that this is not the case. + assert(!(hasIntegerTypes() && hasFloatingPointTypes()) && + !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && + "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); + + // Otherwise, if these are both vector types, either this vector + // must have a larger bitsize than the other, or this element type + // must be larger than the other. + EVT Type(TypeVec[0]); + EVT OtherType(Other.TypeVec[0]); + + if (hasVectorTypes() && Other.hasVectorTypes()) { + if (Type.getSizeInBits() >= OtherType.getSizeInBits()) + if (Type.getVectorElementType().getSizeInBits() + >= OtherType.getVectorElementType().getSizeInBits()) + TP.error("Type inference contradiction found, '" + + getName() + "' element type not smaller than '" + + Other.getName() +"'!"); + } + else + // For scalar types, the bitsize of this type must be larger + // than that of the other. + if (Type.getSizeInBits() >= OtherType.getSizeInBits()) + TP.error("Type inference contradiction found, '" + + getName() + "' is not smaller than '" + + Other.getName() +"'!"); + + } + + + // Handle int and fp as disjoint sets. This won't work for patterns + // that have mixed fp/int types but those are likely rare and would + // not have been accepted by this code previously. // Okay, find the smallest type from the current set and remove it from the // largest set. - MVT::SimpleValueType Smallest = TypeVec[0]; + MVT::SimpleValueType SmallestInt; + for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) + if (isInteger(TypeVec[i])) { + SmallestInt = TypeVec[i]; + break; + } for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) - if (TypeVec[i] < Smallest) - Smallest = TypeVec[i]; + if (isInteger(TypeVec[i]) && TypeVec[i] < SmallestInt) + SmallestInt = TypeVec[i]; + + MVT::SimpleValueType SmallestFP; + for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) + if (isFloatingPoint(TypeVec[i])) { + SmallestFP = TypeVec[i]; + break; + } + for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) + if (isFloatingPoint(TypeVec[i]) && TypeVec[i] < SmallestFP) + SmallestFP = TypeVec[i]; + + int OtherIntSize = 0; + int OtherFPSize = 0; + for (SmallVector::iterator TVI = + Other.TypeVec.begin(); + TVI != Other.TypeVec.end(); + /* NULL */) { + if (isInteger(*TVI)) { + ++OtherIntSize; + if (*TVI == SmallestInt) { + TVI = Other.TypeVec.erase(TVI); + --OtherIntSize; + MadeChange = true; + continue; + } + } + else if (isFloatingPoint(*TVI)) { + ++OtherFPSize; + if (*TVI == SmallestFP) { + TVI = Other.TypeVec.erase(TVI); + --OtherFPSize; + MadeChange = true; + continue; + } + } + ++TVI; + } // If this is the only type in the large set, the constraint can never be // satisfied. - if (Other.TypeVec.size() == 1 && Other.TypeVec[0] == Smallest) + if ((Other.hasIntegerTypes() && OtherIntSize == 0) + || (Other.hasFloatingPointTypes() && OtherFPSize == 0)) TP.error("Type inference contradiction found, '" + Other.getName() + "' has nothing larger than '" + getName() +"'!"); - SmallVector::iterator TVI = - std::find(Other.TypeVec.begin(), Other.TypeVec.end(), Smallest); - if (TVI != Other.TypeVec.end()) { - Other.TypeVec.erase(TVI); - MadeChange = true; - } - // Okay, find the largest type in the Other set and remove it from the // current set. - MVT::SimpleValueType Largest = Other.TypeVec[0]; + MVT::SimpleValueType LargestInt = Other.TypeVec[0]; + for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) + if (isInteger(Other.TypeVec[i])) { + LargestInt = Other.TypeVec[i]; + break; + } for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) - if (Other.TypeVec[i] > Largest) - Largest = Other.TypeVec[i]; + if (isInteger(Other.TypeVec[i]) && Other.TypeVec[i] > LargestInt) + LargestInt = Other.TypeVec[i]; + + MVT::SimpleValueType LargestFP; + for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) + if (isFloatingPoint(Other.TypeVec[i])) { + LargestFP = Other.TypeVec[i]; + break; + } + for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) + if (isFloatingPoint(Other.TypeVec[i]) && Other.TypeVec[i] > LargestFP) + LargestFP = Other.TypeVec[i]; + + int IntSize = 0; + int FPSize = 0; + for (SmallVector::iterator TVI = + TypeVec.begin(); + TVI != TypeVec.end(); + /* NULL */) { + if (isInteger(*TVI)) { + ++IntSize; + if (*TVI == LargestInt) { + TVI = TypeVec.erase(TVI); + --IntSize; + MadeChange = true; + continue; + } + } + else if (isFloatingPoint(*TVI)) { + ++FPSize; + if (*TVI == LargestFP) { + TVI = TypeVec.erase(TVI); + --FPSize; + MadeChange = true; + continue; + } + } + ++TVI; + } // If this is the only type in the small set, the constraint can never be // satisfied. - if (TypeVec.size() == 1 && TypeVec[0] == Largest) + if ((hasIntegerTypes() && IntSize == 0) + || (hasFloatingPointTypes() && FPSize == 0)) TP.error("Type inference contradiction found, '" + getName() + "' has nothing smaller than '" + Other.getName()+"'!"); - TVI = std::find(TypeVec.begin(), TypeVec.end(), Largest); - if (TVI != TypeVec.end()) { - TypeVec.erase(TVI); - MadeChange = true; - } - return MadeChange; }