summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-07 09:21:09 +0000
committered <ed@FreeBSD.org>2009-06-07 09:21:09 +0000
commite65fe1a3e103e3aa81b69704d20eb95f54097271 (patch)
tree7faa7e6887831d68515763b37bd680e3d4a886ea
parent2361a5c2bfbaef476824e51fa72712e334219c7b (diff)
downloadFreeBSD-src-e65fe1a3e103e3aa81b69704d20eb95f54097271.zip
FreeBSD-src-e65fe1a3e103e3aa81b69704d20eb95f54097271.tar.gz
Import LLVM r73021.
-rw-r--r--docs/GoldPlugin.html4
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h14
-rw-r--r--include/llvm/DerivedTypes.h20
-rw-r--r--include/llvm/Type.h2
-rw-r--r--lib/Analysis/ScalarEvolution.cpp74
-rw-r--r--lib/AsmParser/LLParser.cpp14
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp115
-rw-r--r--lib/Target/PowerPC/PPCInstrAltivec.td22
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp166
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp3
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp6
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp6
-rw-r--r--lib/Transforms/Scalar/PredicateSimplifier.cpp27
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp4
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp3
-rw-r--r--lib/VMCore/Type.cpp88
-rw-r--r--lib/VMCore/Verifier.cpp73
-rw-r--r--test/CodeGen/PowerPC/vec_shift.ll10
-rw-r--r--test/CodeGen/X86/vec_loadsingles.ll12
-rw-r--r--test/CodeGen/X86/vec_set-5.ll3
-rw-r--r--test/CodeGen/X86/vec_set-6.ll2
-rw-r--r--test/Transforms/InstCombine/vec_demanded_elts-3.ll14
-rw-r--r--tools/gold/gold-plugin.cpp10
-rw-r--r--tools/llvmc/example/mcc16/Makefile24
-rw-r--r--tools/llvmc/example/mcc16/README75
-rw-r--r--tools/llvmc/example/mcc16/driver/Main.cpp14
-rw-r--r--tools/llvmc/example/mcc16/driver/Makefile22
-rw-r--r--tools/llvmc/example/mcc16/plugins/Makefile18
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile17
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td116
-rw-r--r--tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp1
31 files changed, 613 insertions, 366 deletions
diff --git a/docs/GoldPlugin.html b/docs/GoldPlugin.html
index 17a50ac..b5148ab 100644
--- a/docs/GoldPlugin.html
+++ b/docs/GoldPlugin.html
@@ -157,7 +157,7 @@ export AR="$PREFIX/bin/ar"
export NM="$PREFIX/bin/nm"
export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
export CFLAGS="-O4"
- </pre>
+</pre>
</li>
<li>Or you can just set your path:
<pre class="doc_code">
@@ -166,7 +166,7 @@ export CC="llvm-gcc -use-gold-plugin"
export CXX="llvm-g++ -use-gold-plugin"
export RANLIB=/bin/true
export CFLAGS="-O4"
- </pre>
+</pre>
</li>
<li>Configure &amp; build the project as usual: <tt>./configure &amp;&amp; make &amp;&amp; make check</tt> </li>
</ul>
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 88002cb..e3d4299 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -227,9 +227,9 @@ namespace llvm {
///
TargetData *TD;
- /// UnknownValue - This SCEV is used to represent unknown trip counts and
- /// things.
- SCEVHandle UnknownValue;
+ /// CouldNotCompute - This SCEV is used to represent unknown trip
+ /// counts and things.
+ SCEVHandle CouldNotCompute;
/// Scalars - This is a cache of the scalars we have analyzed so far.
///
@@ -322,23 +322,23 @@ namespace llvm {
/// a constant number of times (the condition evolves only from constants),
/// try to evaluate a few iterations of the loop until we get the exit
/// condition gets a value of ExitWhen (true or false). If we cannot
- /// evaluate the trip count of the loop, return UnknownValue.
+ /// evaluate the trip count of the loop, return CouldNotCompute.
SCEVHandle ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond,
bool ExitWhen);
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
- /// UnknownValue.
+ /// CouldNotCompute.
SCEVHandle HowFarToZero(const SCEV *V, const Loop *L);
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
- /// UnknownValue.
+ /// CouldNotCompute.
SCEVHandle HowFarToNonZero(const SCEV *V, const Loop *L);
/// HowManyLessThans - Return the number of times a backedge containing the
/// specified less-than comparison will execute. If not computable, return
- /// UnknownValue. isSigned specifies whether the less-than is signed.
+ /// CouldNotCompute. isSigned specifies whether the less-than is signed.
BackedgeTakenInfo HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool isSigned);
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index dd6d908..fa951bf 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -159,6 +159,10 @@ public:
/// type.
static bool isValidReturnType(const Type *RetTy);
+ /// isValidArgumentType - Return true if the specified type is valid as an
+ /// argument type.
+ static bool isValidArgumentType(const Type *ArgTy);
+
inline bool isVarArg() const { return isVarArgs; }
inline const Type *getReturnType() const { return ContainedTys[0]; }
@@ -232,6 +236,10 @@ public:
/// an empty struct, pass NULL, NULL.
static StructType *get(const Type *type, ...) END_WITH_NULL;
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
// Iterator access to the elements
typedef Type::subtype_iterator element_iterator;
element_iterator element_begin() const { return ContainedTys; }
@@ -331,6 +339,10 @@ public:
///
static ArrayType *get(const Type *ElementType, uint64_t NumElements);
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
inline uint64_t getNumElements() const { return NumElements; }
// Implement the AbstractTypeUser interface.
@@ -391,6 +403,10 @@ public:
return VectorType::get(EltTy, VTy->getNumElements());
}
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
/// @brief Return the number of elements in the Vector type.
inline unsigned getNumElements() const { return NumElements; }
@@ -431,6 +447,10 @@ public:
return PointerType::get(ElementType, 0);
}
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(const Type *ElemTy);
+
/// @brief Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return AddressSpace; }
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index 5ce23ef..c1732af 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -205,7 +205,7 @@ public:
inline bool isAbstract() const { return Abstract; }
/// canLosslesslyBitCastTo - Return true if this type could be converted
- /// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts
+ /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts
/// are valid for types of the same size only where no re-interpretation of
/// the bits is done.
/// @brief Determine if this type could be losslessly bitcast to Ty
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 03c5005..fd97db8 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -1771,7 +1771,7 @@ const Type *ScalarEvolution::getEffectiveSCEVType(const Type *Ty) const {
}
SCEVHandle ScalarEvolution::getCouldNotCompute() {
- return UnknownValue;
+ return CouldNotCompute;
}
/// hasSCEV - Return true if the SCEV for this value has already been
@@ -2395,7 +2395,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute()));
if (Pair.second) {
BackedgeTakenInfo ItCount = ComputeBackedgeTakenCount(L);
- if (ItCount.Exact != UnknownValue) {
+ if (ItCount.Exact != CouldNotCompute) {
assert(ItCount.Exact->isLoopInvariant(L) &&
ItCount.Max->isLoopInvariant(L) &&
"Computed trip count isn't loop invariant for loop!");
@@ -2464,20 +2464,20 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
// If the loop has a non-one exit block count, we can't analyze it.
BasicBlock *ExitBlock = L->getExitBlock();
if (!ExitBlock)
- return UnknownValue;
+ return CouldNotCompute;
// Okay, there is one exit block. Try to find the condition that causes the
// loop to be exited.
BasicBlock *ExitingBlock = L->getExitingBlock();
if (!ExitingBlock)
- return UnknownValue; // More than one block exiting!
+ return CouldNotCompute; // More than one block exiting!
// Okay, we've computed the exiting block. See what condition causes us to
// exit.
//
// FIXME: we should be able to handle switch instructions (with a single exit)
BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
- if (ExitBr == 0) return UnknownValue;
+ if (ExitBr == 0) return CouldNotCompute;
assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
// At this point, we know we have a conditional branch that determines whether
@@ -2493,7 +2493,7 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
if (ExitBr->getSuccessor(0) != L->getHeader() &&
ExitBr->getSuccessor(1) != L->getHeader() &&
ExitBr->getParent() != L->getHeader())
- return UnknownValue;
+ return CouldNotCompute;
ICmpInst *ExitCond = dyn_cast<ICmpInst>(ExitBr->getCondition());
@@ -2647,11 +2647,11 @@ SCEVHandle ScalarEvolution::
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
const Loop *L,
ICmpInst::Predicate predicate) {
- if (LI->isVolatile()) return UnknownValue;
+ if (LI->isVolatile()) return CouldNotCompute;
// Check to see if the loaded pointer is a getelementptr of a global.
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0));
- if (!GEP) return UnknownValue;
+ if (!GEP) return CouldNotCompute;
// Make sure that it is really a constant global we are gepping, with an
// initializer, and make sure the first IDX is really 0.
@@ -2659,7 +2659,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
GEP->getNumOperands() < 3 || !isa<Constant>(GEP->getOperand(1)) ||
!cast<Constant>(GEP->getOperand(1))->isNullValue())
- return UnknownValue;
+ return CouldNotCompute;
// Okay, we allow one non-constant index into the GEP instruction.
Value *VarIdx = 0;
@@ -2669,7 +2669,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(i))) {
Indexes.push_back(CI);
} else if (!isa<ConstantInt>(GEP->getOperand(i))) {
- if (VarIdx) return UnknownValue; // Multiple non-constant idx's.
+ if (VarIdx) return CouldNotCompute; // Multiple non-constant idx's.
VarIdx = GEP->getOperand(i);
VarIdxNum = i-2;
Indexes.push_back(0);
@@ -2686,7 +2686,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
if (!IdxExpr || !IdxExpr->isAffine() || IdxExpr->isLoopInvariant(L) ||
!isa<SCEVConstant>(IdxExpr->getOperand(0)) ||
!isa<SCEVConstant>(IdxExpr->getOperand(1)))
- return UnknownValue;
+ return CouldNotCompute;
unsigned MaxSteps = MaxBruteForceIterations;
for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) {
@@ -2713,7 +2713,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
return getConstant(ItCst); // Found terminating iteration!
}
}
- return UnknownValue;
+ return CouldNotCompute;
}
@@ -2852,11 +2852,11 @@ getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs, const Loop *L){
/// constant number of times (the condition evolves only from constants),
/// try to evaluate a few iterations of the loop until we get the exit
/// condition gets a value of ExitWhen (true or false). If we cannot
-/// evaluate the trip count of the loop, return UnknownValue.
+/// evaluate the trip count of the loop, return CouldNotCompute.
SCEVHandle ScalarEvolution::
ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) {
PHINode *PN = getConstantEvolvingPHI(Cond, L);
- if (PN == 0) return UnknownValue;
+ if (PN == 0) return CouldNotCompute;
// Since the loop is canonicalized, the PHI node must have two entries. One
// entry must be a constant (coming in from outside of the loop), and the
@@ -2864,11 +2864,11 @@ ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen)
bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1));
Constant *StartCST =
dyn_cast<Constant>(PN->getIncomingValue(!SecondIsBackedge));
- if (StartCST == 0) return UnknownValue; // Must be a constant.
+ if (StartCST == 0) return CouldNotCompute; // Must be a constant.
Value *BEValue = PN->getIncomingValue(SecondIsBackedge);
PHINode *PN2 = getConstantEvolvingPHI(BEValue, L);
- if (PN2 != PN) return UnknownValue; // Not derived from same PHI.
+ if (PN2 != PN) return CouldNotCompute; // Not derived from same PHI.
// Okay, we find a PHI node that defines the trip count of this loop. Execute
// the loop symbolically to determine when the condition gets a value of
@@ -2881,7 +2881,7 @@ ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen)
dyn_cast_or_null<ConstantInt>(EvaluateExpression(Cond, PHIVal));
// Couldn't symbolically evaluate.
- if (!CondVal) return UnknownValue;
+ if (!CondVal) return CouldNotCompute;
if (CondVal->getValue() == uint64_t(ExitWhen)) {
ConstantEvolutionLoopExitValue[PN] = PHIVal;
@@ -2892,12 +2892,12 @@ ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen)
// Compute the value of the PHI node for the next iteration.
Constant *NextPHI = EvaluateExpression(BEValue, PHIVal);
if (NextPHI == 0 || NextPHI == PHIVal)
- return UnknownValue; // Couldn't evaluate or not making progress...
+ return CouldNotCompute; // Couldn't evaluate or not making progress...
PHIVal = NextPHI;
}
// Too many iterations were needed to evaluate.
- return UnknownValue;
+ return CouldNotCompute;
}
/// getSCEVAtScope - Return a SCEV expression handle for the specified value
@@ -3052,7 +3052,7 @@ SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
// To evaluate this recurrence, we need to know how many times the AddRec
// loop iterates. Compute this now.
SCEVHandle BackedgeTakenCount = getBackedgeTakenCount(AddRec->getLoop());
- if (BackedgeTakenCount == UnknownValue) return AddRec;
+ if (BackedgeTakenCount == CouldNotCompute) return AddRec;
// Then, evaluate the AddRec.
return AddRec->evaluateAtIteration(BackedgeTakenCount, *this);
@@ -3201,18 +3201,18 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) {
}
/// HowFarToZero - Return the number of times a backedge comparing the specified
-/// value to zero will execute. If not computable, return UnknownValue.
+/// value to zero will execute. If not computable, return CouldNotCompute.
SCEVHandle ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
// If the value is a constant
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
// If the value is already zero, the branch will execute zero times.
if (C->getValue()->isZero()) return C;
- return UnknownValue; // Otherwise it will loop infinitely.
+ return CouldNotCompute; // Otherwise it will loop infinitely.
}
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V);
if (!AddRec || AddRec->getLoop() != L)
- return UnknownValue;
+ return CouldNotCompute;
if (AddRec->isAffine()) {
// If this is an affine expression, the execution count of this branch is
@@ -3274,12 +3274,12 @@ SCEVHandle ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
}
}
- return UnknownValue;
+ return CouldNotCompute;
}
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
-/// UnknownValue
+/// CouldNotCompute
SCEVHandle ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) {
// Loops that look like: while (X == 0) are very strange indeed. We don't
// handle them yet except for the trivial case. This could be expanded in the
@@ -3290,12 +3290,12 @@ SCEVHandle ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) {
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
if (!C->getValue()->isNullValue())
return getIntegerSCEV(0, C->getType());
- return UnknownValue; // Otherwise it will loop infinitely.
+ return CouldNotCompute; // Otherwise it will loop infinitely.
}
// We could implement others, but I really doubt anyone writes loops like
// this, and if they did, they would already be constant folded.
- return UnknownValue;
+ return CouldNotCompute;
}
/// getLoopPredecessor - If the given loop's header has exactly one unique
@@ -3446,16 +3446,16 @@ bool ScalarEvolution::isLoopGuardedByCond(const Loop *L,
/// HowManyLessThans - Return the number of times a backedge containing the
/// specified less-than comparison will execute. If not computable, return
-/// UnknownValue.
+/// CouldNotCompute.
ScalarEvolution::BackedgeTakenInfo ScalarEvolution::
HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool isSigned) {
// Only handle: "ADDREC < LoopInvariant".
- if (!RHS->isLoopInvariant(L)) return UnknownValue;
+ if (!RHS->isLoopInvariant(L)) return CouldNotCompute;
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS);
if (!AddRec || AddRec->getLoop() != L)
- return UnknownValue;
+ return CouldNotCompute;
if (AddRec->isAffine()) {
// FORNOW: We only support unit strides.
@@ -3466,7 +3466,7 @@ HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
// TODO: handle non-constant strides.
const SCEVConstant *CStep = dyn_cast<SCEVConstant>(Step);
if (!CStep || CStep->isZero())
- return UnknownValue;
+ return CouldNotCompute;
if (CStep->isOne()) {
// With unit stride, the iteration never steps past the limit value.
} else if (CStep->getValue()->getValue().isStrictlyPositive()) {
@@ -3477,19 +3477,19 @@ HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
APInt Max = APInt::getSignedMaxValue(BitWidth);
if ((Max - CStep->getValue()->getValue())
.slt(CLimit->getValue()->getValue()))
- return UnknownValue;
+ return CouldNotCompute;
} else {
APInt Max = APInt::getMaxValue(BitWidth);
if ((Max - CStep->getValue()->getValue())
.ult(CLimit->getValue()->getValue()))
- return UnknownValue;
+ return CouldNotCompute;
}
} else
// TODO: handle non-constant limit values below.
- return UnknownValue;
+ return CouldNotCompute;
} else
// TODO: handle negative strides below.
- return UnknownValue;
+ return CouldNotCompute;
// We know the LHS is of the form {n,+,s} and the RHS is some loop-invariant
// m. So, we count the number of iterations in which {n,+,s} < m is true.
@@ -3536,7 +3536,7 @@ HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
return BackedgeTakenInfo(BECount, MaxBECount);
}
- return UnknownValue;
+ return CouldNotCompute;
}
/// getNumIterationsInRange - Return the number of iterations of this loop that
@@ -3724,7 +3724,7 @@ ScalarEvolution::SCEVCallbackVH::SCEVCallbackVH(Value *V, ScalarEvolution *se)
//===----------------------------------------------------------------------===//
ScalarEvolution::ScalarEvolution()
- : FunctionPass(&ID), UnknownValue(new SCEVCouldNotCompute()) {
+ : FunctionPass(&ID), CouldNotCompute(new SCEVCouldNotCompute()) {
}
bool ScalarEvolution::runOnFunction(Function &F) {
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 5c44502..4863f3c 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -1043,6 +1043,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
return TokError("basic block pointers are invalid");
if (Result.get() == Type::VoidTy)
return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
Lex.Lex();
break;
@@ -1053,6 +1055,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
return TokError("basic block pointers are invalid");
if (Result.get() == Type::VoidTy)
return TokError("pointers to void are invalid; use i8* instead");
+ if (!PointerType::isValidElementType(Result.get()))
+ return TokError("pointer to this type is invalid");
unsigned AddrSpace;
if (ParseOptionalAddrSpace(AddrSpace) ||
ParseToken(lltok::star, "expected '*' in address space"))
@@ -1149,7 +1153,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Lex.Lex();
}
- if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
+ if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
@@ -1245,6 +1249,8 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
if (Result == Type::VoidTy)
return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
while (EatIfPresent(lltok::comma)) {
EltTyLoc = Lex.getLoc();
@@ -1252,6 +1258,8 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
if (Result == Type::VoidTy)
return Error(EltTyLoc, "struct element can not have void type");
+ if (!StructType::isValidElementType(Result))
+ return Error(EltTyLoc, "invalid element type for struct");
ParamsList.push_back(Result);
}
@@ -1299,11 +1307,11 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
return Error(SizeLoc, "zero element vector is illegal");
if ((unsigned)Size != Size)
return Error(SizeLoc, "size too large for vector");
- if (!EltTy->isFloatingPoint() && !EltTy->isInteger())
+ if (!VectorType::isValidElementType(EltTy))
return Error(TypeLoc, "vector element type must be fp or integer");
Result = VectorType::get(EltTy, unsigned(Size));
} else {
- if (!EltTy->isFirstClassType() && !isa<OpaqueType>(EltTy))
+ if (!ArrayType::isValidElementType(EltTy))
return Error(TypeLoc, "invalid array element type");
Result = HandleUpRefs(ArrayType::get(EltTy, Size));
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 5ae183e..f3c2833 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1785,48 +1785,41 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
/// support the operation, but do support the resultant vector type.
SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
unsigned NumElems = Node->getNumOperands();
- SDValue SplatValue = Node->getOperand(0);
+ SDValue Value1, Value2;
DebugLoc dl = Node->getDebugLoc();
MVT VT = Node->getValueType(0);
- MVT OpVT = SplatValue.getValueType();
+ MVT OpVT = Node->getOperand(0).getValueType();
MVT EltVT = VT.getVectorElementType();
// If the only non-undef value is the low element, turn this into a
// SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X.
bool isOnlyLowElement = true;
-
- // FIXME: it would be far nicer to change this into map<SDValue,uint64_t>
- // and use a bitmask instead of a list of elements.
- // FIXME: this doesn't treat <0, u, 0, u> for example, as a splat.
- std::map<SDValue, std::vector<unsigned> > Values;
- Values[SplatValue].push_back(0);
+ bool MoreThanTwoValues = false;
bool isConstant = true;
- if (!isa<ConstantFPSDNode>(SplatValue) && !isa<ConstantSDNode>(SplatValue) &&
- SplatValue.getOpcode() != ISD::UNDEF)
- isConstant = false;
-
- for (unsigned i = 1; i < NumElems; ++i) {
+ for (unsigned i = 0; i < NumElems; ++i) {
SDValue V = Node->getOperand(i);
- Values[V].push_back(i);
- if (V.getOpcode() != ISD::UNDEF)
+ if (V.getOpcode() == ISD::UNDEF)
+ continue;
+ if (i > 0)
isOnlyLowElement = false;
- if (SplatValue != V)
- SplatValue = SDValue(0, 0);
-
- // If this isn't a constant element or an undef, we can't use a constant
- // pool load.
- if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V) &&
- V.getOpcode() != ISD::UNDEF)
+ if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
isConstant = false;
+
+ if (!Value1.getNode()) {
+ Value1 = V;
+ } else if (!Value2.getNode()) {
+ if (V != Value1)
+ Value2 = V;
+ } else if (V != Value1 && V != Value2) {
+ MoreThanTwoValues = true;
+ }
}
- if (isOnlyLowElement) {
- // If the low element is an undef too, then this whole things is an undef.
- if (Node->getOperand(0).getOpcode() == ISD::UNDEF)
- return DAG.getUNDEF(VT);
- // Otherwise, turn this into a scalar_to_vector node.
+ if (!Value1.getNode())
+ return DAG.getUNDEF(VT);
+
+ if (isOnlyLowElement)
return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0));
- }
// If all elements are constants, create a load from the constant pool.
if (isConstant) {
@@ -1852,59 +1845,25 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
false, Alignment);
}
- if (SplatValue.getNode()) { // Splat of one value?
- // Build the shuffle constant vector: <0, 0, 0, 0>
- SmallVector<int, 8> ZeroVec(NumElems, 0);
-
- // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it.
- if (TLI.isShuffleMaskLegal(ZeroVec, Node->getValueType(0))) {
+ if (!MoreThanTwoValues) {
+ SmallVector<int, 8> ShuffleVec(NumElems, -1);
+ for (unsigned i = 0; i < NumElems; ++i) {
+ SDValue V = Node->getOperand(i);
+ if (V.getOpcode() == ISD::UNDEF)
+ continue;
+ ShuffleVec[i] = V == Value1 ? 0 : NumElems;
+ }
+ if (TLI.isShuffleMaskLegal(ShuffleVec, Node->getValueType(0))) {
// Get the splatted value into the low element of a vector register.
- SDValue LowValVec =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, SplatValue);
+ SDValue Vec1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value1);
+ SDValue Vec2;
+ if (Value2.getNode())
+ Vec2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value2);
+ else
+ Vec2 = DAG.getUNDEF(VT);
// Return shuffle(LowValVec, undef, <0,0,0,0>)
- return DAG.getVectorShuffle(VT, dl, LowValVec, DAG.getUNDEF(VT),
- &ZeroVec[0]);
- }
- }
-
- // If there are only two unique elements, we may be able to turn this into a
- // vector shuffle.
- if (Values.size() == 2) {
- // Get the two values in deterministic order.
- SDValue Val1 = Node->getOperand(1);
- SDValue Val2;
- std::map<SDValue, std::vector<unsigned> >::iterator MI = Values.begin();
- if (MI->first != Val1)
- Val2 = MI->first;
- else
- Val2 = (++MI)->first;
-
- // If Val1 is an undef, make sure it ends up as Val2, to ensure that our
- // vector shuffle has the undef vector on the RHS.
- if (Val1.getOpcode() == ISD::UNDEF)
- std::swap(Val1, Val2);
-
- // Build the shuffle constant vector: e.g. <0, 4, 0, 4>
- SmallVector<int, 8> ShuffleMask(NumElems, -1);
-
- // Set elements of the shuffle mask for Val1.
- std::vector<unsigned> &Val1Elts = Values[Val1];
- for (unsigned i = 0, e = Val1Elts.size(); i != e; ++i)
- ShuffleMask[Val1Elts[i]] = 0;
-
- // Set elements of the shuffle mask for Val2.
- std::vector<unsigned> &Val2Elts = Values[Val2];
- for (unsigned i = 0, e = Val2Elts.size(); i != e; ++i)
- if (Val2.getOpcode() != ISD::UNDEF)
- ShuffleMask[Val2Elts[i]] = NumElems;
-
- // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it.
- if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, VT) &&
- TLI.isShuffleMaskLegal(ShuffleMask, VT)) {
- Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val1);
- Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val2);
- return DAG.getVectorShuffle(VT, dl, Val1, Val2, &ShuffleMask[0]);
+ return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec.data());
}
}
diff --git a/lib/Target/PowerPC/PPCInstrAltivec.td b/lib/Target/PowerPC/PPCInstrAltivec.td
index 9a5be79..3f4d329 100644
--- a/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -666,3 +666,25 @@ def : Pat<(int_ppc_altivec_vnmsubfp VRRC:$A, VRRC:$B, VRRC:$C),
def : Pat<(PPCvperm (v16i8 VRRC:$vA), VRRC:$vB, VRRC:$vC),
(VPERM VRRC:$vA, VRRC:$vB, VRRC:$vC)>;
+
+// Vector shifts
+def : Pat<(v16i8 (shl (v16i8 VRRC:$vA), (v16i8 VRRC:$vB))),
+ (v16i8 (VSLB VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v8i16 (shl (v8i16 VRRC:$vA), (v8i16 VRRC:$vB))),
+ (v8i16 (VSLH VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v4i32 (shl (v4i32 VRRC:$vA), (v4i32 VRRC:$vB))),
+ (v4i32 (VSLW VRRC:$vA, VRRC:$vB))>;
+
+def : Pat<(v16i8 (srl (v16i8 VRRC:$vA), (v16i8 VRRC:$vB))),
+ (v16i8 (VSRB VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v8i16 (srl (v8i16 VRRC:$vA), (v8i16 VRRC:$vB))),
+ (v8i16 (VSRH VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v4i32 (srl (v4i32 VRRC:$vA), (v4i32 VRRC:$vB))),
+ (v4i32 (VSRW VRRC:$vA, VRRC:$vB))>;
+
+def : Pat<(v16i8 (sra (v16i8 VRRC:$vA), (v16i8 VRRC:$vB))),
+ (v16i8 (VSRAB VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v8i16 (sra (v8i16 VRRC:$vA), (v8i16 VRRC:$vB))),
+ (v8i16 (VSRAH VRRC:$vA, VRRC:$vB))>;
+def : Pat<(v4i32 (sra (v4i32 VRRC:$vA), (v4i32 VRRC:$vB))),
+ (v4i32 (VSRAW VRRC:$vA, VRRC:$vB))>;
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index ef60ff5..9e15a54 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -7691,13 +7691,15 @@ static bool isBaseAlignmentOfN(unsigned N, SDNode *Base,
}
static bool EltsFromConsecutiveLoads(ShuffleVectorSDNode *N, unsigned NumElems,
- MVT EVT, SDNode *&Base,
+ MVT EVT, LoadSDNode *&LDBase,
+ unsigned &LastLoadedElt,
SelectionDAG &DAG, MachineFrameInfo *MFI,
const TargetLowering &TLI) {
- Base = NULL;
+ LDBase = NULL;
+ LastLoadedElt = -1;
for (unsigned i = 0; i < NumElems; ++i) {
if (N->getMaskElt(i) < 0) {
- if (!Base)
+ if (!LDBase)
return false;
continue;
}
@@ -7706,19 +7708,20 @@ static bool EltsFromConsecutiveLoads(ShuffleVectorSDNode *N, unsigned NumElems,
if (!Elt.getNode() ||
(Elt.getOpcode() != ISD::UNDEF && !ISD::isNON_EXTLoad(Elt.getNode())))
return false;
- if (!Base) {
- Base = Elt.getNode();
- if (Base->getOpcode() == ISD::UNDEF)
+ if (!LDBase) {
+ if (Elt.getNode()->getOpcode() == ISD::UNDEF)
return false;
+ LDBase = cast<LoadSDNode>(Elt.getNode());
+ LastLoadedElt = i;
continue;
}
if (Elt.getOpcode() == ISD::UNDEF)
continue;
LoadSDNode *LD = cast<LoadSDNode>(Elt);
- LoadSDNode *LDBase = cast<LoadSDNode>(Base);
if (!TLI.isConsecutiveLoad(LD, LDBase, EVT.getSizeInBits()/8, i, MFI))
return false;
+ LastLoadedElt = i;
}
return true;
}
@@ -7737,134 +7740,29 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
unsigned NumElems = VT.getVectorNumElements();
- // For x86-32 machines, if we see an insert and then a shuffle in a v2i64
- // where the upper half is 0, it is advantageous to rewrite it as a build
- // vector of (0, val) so it can use movq.
- if (VT == MVT::v2i64) {
- SDValue In[2];
- In[0] = N->getOperand(0);
- In[1] = N->getOperand(1);
- int Idx0 = SVN->getMaskElt(0);
- int Idx1 = SVN->getMaskElt(1);
- // FIXME: can we take advantage of undef index?
- if (Idx0 >= 0 && Idx1 >= 0 &&
- In[Idx0/2].getOpcode() == ISD::INSERT_VECTOR_ELT &&
- In[Idx1/2].getOpcode() == ISD::BUILD_VECTOR) {
- ConstantSDNode* InsertVecIdx =
- dyn_cast<ConstantSDNode>(In[Idx0/2].getOperand(2));
- if (InsertVecIdx &&
- InsertVecIdx->getZExtValue() == (unsigned)(Idx0 % 2) &&
- isZeroNode(In[Idx1/2].getOperand(Idx1 % 2))) {
- return DAG.getNode(ISD::BUILD_VECTOR, dl, VT,
- In[Idx0/2].getOperand(1),
- In[Idx1/2].getOperand(Idx1 % 2));
- }
- }
- }
+ if (VT.getSizeInBits() != 128)
+ return SDValue();
// Try to combine a vector_shuffle into a 128-bit load.
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
- SDNode *Base = NULL;
- if (!EltsFromConsecutiveLoads(SVN, NumElems, EVT, Base, DAG, MFI, TLI))
+ LoadSDNode *LD = NULL;
+ unsigned LastLoadedElt;
+ if (!EltsFromConsecutiveLoads(SVN, NumElems, EVT, LD, LastLoadedElt, DAG,
+ MFI, TLI))
return SDValue();
- LoadSDNode *LD = cast<LoadSDNode>(Base);
- if (isBaseAlignmentOfN(16, Base->getOperand(1).getNode(), TLI))
+ if (LastLoadedElt == NumElems - 1) {
+ if (isBaseAlignmentOfN(16, LD->getBasePtr().getNode(), TLI))
+ return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
+ LD->getSrcValue(), LD->getSrcValueOffset(),
+ LD->isVolatile());
return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile());
- return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(),
- LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
-}
-
-/// PerformBuildVectorCombine - build_vector 0,(load i64 / f64) -> movq / movsd.
-static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const X86Subtarget *Subtarget,
- const TargetLowering &TLI) {
- unsigned NumOps = N->getNumOperands();
- DebugLoc dl = N->getDebugLoc();
-
- // Ignore single operand BUILD_VECTOR.
- if (NumOps == 1)
- return SDValue();
-
- MVT VT = N->getValueType(0);
- MVT EVT = VT.getVectorElementType();
-
- // Before or during type legalization, we want to try and convert a
- // build_vector of an i64 load and a zero value into vzext_movl before the
- // legalizer can break it up.
- // FIXME: does the case below remove the need to do this?
- if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer()) {
- if ((EVT != MVT::i64 && EVT != MVT::f64) || Subtarget->is64Bit())
- return SDValue();
-
- // This must be an insertion into a zero vector.
- SDValue HighElt = N->getOperand(1);
- if (!isZeroNode(HighElt))
- return SDValue();
-
- // Value must be a load.
- SDNode *Base = N->getOperand(0).getNode();
- if (!isa<LoadSDNode>(Base)) {
- if (Base->getOpcode() != ISD::BIT_CONVERT)
- return SDValue();
- Base = Base->getOperand(0).getNode();
- if (!isa<LoadSDNode>(Base))
- return SDValue();
- }
-
- // Transform it into VZEXT_LOAD addr.
- LoadSDNode *LD = cast<LoadSDNode>(Base);
-
- // Load must not be an extload.
- if (LD->getExtensionType() != ISD::NON_EXTLOAD)
- return SDValue();
-
- // Load type should legal type so we don't have to legalize it.
- if (!TLI.isTypeLegal(VT))
- return SDValue();
-
- SDVTList Tys = DAG.getVTList(VT, MVT::Other);
- SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
- SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, dl, Tys, Ops, 2);
- TargetLowering::TargetLoweringOpt TLO(DAG);
- TLO.CombineTo(SDValue(Base, 1), ResNode.getValue(1));
- DCI.CommitTargetLoweringOpt(TLO);
- return ResNode;
- }
-
- // The type legalizer will have broken apart v2i64 build_vector created during
- // widening before the code which handles that case is run. Look for build
- // vector (load, load + 4, 0/undef, 0/undef)
- if (VT == MVT::v4i32 || VT == MVT::v4f32) {
- LoadSDNode *LD0 = dyn_cast<LoadSDNode>(N->getOperand(0));
- LoadSDNode *LD1 = dyn_cast<LoadSDNode>(N->getOperand(1));
- if (!LD0 || !LD1)
- return SDValue();
- if (LD0->getExtensionType() != ISD::NON_EXTLOAD ||
- LD1->getExtensionType() != ISD::NON_EXTLOAD)
- return SDValue();
- // Make sure the second elt is a consecutive load.
- if (!TLI.isConsecutiveLoad(LD1, LD0, EVT.getSizeInBits()/8, 1,
- DAG.getMachineFunction().getFrameInfo()))
- return SDValue();
-
- SDValue N2 = N->getOperand(2);
- SDValue N3 = N->getOperand(3);
- if (!isZeroNode(N2) && N2.getOpcode() != ISD::UNDEF)
- return SDValue();
- if (!isZeroNode(N3) && N3.getOpcode() != ISD::UNDEF)
- return SDValue();
-
+ LD->isVolatile(), LD->getAlignment());
+ } else if (NumElems == 4 && LastLoadedElt == 1) {
SDVTList Tys = DAG.getVTList(MVT::v2i64, MVT::Other);
- SDValue Ops[] = { LD0->getChain(), LD0->getBasePtr() };
+ SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, dl, Tys, Ops, 2);
- TargetLowering::TargetLoweringOpt TLO(DAG);
- TLO.CombineTo(SDValue(LD0, 1), ResNode.getValue(1));
- DCI.CommitTargetLoweringOpt(TLO);
return DAG.getNode(ISD::BIT_CONVERT, dl, VT, ResNode);
}
return SDValue();
@@ -8466,14 +8364,25 @@ static SDValue PerformBTCombine(SDNode *N,
return SDValue();
}
+static SDValue PerformVZEXT_MOVLCombine(SDNode *N, SelectionDAG &DAG) {
+ SDValue Op = N->getOperand(0);
+ if (Op.getOpcode() == ISD::BIT_CONVERT)
+ Op = Op.getOperand(0);
+ MVT VT = N->getValueType(0), OpVT = Op.getValueType();
+ if (Op.getOpcode() == X86ISD::VZEXT_LOAD &&
+ VT.getVectorElementType().getSizeInBits() ==
+ OpVT.getVectorElementType().getSizeInBits()) {
+ return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), VT, Op);
+ }
+ return SDValue();
+}
+
SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
switch (N->getOpcode()) {
default: break;
case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, *this);
- case ISD::BUILD_VECTOR:
- return PerformBuildVectorCombine(N, DAG, DCI, Subtarget, *this);
case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget);
case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI);
case ISD::MUL: return PerformMulCombine(N, DAG, DCI);
@@ -8485,6 +8394,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case X86ISD::FOR: return PerformFORCombine(N, DAG);
case X86ISD::FAND: return PerformFANDCombine(N, DAG);
case X86ISD::BT: return PerformBTCombine(N, DAG, DCI);
+ case X86ISD::VZEXT_MOVL: return PerformVZEXT_MOVLCombine(N, DAG);
}
return SDValue();
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 2c01cc3..5f12825 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -932,8 +932,7 @@ static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V,
GlobalVariable *GV,
SmallPtrSet<PHINode*, 8> &PHIs) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
- Instruction *Inst = dyn_cast<Instruction>(*UI);
- if (Inst == 0) return false;
+ Instruction *Inst = cast<Instruction>(*UI);
if (isa<LoadInst>(Inst) || isa<CmpInst>(Inst)) {
continue; // Fine, ignore.
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index 2dc8558..e4a9dea 100644
--- a/lib/Transforms/IPO/IPConstantPropagation.cpp
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -241,15 +241,11 @@ bool IPCP::PropagateConstantReturn(Function &F) {
for (Value::use_iterator I = Call->use_begin(), E = Call->use_end();
I != E;) {
- Instruction *Ins = dyn_cast<Instruction>(*I);
+ Instruction *Ins = cast<Instruction>(*I);
// Increment now, so we can remove the use
++I;
- // Not an instruction? Ignore
- if (!Ins)
- continue;
-
// Find the index of the retval to replace with
int index = -1;
if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins))
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 97bd34c..6d2ff0e 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -12579,6 +12579,12 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) {
}
}
+ unsigned VWidth = cast<VectorType>(VecOp->getType())->getNumElements();
+ APInt UndefElts(VWidth, 0);
+ APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth));
+ if (SimplifyDemandedVectorElts(&IE, AllOnesEltMask, UndefElts))
+ return &IE;
+
return 0;
}
diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp
index a7e4d6e..b9b5688 100644
--- a/lib/Transforms/Scalar/PredicateSimplifier.cpp
+++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp
@@ -1525,12 +1525,12 @@ namespace {
Instruction *I2 = dyn_cast<Instruction>(R);
if (I2 && below(I2)) {
std::vector<Instruction *> ToNotify;
- for (Value::use_iterator UI = R->use_begin(), UE = R->use_end();
+ for (Value::use_iterator UI = I2->use_begin(), UE = I2->use_end();
UI != UE;) {
Use &TheUse = UI.getUse();
++UI;
- if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser()))
- ToNotify.push_back(I);
+ Instruction *I = cast<Instruction>(TheUse.getUser());
+ ToNotify.push_back(I);
}
DOUT << "Simply removing " << *I2
@@ -1658,10 +1658,9 @@ namespace {
++UI;
Value *V = TheUse.getUser();
if (!V->use_empty()) {
- if (Instruction *Inst = dyn_cast<Instruction>(V)) {
- if (aboveOrBelow(Inst))
- opsToDef(Inst);
- }
+ Instruction *Inst = cast<Instruction>(V);
+ if (aboveOrBelow(Inst))
+ opsToDef(Inst);
}
}
}
@@ -2262,10 +2261,9 @@ namespace {
UE = O.LHS->use_end(); UI != UE;) {
Use &TheUse = UI.getUse();
++UI;
- if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
- if (aboveOrBelow(I))
- opsToDef(I);
- }
+ Instruction *I = cast<Instruction>(TheUse.getUser());
+ if (aboveOrBelow(I))
+ opsToDef(I);
}
}
if (Instruction *I2 = dyn_cast<Instruction>(O.RHS)) {
@@ -2277,10 +2275,9 @@ namespace {
UE = O.RHS->use_end(); UI != UE;) {
Use &TheUse = UI.getUse();
++UI;
- if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
- if (aboveOrBelow(I))
- opsToDef(I);
- }
+ Instruction *I = cast<Instruction>(TheUse.getUser());
+ if (aboveOrBelow(I))
+ opsToDef(I);
}
}
}
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index d73519c..3deee54 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -639,8 +639,8 @@ void SCCPSolver::visitReturnInst(ReturnInst &I) {
DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
- Value *Val = FindInsertedValue(I.getOperand(0), i);
- mergeInValue(It->second, F, getValueState(Val));
+ if (Value *Val = FindInsertedValue(I.getOperand(0), i))
+ mergeInValue(It->second, F, getValueState(Val));
}
}
}
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 9935f12..7143c7b 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -1228,7 +1228,8 @@ void SROA::CleanupAllocaUsers(AllocationInst *AI) {
User *U = *UI++;
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U))
CleanupGEP(GEPI);
- else if (Instruction *I = dyn_cast<Instruction>(U)) {
+ else {
+ Instruction *I = cast<Instruction>(U);
SmallVector<DbgInfoIntrinsic *, 2> DbgInUses;
if (!isa<StoreInst>(I) && OnlyUsedByDbgInfoIntrinsics(I, &DbgInUses)) {
// Safe to remove debug info uses.
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 11b93ff..a1e6c42 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -135,8 +135,8 @@ bool Type::isFPOrFPVector() const {
return cast<VectorType>(this)->getElementType()->isFloatingPoint();
}
-// canLosslesllyBitCastTo - Return true if this type can be converted to
-// 'Ty' without any reinterpretation of bits. For example, uint to int.
+// canLosslesslyBitCastTo - Return true if this type can be converted to
+// 'Ty' without any reinterpretation of bits. For example, i8* to i32*.
//
bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
// Identity cast means no change so return true
@@ -318,6 +318,17 @@ bool FunctionType::isValidReturnType(const Type *RetTy) {
return true;
}
+/// isValidArgumentType - Return true if the specified type is valid as an
+/// argument type.
+bool FunctionType::isValidArgumentType(const Type *ArgTy) {
+ if ((!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy)) ||
+ (isa<PointerType>(ArgTy) &&
+ cast<PointerType>(ArgTy)->getElementType() == Type::MetadataTy))
+ return false;
+
+ return true;
+}
+
FunctionType::FunctionType(const Type *Result,
const std::vector<const Type*> &Params,
bool IsVarArgs)
@@ -331,11 +342,8 @@ FunctionType::FunctionType(const Type *Result,
new (&ContainedTys[0]) PATypeHandle(Result, this);
for (unsigned i = 0; i != Params.size(); ++i) {
- assert((Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])) &&
- "Function arguments must be value types!");
- assert((!isa<PointerType>(Params[i]) ||
- cast<PointerType>(Params[i])->getElementType() != Type::MetadataTy)
- && "Attempt to use metadata* as function argument type!");
+ assert(isValidArgumentType(Params[i]) &&
+ "Not a valid type for function argument!");
new (&ContainedTys[i+1]) PATypeHandle(Params[i], this);
isAbstract |= Params[i]->isAbstract();
}
@@ -352,12 +360,8 @@ StructType::StructType(const std::vector<const Type*> &Types, bool isPacked)
bool isAbstract = false;
for (unsigned i = 0; i < Types.size(); ++i) {
assert(Types[i] && "<null> type for structure field!");
- assert(Types[i] != Type::VoidTy && "Void type for structure field!");
- assert(Types[i] != Type::LabelTy && "Label type for structure field!");
- assert(Types[i] != Type::MetadataTy && "Metadata type for structure field");
- assert((!isa<PointerType>(Types[i]) ||
- cast<PointerType>(Types[i])->getElementType() != Type::MetadataTy)
- && "Type 'metadata*' is invalid for structure field.");
+ assert(isValidElementType(Types[i]) &&
+ "Invalid type for structure element!");
new (&ContainedTys[i]) PATypeHandle(Types[i], this);
isAbstract |= Types[i]->isAbstract();
}
@@ -379,8 +383,7 @@ VectorType::VectorType(const Type *ElType, unsigned NumEl)
NumElements = NumEl;
setAbstract(ElType->isAbstract());
assert(NumEl > 0 && "NumEl of a VectorType must be greater than 0");
- assert((ElType->isInteger() || ElType->isFloatingPoint() ||
- isa<OpaqueType>(ElType)) &&
+ assert(isValidElementType(ElType) &&
"Elements of a VectorType must be a primitive type");
}
@@ -1051,12 +1054,7 @@ static ManagedStatic<TypeMap<ArrayValType, ArrayType> > ArrayTypes;
ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
assert(ElementType && "Can't get array of <null> types!");
- assert(ElementType != Type::VoidTy && "Array of void is not valid!");
- assert(ElementType != Type::LabelTy && "Array of labels is not valid!");
- assert(ElementType != Type::MetadataTy && "Array of metadata is not valid!");
- assert((!isa<PointerType>(ElementType) ||
- cast<PointerType>(ElementType)->getElementType() != Type::MetadataTy)
- && "Array of metadata* is not valid!");
+ assert(isValidElementType(ElementType) && "Invalid type for array element!");
ArrayValType AVT(ElementType, NumElements);
ArrayType *AT = ArrayTypes->get(AVT);
@@ -1071,6 +1069,18 @@ ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
return AT;
}
+bool ArrayType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy ||
+ ElemTy == Type::MetadataTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Vector Type Factory...
@@ -1115,6 +1125,14 @@ VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
return PT;
}
+bool VectorType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
+ isa<OpaqueType>(ElemTy))
+ return true;
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Struct Type Factory...
//
@@ -1181,6 +1199,17 @@ StructType *StructType::get(const Type *type, ...) {
return llvm::StructType::get(StructFields);
}
+bool StructType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy ||
+ ElemTy == Type::MetadataTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
//===----------------------------------------------------------------------===//
@@ -1217,10 +1246,7 @@ PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
assert(ValueType && "Can't get a pointer to <null> type!");
assert(ValueType != Type::VoidTy &&
"Pointer to void is not valid, use i8* instead!");
- assert(ValueType != Type::LabelTy && "Pointer to label is not valid!");
- assert((!isa<PointerType>(ValueType) ||
- cast<PointerType>(ValueType)->getElementType() != Type::MetadataTy)
- && "Pointer to metadata* is not valid!");
+ assert(isValidElementType(ValueType) && "Invalid type for pointer element!");
PointerValType PVT(ValueType, AddressSpace);
PointerType *PT = PointerTypes->get(PVT);
@@ -1239,6 +1265,18 @@ PointerType *Type::getPointerTo(unsigned addrs) const {
return PointerType::get(this, addrs);
}
+bool PointerType::isValidElementType(const Type *ElemTy) {
+ if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy)
+ return false;
+
+ if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
+ if (PTy->getElementType() == Type::MetadataTy)
+ return false;
+
+ return true;
+}
+
+
//===----------------------------------------------------------------------===//
// Derived Type Refinement Functions
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index b047d0c..b1297ff 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -280,7 +280,6 @@ namespace {
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs,
const Value *V);
- bool VerifyMDNode(const MDNode *N);
void WriteValue(const Value *V) {
if (!V) return;
@@ -380,24 +379,22 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
// Verify that any metadata used in a global initializer points only to
// other globals.
if (MDNode *FirstNode = dyn_cast<MDNode>(GV.getInitializer())) {
- if (VerifyMDNode(FirstNode)) {
- SmallVector<const MDNode *, 4> NodesToAnalyze;
- NodesToAnalyze.push_back(FirstNode);
- while (!NodesToAnalyze.empty()) {
- const MDNode *N = NodesToAnalyze.back();
- NodesToAnalyze.pop_back();
-
- for (MDNode::const_elem_iterator I = N->elem_begin(),
- E = N->elem_end(); I != E; ++I)
- if (const Value *V = *I) {
- if (const MDNode *Next = dyn_cast<MDNode>(V))
- NodesToAnalyze.push_back(Next);
- else
- Assert3(isa<Constant>(V),
- "reference to instruction from global metadata node",
- &GV, N, V);
- }
- }
+ SmallVector<const MDNode *, 4> NodesToAnalyze;
+ NodesToAnalyze.push_back(FirstNode);
+ while (!NodesToAnalyze.empty()) {
+ const MDNode *N = NodesToAnalyze.back();
+ NodesToAnalyze.pop_back();
+
+ for (MDNode::const_elem_iterator I = N->elem_begin(),
+ E = N->elem_end(); I != E; ++I)
+ if (const Value *V = *I) {
+ if (const MDNode *Next = dyn_cast<MDNode>(V))
+ NodesToAnalyze.push_back(Next);
+ else
+ Assert3(isa<Constant>(V),
+ "reference to instruction from global metadata node",
+ &GV, N, V);
+ }
}
}
} else {
@@ -1708,44 +1705,6 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
"Intrinsic has wrong parameter attributes!", F);
}
-/// Verify that an MDNode is not cyclic.
-bool Verifier::VerifyMDNode(const MDNode *N) {
- if (N->elem_empty()) return true;
-
- // The current DFS path through the nodes. Node and element number.
- typedef std::pair<const MDNode *, MDNode::const_elem_iterator> Edge;
- SmallVector<Edge, 8> Path;
-
- Path.push_back(std::make_pair(N, N->elem_begin()));
- while (!Path.empty()) {
- Edge &e = Path.back();
- const MDNode *&e_N = e.first;
- MDNode::const_elem_iterator &e_I = e.second;
-
- if (e_N->elem_end() == e_I) {
- Path.pop_back();
- continue;
- }
-
- for (MDNode::const_elem_iterator e_E = e_N->elem_end(); e_I != e_E; ++e_I) {
- if (const MDNode *C = dyn_cast_or_null<MDNode>(e_I->operator Value*())) {
- // Is child MDNode C already in the Path?
- for (SmallVectorImpl<Edge>::iterator I = Path.begin(), E = Path.end();
- I != E; ++I) {
- if (I->first != C) {
- CheckFailed("MDNode is cyclic.", C);
- return false;
- }
- }
-
- Path.push_back(std::make_pair(C, C->elem_begin()));
- break;
- }
- }
- }
- return true;
-}
-
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...
diff --git a/test/CodeGen/PowerPC/vec_shift.ll b/test/CodeGen/PowerPC/vec_shift.ll
new file mode 100644
index 0000000..0cc699c
--- /dev/null
+++ b/test/CodeGen/PowerPC/vec_shift.ll
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5
+; PR3628
+
+define void @update(<4 x i32> %val, <4 x i32>* %dst) nounwind {
+entry:
+ %shl = shl <4 x i32> %val, < i32 4, i32 3, i32 2, i32 1 >
+ %shr = ashr <4 x i32> %shl, < i32 1, i32 2, i32 3, i32 4 >
+ store <4 x i32> %shr, <4 x i32>* %dst
+ ret void
+}
diff --git a/test/CodeGen/X86/vec_loadsingles.ll b/test/CodeGen/X86/vec_loadsingles.ll
new file mode 100644
index 0000000..6712276
--- /dev/null
+++ b/test/CodeGen/X86/vec_loadsingles.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movq
+
+define <4 x float> @a(<4 x float> %a, float* nocapture %p) nounwind readonly {
+entry:
+ %tmp1 = load float* %p
+ %vecins = insertelement <4 x float> undef, float %tmp1, i32 0
+ %add.ptr = getelementptr float* %p, i32 1
+ %tmp5 = load float* %add.ptr
+ %vecins7 = insertelement <4 x float> %vecins, float %tmp5, i32 1
+ ret <4 x float> %vecins7
+}
+
diff --git a/test/CodeGen/X86/vec_set-5.ll b/test/CodeGen/X86/vec_set-5.ll
index 4fc652c..d332970 100644
--- a/test/CodeGen/X86/vec_set-5.ll
+++ b/test/CodeGen/X86/vec_set-5.ll
@@ -1,7 +1,6 @@
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -o %t -f
; RUN: grep movlhps %t | count 1
-; RUN: grep movq %t | count 1
-; RUN: grep movsd %t | count 1
+; RUN: grep movq %t | count 2
define <4 x float> @test1(float %a, float %b) nounwind {
%tmp = insertelement <4 x float> zeroinitializer, float %a, i32 0 ; <<4 x float>> [#uses=1]
diff --git a/test/CodeGen/X86/vec_set-6.ll b/test/CodeGen/X86/vec_set-6.ll
index 02df526..c7b6747 100644
--- a/test/CodeGen/X86/vec_set-6.ll
+++ b/test/CodeGen/X86/vec_set-6.ll
@@ -1,6 +1,6 @@
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -o %t -f
; RUN: grep movss %t | count 1
-; RUN: grep movups %t | count 1
+; RUN: grep movq %t | count 1
; RUN: grep shufps %t | count 1
define <4 x float> @test(float %a, float %b, float %c) nounwind {
diff --git a/test/Transforms/InstCombine/vec_demanded_elts-3.ll b/test/Transforms/InstCombine/vec_demanded_elts-3.ll
new file mode 100644
index 0000000..eba3629
--- /dev/null
+++ b/test/Transforms/InstCombine/vec_demanded_elts-3.ll
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep load
+; PR4340
+
+define void @vac(<4 x float>* nocapture %a) nounwind {
+entry:
+ %tmp1 = load <4 x float>* %a ; <<4 x float>> [#uses=1]
+ %vecins = insertelement <4 x float> %tmp1, float 0.000000e+00, i32 0 ; <<4 x float>> [#uses=1]
+ %vecins4 = insertelement <4 x float> %vecins, float 0.000000e+00, i32 1; <<4 x float>> [#uses=1]
+ %vecins6 = insertelement <4 x float> %vecins4, float 0.000000e+00, i32 2; <<4 x float>> [#uses=1]
+ %vecins8 = insertelement <4 x float> %vecins6, float 0.000000e+00, i32 3; <<4 x float>> [#uses=1]
+ store <4 x float> %vecins8, <4 x float>* %a
+ ret void
+}
+
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 86d3fd3..46b1717 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -45,6 +45,7 @@ namespace {
bool generate_api_file = false;
const char *gcc_path = NULL;
+ const char *as_path = NULL;
struct claimed_file {
lto_module_t M;
@@ -109,6 +110,13 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
} else {
gcc_path = strdup(tv->tv_u.tv_string + 4);
}
+ } else if (strncmp("as=", tv->tv_u.tv_string, 3) == 0) {
+ if (as_path) {
+ (*message)(LDPL_WARNING, "Path to as specified twice. "
+ "Discarding %s", tv->tv_u.tv_string);
+ } else {
+ as_path = strdup(tv->tv_u.tv_string + 3);
+ }
} else {
(*message)(LDPL_WARNING, "Ignoring flag %s", tv->tv_u.tv_string);
}
@@ -346,6 +354,8 @@ ld_plugin_status all_symbols_read_hook(void) {
lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF);
if (gcc_path)
lto_codegen_set_gcc_path(cg, gcc_path);
+ if (as_path)
+ lto_codegen_set_assembler_path(cg, as_path);
size_t bufsize = 0;
const char *buffer = static_cast<const char *>(lto_codegen_compile(cg,
diff --git a/tools/llvmc/example/mcc16/Makefile b/tools/llvmc/example/mcc16/Makefile
new file mode 100644
index 0000000..efc9d2d
--- /dev/null
+++ b/tools/llvmc/example/mcc16/Makefile
@@ -0,0 +1,24 @@
+##===- llvmc/example/mcc16/Makefile ------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+# Change this so that $(BASE_LEVEL)/Makefile.common refers to
+# $LLVM_DIR/Makefile.common.
+export LLVMC_BASE_LEVEL = ../../../..
+
+# Change this to the name of your LLVMC-based driver.
+export LLVMC_BASED_DRIVER_NAME = mcc16
+
+# List your plugin names here
+export LLVMC_BUILTIN_PLUGINS = PIC16Base
+
+LEVEL = $(LLVMC_BASE_LEVEL)
+
+DIRS = plugins driver
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/example/mcc16/README b/tools/llvmc/example/mcc16/README
new file mode 100644
index 0000000..eeef6a4
--- /dev/null
+++ b/tools/llvmc/example/mcc16/README
@@ -0,0 +1,75 @@
+This is a basic compiler driver for the PIC16 toolchain that shows how to create
+your own llvmc-based drivers. It is based on the example/Skeleton template.
+
+The PIC16 toolchain looks like this:
+
+clang-cc (FE) -> llvm-ld (optimizer) -> llc (codegen) -> native-as -> native-ld
+
+Following features were requested by Sanjiv:
+
+From: Sanjiv Gupta <sanjiv.gupta <at> microchip.com>
+Subject: Re: llvmc for PIC16
+Newsgroups: gmane.comp.compilers.llvm.devel
+Date: 2009-06-05 06:51:14 GMT
+
+The salient features that we want to have in the driver are:
+1. llvm-ld will be used as "The Optimizer".
+2. If the user has specified to generate the final executable, then
+llvm-ld should run on all the .bc files generated by clang and create a
+single optimized .bc file for further tools.
+3. -Wo <options> - pass optimizations to the llvm-ld
+4. mcc16 -Wl <options> - pass options to native linker.
+5. mcc16 -Wa <options> - pass options to native assembler.
+
+Here are some example command lines and sample command invocations as to
+what should be done.
+
+$ mcc16 -S foo.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+
+$ mcc16 -S foo.c bar.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+// [clang-cc bar.c] -> bar.bc
+// [llvm-ld bar.bc] -> bar.opt.bc
+// [llc bar.opt.bc] -> bar.s
+
+** Use of -g causes llvm-ld to run with -disable-opt
+$ mcc16 -S -g foo.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+
+** -I is passed to clang-cc, -pre-RA-sched=list-burr to llc.
+$ mcc16 -S -g -I ../include -pre-RA-sched=list-burr foo.c
+// [clang-cc -I ../include foo.c] -> foo.bc
+// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
+// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
+
+** -Wo passes options to llvm-ld
+$ mcc16 -Wo=opt1,opt2 -S -I ../include -pre-RA-sched=list-burr foo.c
+// [clang-cc -I ../include foo.c] -> foo.bc
+// [llvm-ld -opt1 -opt2 foo.bc] -> foo.opt.bc
+// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
+
+** -Wa passes options to native as.
+$ mcc16 -c foo.c -Wa=opt1
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+// [native-as -opt1 foo.s] -> foo.o
+
+$ mcc16 -Wo=opt1 -Wl=opt2 -Wa=opt3 foo.c bar.c
+// [clang-cc foo.c] -> foo.bc
+// [clang-cc bar.c] -> bar.bc
+// [llvm-ld -opt1 foo.bc bar.bc] -> a.out.bc
+// [llc a.out.bc] -> a.out.s
+// [native-as -opt3 a.out.s] -> a.out.o
+// [native-ld -opt2 a.out.o] -> a.out
+
+Is this achievable by a tablegen based driver ?
+
+- Sanjiv
diff --git a/tools/llvmc/example/mcc16/driver/Main.cpp b/tools/llvmc/example/mcc16/driver/Main.cpp
new file mode 100644
index 0000000..b1f5b67
--- /dev/null
+++ b/tools/llvmc/example/mcc16/driver/Main.cpp
@@ -0,0 +1,14 @@
+//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Just include CompilerDriver/Main.inc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/Main.inc"
diff --git a/tools/llvmc/example/mcc16/driver/Makefile b/tools/llvmc/example/mcc16/driver/Makefile
new file mode 100644
index 0000000..ed9ebfd
--- /dev/null
+++ b/tools/llvmc/example/mcc16/driver/Makefile
@@ -0,0 +1,22 @@
+##===- llvmc/example/mcc16/driver/Makefile -----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+
+TOOLNAME = $(LLVMC_BASED_DRIVER_NAME)
+LLVMLIBS = CompilerDriver
+
+ifneq ($(LLVMC_BUILTIN_PLUGINS),)
+USEDLIBS += $(patsubst %,plugin_llvmc_%,$(LLVMC_BUILTIN_PLUGINS))
+endif
+
+LINK_COMPONENTS = support system
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/example/mcc16/plugins/Makefile b/tools/llvmc/example/mcc16/plugins/Makefile
new file mode 100644
index 0000000..fb07f23
--- /dev/null
+++ b/tools/llvmc/example/mcc16/plugins/Makefile
@@ -0,0 +1,18 @@
+##===- llvmc/example/Skeleton/plugins/Makefile -------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+
+ifneq ($(LLVMC_BUILTIN_PLUGINS),)
+DIRS = $(LLVMC_BUILTIN_PLUGINS)
+endif
+
+export LLVMC_BUILTIN_PLUGIN=1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile b/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile
new file mode 100644
index 0000000..5d785fd
--- /dev/null
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile
@@ -0,0 +1,17 @@
+##===- llvmc/example/Skeleton/plugins/Plugin/Makefile ------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/../..
+
+# Change this to the name of your plugin.
+LLVMC_PLUGIN = PIC16Base
+
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
new file mode 100644
index 0000000..0b8a22b
--- /dev/null
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
@@ -0,0 +1,116 @@
+//===- PIC16Base.td - PIC16 toolchain driver ---------------*- tablegen -*-===//
+//
+// A basic driver for the PIC16 toolchain.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CompilerDriver/Common.td"
+
+// Options
+
+def OptionList : OptionList<[
+ (switch_option "g",
+ (help "Disable optimizations")),
+ (switch_option "S",
+ (help "Stop after compilation, do not assemble")),
+ (parameter_option "I",
+ (help "Add a directory to include path")),
+ (parameter_option "pre-RA-sched",
+ (help "Example of an option that is passed to llc")),
+ (prefix_list_option "Wa,",
+ (help "Pass options to native assembler")),
+ (prefix_list_option "Wl,",
+ (help "Pass options to native linker")),
+ (prefix_list_option "Wllc,",
+ (help "Pass options to llc")),
+ (prefix_list_option "Wo,",
+ (help "Pass options to llvm-ld"))
+]>;
+
+// Tools
+
+def clang_cc : Tool<[
+ (in_language "c"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (cmd_line "clang-cc $INFILE -o $OUTFILE"),
+ (actions (case
+ (not_empty "I"), (forward "I"))),
+ (sink)
+]>;
+
+def llvm_ld : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-ld $INFILE -o $OUTFILE"),
+ (actions (case
+ (switch_on "g"), (append_cmd "-disable-opt"),
+ (not_empty "Wo,"), (unpack_values "Wo,")))
+]>;
+
+def llvm_ld_lto : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-ld $INFILE -o $OUTFILE"),
+ (actions (case
+ (switch_on "g"), (append_cmd "-disable-opt"),
+ (not_empty "Wo,"), (unpack_values "Wo,"))),
+ (join)
+]>;
+
+def llc : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "assembler"),
+ (output_suffix "s"),
+ (cmd_line "llc -f $INFILE -o $OUTFILE"),
+ (actions (case
+ (switch_on "S"), (stop_compilation),
+ (not_empty "Wllc,"), (unpack_values "Wllc,"),
+ (not_empty "pre-RA-sched"), (forward "pre-RA-sched")))
+]>;
+
+def native_as : Tool<[
+ (in_language "assembler"),
+ (out_language "object-code"),
+ (output_suffix "o"),
+ (cmd_line "native-as $INFILE -o $OUTFILE"),
+ (actions (case
+ (not_empty "Wa,"), (unpack_values "Wa,")))
+]>;
+
+def native_ld : Tool<[
+ (in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "native-ld $INFILE -o $OUTFILE"),
+ (actions (case
+ (not_empty "Wl,"), (unpack_values "Wl,"))),
+ (join)
+]>;
+
+// Language map
+
+def LanguageMap : LanguageMap<[
+ LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"c-cpp-output", ["i"]>,
+ LangToSuffixes<"assembler", ["s"]>,
+ LangToSuffixes<"assembler-with-cpp", ["S"]>,
+ LangToSuffixes<"llvm-assembler", ["ll"]>,
+ LangToSuffixes<"llvm-bitcode", ["bc"]>,
+ LangToSuffixes<"object-code", ["o"]>,
+ LangToSuffixes<"executable", ["out"]>
+]>;
+
+// Compilation graph
+
+def CompilationGraph : CompilationGraph<[
+ Edge<"root", "clang_cc">,
+ Edge<"clang_cc", "llvm_ld_lto">,
+ Edge<"llvm_ld_lto", "llc">,
+ OptionalEdge<"clang_cc", "llvm_ld", (case (switch_on "S"), (inc_weight))>,
+ Edge<"llvm_ld", "llc">,
+ Edge<"llc", "native_as">,
+ Edge<"native_as", "native_ld">
+]>;
diff --git a/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp b/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
new file mode 100644
index 0000000..add8acb
--- /dev/null
+++ b/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
@@ -0,0 +1 @@
+#include "AutoGenerated.inc"
OpenPOWER on IntegriCloud