Date: Tue, 4 May 2010 20:50:39 +0000 (UTC) From: Roman Divacky <rdivacky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r207631 - in vendor/llvm/dist: docs lib/CodeGen lib/Target/ARM lib/Target/CellSPU lib/Target/X86 lib/Target/X86/AsmParser lib/Transforms/Scalar lib/VMCore test/CodeGen/CellSPU test/MC/A... Message-ID: <201005042050.o44KodLt029690@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rdivacky Date: Tue May 4 20:50:39 2010 New Revision: 207631 URL: http://svn.freebsd.org/changeset/base/207631 Log: Update LLVM to r103052. Added: vendor/llvm/dist/test/CodeGen/CellSPU/storestruct.ll vendor/llvm/dist/test/MC/AsmParser/X86/x86_64-suffix-matching.s Modified: vendor/llvm/dist/docs/FAQ.html vendor/llvm/dist/lib/CodeGen/LiveIntervalAnalysis.cpp vendor/llvm/dist/lib/CodeGen/PHIElimination.cpp vendor/llvm/dist/lib/CodeGen/PHIElimination.h vendor/llvm/dist/lib/Target/ARM/ARMISelDAGToDAG.cpp vendor/llvm/dist/lib/Target/ARM/NEONPreAllocPass.cpp vendor/llvm/dist/lib/Target/CellSPU/SPUISelDAGToDAG.cpp vendor/llvm/dist/lib/Target/X86/AsmParser/X86AsmParser.cpp vendor/llvm/dist/lib/Target/X86/X86.td vendor/llvm/dist/lib/Transforms/Scalar/GVN.cpp vendor/llvm/dist/lib/VMCore/Metadata.cpp vendor/llvm/dist/test/Transforms/GlobalOpt/metadata.ll vendor/llvm/dist/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: vendor/llvm/dist/docs/FAQ.html ============================================================================== --- vendor/llvm/dist/docs/FAQ.html Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/docs/FAQ.html Tue May 4 20:50:39 2010 (r207631) @@ -632,22 +632,22 @@ Stop. <p>Use commands like this:</p> <ol> - <li><p>Compile your program as normal with llvm-g++:</p> + <li><p>Compile your program with llvm-g++:</p> <pre class="doc_code"> -% llvm-g++ x.cpp -o program +% llvm-g++ -emit-llvm x.cpp -o program.bc -c </pre> <p>or:</p> <pre class="doc_code"> -% llvm-g++ a.cpp -c -% llvm-g++ b.cpp -c -% llvm-g++ a.o b.o -o program +% llvm-g++ a.cpp -c -emit-llvm +% llvm-g++ b.cpp -c -emit-llvm +% llvm-ld a.o b.o -o program </pre> - <p>With llvm-gcc3, this will generate program and program.bc. The .bc - file is the LLVM version of the program all linked together.</p></li> + <p>This will generate program and program.bc. The .bc + file is the LLVM version of the program all linked together.</p></li> <li><p>Convert the LLVM code to C code, using the LLC tool with the C backend:</p> @@ -659,7 +659,7 @@ Stop. <li><p>Finally, compile the C file:</p> <pre class="doc_code"> -% cc x.c +% cc x.c -lstdc++ </pre></li> </ol> @@ -931,7 +931,7 @@ F.i: src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a> <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br> - Last modified: $Date: 2010-02-26 00:41:41 +0100 (Fri, 26 Feb 2010) $ + Last modified: $Date: 2010-05-04 20:16:00 +0200 (Tue, 04 May 2010) $ </address> </body> Modified: vendor/llvm/dist/lib/CodeGen/LiveIntervalAnalysis.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/LiveIntervalAnalysis.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/CodeGen/LiveIntervalAnalysis.cpp Tue May 4 20:50:39 2010 (r207631) @@ -262,6 +262,23 @@ static void printRegName(unsigned reg, c } #endif +static +bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) { + unsigned Reg = MI.getOperand(MOIdx).getReg(); + for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) { + const MachineOperand &MO = MI.getOperand(i); + if (!MO.isReg()) + continue; + if (MO.getReg() == Reg && MO.isDef()) { + assert(MI.getOperand(MOIdx).getSubReg() != MO.getSubReg() && + MI.getOperand(MOIdx).getSubReg() && + MO.getSubReg()); + return true; + } + } + return false; +} + void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, SlotIndex MIIdx, @@ -372,6 +389,13 @@ void LiveIntervals::handleVirtualRegiste } } else { + if (MultipleDefsByMI(*mi, MOIdx)) + // Mutple defs of the same virtual register by the same instruction. e.g. + // %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... + // This is likely due to elimination of REG_SEQUENCE instructions. Return + // here since there is nothing to do. + return; + // If this is the second time we see a virtual register definition, it // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the Modified: vendor/llvm/dist/lib/CodeGen/PHIElimination.cpp ============================================================================== --- vendor/llvm/dist/lib/CodeGen/PHIElimination.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/CodeGen/PHIElimination.cpp Tue May 4 20:50:39 2010 (r207631) @@ -30,6 +30,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <map> using namespace llvm; @@ -52,22 +53,22 @@ void llvm::PHIElimination::getAnalysisUs MachineFunctionPass::getAnalysisUsage(AU); } -bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) { - MRI = &Fn.getRegInfo(); +bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &MF) { + MRI = &MF.getRegInfo(); bool Changed = false; // Split critical edges to help the coalescer if (LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>()) - for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - Changed |= SplitPHIEdges(Fn, *I, *LV); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + Changed |= SplitPHIEdges(MF, *I, *LV); // Populate VRegPHIUseCount - analyzePHINodes(Fn); + analyzePHINodes(MF); // Eliminate PHI instructions by inserting copies into predecessor blocks. - for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - Changed |= EliminatePHINodes(Fn, *I); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + Changed |= EliminatePHINodes(MF, *I); // Remove dead IMPLICIT_DEF instructions. for (SmallPtrSet<MachineInstr*, 4>::iterator I = ImpDefs.begin(), @@ -81,11 +82,16 @@ bool llvm::PHIElimination::runOnMachineF // Clean up the lowered PHI instructions. for (LoweredPHIMap::iterator I = LoweredPHIs.begin(), E = LoweredPHIs.end(); I != E; ++I) - Fn.DeleteMachineInstr(I->first); + MF.DeleteMachineInstr(I->first); LoweredPHIs.clear(); ImpDefs.clear(); VRegPHIUseCount.clear(); + + // Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve + // SSA form. + Changed |= EliminateRegSequences(MF); + return Changed; } @@ -364,8 +370,8 @@ void llvm::PHIElimination::LowerAtomicPH /// used in a PHI node. We map that to the BB the vreg is coming from. This is /// used later to determine when the vreg is killed in the BB. /// -void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) { - for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end(); +void llvm::PHIElimination::analyzePHINodes(const MachineFunction& MF) { + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end(); BBI != BBE && BBI->isPHI(); ++BBI) @@ -443,3 +449,58 @@ MachineBasicBlock *PHIElimination::Split return NMBB; } + +static void UpdateRegSequenceSrcs(unsigned SrcReg, + unsigned DstReg, unsigned SrcIdx, + MachineRegisterInfo *MRI) { + for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg), + UE = MRI->reg_end(); RI != UE; ) { + MachineOperand &MO = RI.getOperand(); + ++RI; + MO.setReg(DstReg); + MO.setSubReg(SrcIdx); + } +} + +/// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as second part +/// of de-ssa process. This replaces sources of REG_SEQUENCE as sub-register +/// references of the register defined by REG_SEQUENCE. e.g. +/// +/// %reg1029<def>, %reg1030<def> = VLD1q16 %reg1024<kill>, ... +/// %reg1031<def> = REG_SEQUENCE %reg1029<kill>, 5, %reg1030<kill>, 6 +/// => +/// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... +bool PHIElimination::EliminateRegSequences(MachineFunction &MF) { + bool Changed = false; + + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE; ) { + MachineInstr &MI = *BBI; + ++BBI; + if (MI.getOpcode() != TargetOpcode::REG_SEQUENCE) + continue; + unsigned DstReg = MI.getOperand(0).getReg(); + if (MI.getOperand(0).getSubReg() || + TargetRegisterInfo::isPhysicalRegister(DstReg) || + !(MI.getNumOperands() & 1)) { + DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI); + llvm_unreachable(0); + } + for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) { + unsigned SrcReg = MI.getOperand(i).getReg(); + if (MI.getOperand(i).getSubReg() || + TargetRegisterInfo::isPhysicalRegister(SrcReg)) { + DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI); + llvm_unreachable(0); + } + unsigned SrcIdx = MI.getOperand(i+1).getImm(); + UpdateRegSequenceSrcs(SrcReg, DstReg, SrcIdx, MRI); + } + + MI.eraseFromParent(); + Changed = true; + } + + return Changed; +} Modified: vendor/llvm/dist/lib/CodeGen/PHIElimination.h ============================================================================== --- vendor/llvm/dist/lib/CodeGen/PHIElimination.h Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/CodeGen/PHIElimination.h Tue May 4 20:50:39 2010 (r207631) @@ -94,6 +94,8 @@ namespace llvm { return I; } + bool EliminateRegSequences(MachineFunction &MF); + typedef std::pair<unsigned, unsigned> BBVRegPair; typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse; Modified: vendor/llvm/dist/lib/Target/ARM/ARMISelDAGToDAG.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue May 4 20:50:39 2010 (r207631) @@ -27,6 +27,7 @@ #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -34,6 +35,10 @@ using namespace llvm; +static cl::opt<bool> +UseRegSeq("neon-reg-sequence", cl::Hidden, + cl::desc("Use reg_sequence to model ld / st of multiple neon regs")); + //===--------------------------------------------------------------------===// /// ARMDAGToDAGISel - ARM specific code to select ARM machine /// instructions for SelectionDAG operations. @@ -939,10 +944,14 @@ SDNode *ARMDAGToDAGISel::SelectT2Indexed /// form a quad register. SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue Undef = - SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0); SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); + if (UseRegSeq) { + const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; + return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); + } + SDValue Undef = + SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0); SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, VT, Undef, V0, SubReg0); return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, Modified: vendor/llvm/dist/lib/Target/ARM/NEONPreAllocPass.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/ARM/NEONPreAllocPass.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Target/ARM/NEONPreAllocPass.cpp Tue May 4 20:50:39 2010 (r207631) @@ -12,12 +12,14 @@ #include "ARMInstrInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" using namespace llvm; namespace { class NEONPreAllocPass : public MachineFunctionPass { const TargetInstrInfo *TII; + MachineRegisterInfo *MRI; public: static char ID; @@ -30,6 +32,8 @@ namespace { } private: + bool FormsRegSequence(MachineInstr *MI, + unsigned FirstOpnd, unsigned NumRegs); bool PreAllocNEONRegisters(MachineBasicBlock &MBB); }; @@ -334,6 +338,27 @@ static bool isNEONMultiRegOp(int Opcode, return false; } +bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI, + unsigned FirstOpnd, unsigned NumRegs) { + MachineInstr *RegSeq = 0; + for (unsigned R = 0; R < NumRegs; ++R) { + MachineOperand &MO = MI->getOperand(FirstOpnd + R); + assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand"); + unsigned VirtReg = MO.getReg(); + assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && + "expected a virtual register"); + if (!MRI->hasOneNonDBGUse(VirtReg)) + return false; + MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg); + if (UseMI->getOpcode() != TargetOpcode::REG_SEQUENCE) + return false; + if (RegSeq && RegSeq != UseMI) + return false; + RegSeq = UseMI; + } + return true; +} + bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) { bool Modified = false; @@ -343,6 +368,8 @@ bool NEONPreAllocPass::PreAllocNEONRegis unsigned FirstOpnd, NumRegs, Offset, Stride; if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride)) continue; + if (FormsRegSequence(MI, FirstOpnd, NumRegs)) + continue; MachineBasicBlock::iterator NextI = llvm::next(MBBI); for (unsigned R = 0; R < NumRegs; ++R) { @@ -382,6 +409,7 @@ bool NEONPreAllocPass::PreAllocNEONRegis bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); + MRI = &MF.getRegInfo(); bool Modified = false; for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; Modified: vendor/llvm/dist/lib/Target/CellSPU/SPUISelDAGToDAG.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Tue May 4 20:50:39 2010 (r207631) @@ -941,13 +941,21 @@ SPUDAGToDAGISel::Select(SDNode *N) { && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 && RN->getReg() != SPU::R1))) { NewOpc = SPU::Ar32; + Ops[1] = Op1; if (Op1.getOpcode() == ISD::Constant) { ConstantSDNode *CN = cast<ConstantSDNode>(Op1); Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); - NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); + if (isInt<10>(CN->getSExtValue())) { + NewOpc = SPU::AIr32; + Ops[1] = Op1; + } else { + Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, + N->getValueType(0), + Op1), + 0); + } } Ops[0] = Op0; - Ops[1] = Op1; n_ops = 2; } } Modified: vendor/llvm/dist/lib/Target/X86/AsmParser/X86AsmParser.cpp ============================================================================== --- vendor/llvm/dist/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue May 4 20:50:39 2010 (r207631) @@ -51,11 +51,14 @@ private: void InstructionCleanup(MCInst &Inst); /// @name Auto-generated Match Functions - /// { + /// { bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst); + bool MatchInstructionImpl( + const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst); + /// } public: @@ -132,7 +135,7 @@ struct X86Operand : public MCParsedAsmOp X86Operand(KindTy K, SMLoc Start, SMLoc End) : Kind(K), StartLoc(Start), EndLoc(End) {} - + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. @@ -142,6 +145,11 @@ struct X86Operand : public MCParsedAsmOp assert(Kind == Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } + void setTokenValue(StringRef Value) { + assert(Kind == Token && "Invalid access!"); + Tok.Data = Value.data(); + Tok.Length = Value.size(); + } unsigned getReg() const { assert(Kind == Register && "Invalid access!"); @@ -632,6 +640,54 @@ void X86ATTAsmParser::InstructionCleanup } } +bool +X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> + &Operands, + MCInst &Inst) { + // First, try a direct match. + if (!MatchInstructionImpl(Operands, Inst)) + return false; + + // Ignore anything which is obviously not a suffix match. + if (Operands.size() == 0) + return true; + X86Operand *Op = static_cast<X86Operand*>(Operands[0]); + if (!Op->isToken() || Op->getToken().size() > 15) + return true; + + // FIXME: Ideally, we would only attempt suffix matches for things which are + // valid prefixes, and we could just infer the right unambiguous + // type. However, that requires substantially more matcher support than the + // following hack. + + // Change the operand to point to a temporary token. + char Tmp[16]; + StringRef Base = Op->getToken(); + memcpy(Tmp, Base.data(), Base.size()); + Op->setTokenValue(StringRef(Tmp, Base.size() + 1)); + + // Check for the various suffix matches. + Tmp[Base.size()] = 'b'; + bool MatchB = MatchInstructionImpl(Operands, Inst); + Tmp[Base.size()] = 'w'; + bool MatchW = MatchInstructionImpl(Operands, Inst); + Tmp[Base.size()] = 'l'; + bool MatchL = MatchInstructionImpl(Operands, Inst); + + // Restore the old token. + Op->setTokenValue(Base); + + // If exactly one matched, then we treat that as a successful match (and the + // instruction will already have been filled in correctly, since the failing + // matches won't have modified it). + if (MatchB + MatchW + MatchL == 2) + return false; + + // Otherwise, the match failed. + return true; +} + + extern "C" void LLVMInitializeX86AsmLexer(); // Force static initialization. Modified: vendor/llvm/dist/lib/Target/X86/X86.td ============================================================================== --- vendor/llvm/dist/lib/Target/X86/X86.td Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Target/X86/X86.td Tue May 4 20:50:39 2010 (r207631) @@ -179,8 +179,9 @@ include "X86CallingConv.td" // Currently the X86 assembly parser only supports ATT syntax. def ATTAsmParser : AsmParser { - string AsmParserClassName = "ATTAsmParser"; - string AsmParserInstCleanup = "InstructionCleanup"; + string AsmParserClassName = "ATTAsmParser"; + string AsmParserInstCleanup = "InstructionCleanup"; + string MatchInstructionName = "MatchInstructionImpl"; int Variant = 0; // Discard comments in assembly strings. Modified: vendor/llvm/dist/lib/Transforms/Scalar/GVN.cpp ============================================================================== --- vendor/llvm/dist/lib/Transforms/Scalar/GVN.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/Transforms/Scalar/GVN.cpp Tue May 4 20:50:39 2010 (r207631) @@ -1584,7 +1584,7 @@ bool GVN::processNonLocalLoad(LoadInst * for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i) FullyAvailableBlocks[UnavailableBlocks[i]] = false; - bool NeedToSplitEdges = false; + SmallVector<std::pair<TerminatorInst*, unsigned>, 4> NeedToSplit; for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); PI != E; ++PI) { BasicBlock *Pred = *PI; @@ -1600,12 +1600,13 @@ bool GVN::processNonLocalLoad(LoadInst * return false; } unsigned SuccNum = GetSuccessorNumber(Pred, LoadBB); - toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum)); - NeedToSplitEdges = true; + NeedToSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum)); } } - if (NeedToSplitEdges) + if (!NeedToSplit.empty()) { + toSplit.append(NeedToSplit.size(), NeedToSplit.front()); return false; + } // Decide whether PRE is profitable for this load. unsigned NumUnavailablePreds = PredLoads.size(); Modified: vendor/llvm/dist/lib/VMCore/Metadata.cpp ============================================================================== --- vendor/llvm/dist/lib/VMCore/Metadata.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/lib/VMCore/Metadata.cpp Tue May 4 20:50:39 2010 (r207631) @@ -115,14 +115,17 @@ MDNode::~MDNode() { } static const Function *getFunctionForValue(Value *V) { - assert(!isa<MDNode>(V) && "does not iterate over metadata operands"); if (!V) return NULL; - if (Instruction *I = dyn_cast<Instruction>(V)) - return I->getParent()->getParent(); - if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) - return BB->getParent(); + if (Instruction *I = dyn_cast<Instruction>(V)) { + BasicBlock *BB = I->getParent(); + return BB ? BB->getParent() : 0; + } if (Argument *A = dyn_cast<Argument>(V)) return A->getParent(); + if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) + return BB->getParent(); + if (MDNode *MD = dyn_cast<MDNode>(V)) + return MD->getFunction(); return NULL; } @@ -156,17 +159,9 @@ const Function *MDNode::getFunction() co return assertLocalFunction(this); #endif if (!isFunctionLocal()) return NULL; - - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - if (Value *V = getOperand(i)) { - if (MDNode *MD = dyn_cast<MDNode>(V)) { - if (const Function *F = MD->getFunction()) - return F; - } else { - return getFunctionForValue(V); - } - } - } + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (const Function *F = getFunctionForValue(getOperand(i))) + return F; return NULL; } @@ -272,8 +267,19 @@ void MDNode::replaceOperand(MDNodeOperan // with an instruction or some other function-local object. If this is a // non-function-local MDNode, it can't point to a function-local object. // Handle this case by implicitly dropping the MDNode reference to null. - if (!isFunctionLocal() && To && isFunctionLocalValue(To)) - To = 0; + // Likewise if the MDNode is function-local but for a different function. + if (To && isFunctionLocalValue(To)) { + if (!isFunctionLocal()) + To = 0; + else { + const Function *F = getFunction(); + const Function *FV = getFunctionForValue(To); + // Metadata can be function-local without having an associated function. + // So only consider functions to have changed if non-null. + if (F && FV && F != FV) + To = 0; + } + } if (From == To) return; Added: vendor/llvm/dist/test/CodeGen/CellSPU/storestruct.ll ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm/dist/test/CodeGen/CellSPU/storestruct.ll Tue May 4 20:50:39 2010 (r207631) @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=cellspu | FileCheck %s + +%0 = type {i32, i32} +@buffer = global [ 72 x %0 ] zeroinitializer + +define void@test( ) { +; Check that there is no illegal "a rt, ra, imm" instruction +; CHECK-NOT: a {{\$., \$., 5..}} +; CHECK: a {{\$., \$., \$.}} + store %0 {i32 1, i32 2} , + %0* getelementptr ([72 x %0]* @buffer, i32 0, i32 71) + ret void +} Added: vendor/llvm/dist/test/MC/AsmParser/X86/x86_64-suffix-matching.s ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/llvm/dist/test/MC/AsmParser/X86/x86_64-suffix-matching.s Tue May 4 20:50:39 2010 (r207631) @@ -0,0 +1,6 @@ +// RUN: llvm-mc -triple x86_64 -o - %s | FileCheck %s + +// CHECK: addl $0, %eax + add $0, %eax +// CHECK: addb $255, %al + add $0xFF, %al Modified: vendor/llvm/dist/test/Transforms/GlobalOpt/metadata.ll ============================================================================== --- vendor/llvm/dist/test/Transforms/GlobalOpt/metadata.ll Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/test/Transforms/GlobalOpt/metadata.ll Tue May 4 20:50:39 2010 (r207631) @@ -1,7 +1,8 @@ ; RUN: opt -S -globalopt < %s | FileCheck %s ; PR6112 - When globalopt does RAUW(@G, %G), the metadata reference should drop -; to null. +; to null. Function local metadata that references @G from a different function +; to that containing %G should likewise drop to null. @G = internal global i8** null define i32 @main(i32 %argc, i8** %argv) { @@ -11,9 +12,15 @@ define i32 @main(i32 %argc, i8** %argv) ret i32 0 } -!named = !{!0} +define void @foo(i32 %x) { + call void @llvm.foo(metadata !{i8*** @G, i32 %x}) +; CHECK: call void @llvm.foo(metadata !{null, i32 %x}) + ret void +} -; CHECK: !0 = metadata !{null} -!0 = metadata !{i8*** @G} +declare void @llvm.foo(metadata) nounwind readnone +!named = !{!0} +!0 = metadata !{i8*** @G} +; CHECK: !0 = metadata !{null} Modified: vendor/llvm/dist/utils/TableGen/ClangDiagnosticsEmitter.cpp ============================================================================== --- vendor/llvm/dist/utils/TableGen/ClangDiagnosticsEmitter.cpp Tue May 4 19:58:55 2010 (r207630) +++ vendor/llvm/dist/utils/TableGen/ClangDiagnosticsEmitter.cpp Tue May 4 20:50:39 2010 (r207631) @@ -17,12 +17,109 @@ #include "llvm/Support/Compiler.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/VectorExtras.h" #include <set> #include <map> using namespace llvm; //===----------------------------------------------------------------------===// +// Diagnostic category computation code. +//===----------------------------------------------------------------------===// + +namespace { +class DiagGroupParentMap { + std::map<const Record*, std::vector<Record*> > Mapping; +public: + DiagGroupParentMap() { + std::vector<Record*> DiagGroups + = Records.getAllDerivedDefinitions("DiagGroup"); + for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { + std::vector<Record*> SubGroups = + DiagGroups[i]->getValueAsListOfDefs("SubGroups"); + for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) + Mapping[SubGroups[j]].push_back(DiagGroups[i]); + } + } + + const std::vector<Record*> &getParents(const Record *Group) { + return Mapping[Group]; + } +}; +} // end anonymous namespace. + + +static std::string +getCategoryFromDiagGroup(const Record *Group, + DiagGroupParentMap &DiagGroupParents) { + // If the DiagGroup has a category, return it. + std::string CatName = Group->getValueAsString("CategoryName"); + if (!CatName.empty()) return CatName; + + // The diag group may the subgroup of one or more other diagnostic groups, + // check these for a category as well. + const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); + for (unsigned i = 0, e = Parents.size(); i != e; ++i) { + CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents); + if (!CatName.empty()) return CatName; + } + return ""; +} + +/// getDiagnosticCategory - Return the category that the specified diagnostic +/// lives in. +static std::string getDiagnosticCategory(const Record *R, + DiagGroupParentMap &DiagGroupParents) { + // If the diagnostic itself has a category, get it. + std::string CatName = R->getValueAsString("CategoryName"); + if (!CatName.empty()) return CatName; + + DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group")); + if (Group == 0) return ""; + + // Check the diagnostic's diag group for a category. + return getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents); +} + +namespace { + class DiagCategoryIDMap { + StringMap<unsigned> CategoryIDs; + std::vector<std::string> CategoryStrings; + public: + DiagCategoryIDMap() { + DiagGroupParentMap ParentInfo; + + // The zero'th category is "". + CategoryStrings.push_back(""); + CategoryIDs[""] = 0; + + std::vector<Record*> Diags = + Records.getAllDerivedDefinitions("Diagnostic"); + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { + std::string Category = getDiagnosticCategory(Diags[i], ParentInfo); + if (Category.empty()) continue; // Skip diags with no category. + + unsigned &ID = CategoryIDs[Category]; + if (ID != 0) continue; // Already seen. + + ID = CategoryStrings.size(); + CategoryStrings.push_back(Category); + } + } + + unsigned getID(StringRef CategoryString) { + return CategoryIDs[CategoryString]; + } + + typedef std::vector<std::string>::iterator iterator; + iterator begin() { return CategoryStrings.begin(); } + iterator end() { return CategoryStrings.end(); } + }; +} // end anonymous namespace. + + + +//===----------------------------------------------------------------------===// // Warning Tables (.inc file) generation. //===----------------------------------------------------------------------===// @@ -40,6 +137,9 @@ void ClangDiagsDefsEmitter::run(raw_ostr const std::vector<Record*> &Diags = Records.getAllDerivedDefinitions("Diagnostic"); + DiagCategoryIDMap CategoryIDs; + DiagGroupParentMap DGParentMap; + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record &R = *Diags[i]; // Filter by component. @@ -67,6 +167,9 @@ void ClangDiagsDefsEmitter::run(raw_ostr OS << ", true"; else OS << ", false"; + + // Category number. + OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); OS << ")\n"; } } @@ -82,6 +185,9 @@ struct GroupInfo { }; void ClangDiagGroupsEmitter::run(raw_ostream &OS) { + // Compute a mapping from a DiagGroup to all of its parents. + DiagGroupParentMap DGParentMap; + // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of // groups to diags in the group. std::map<std::string, GroupInfo> DiagsInGroup; @@ -98,9 +204,10 @@ void ClangDiagGroupsEmitter::run(raw_ost // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). - Diags = Records.getAllDerivedDefinitions("DiagGroup"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - Record *Group = Diags[i]; + std::vector<Record*> DiagGroups + = Records.getAllDerivedDefinitions("DiagGroup"); + for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { + Record *Group = DiagGroups[i]; GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups"); @@ -167,4 +274,12 @@ void ClangDiagGroupsEmitter::run(raw_ost OS << " },\n"; } OS << "#endif // GET_DIAG_TABLE\n\n"; + + // Emit the category table next. + DiagCategoryIDMap CategoriesByID; + OS << "\n#ifdef GET_CATEGORY_TABLE\n"; + for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(), + E = CategoriesByID.end(); I != E; ++I) + OS << "CATEGORY(\"" << *I << "\")\n"; + OS << "#endif // GET_CATEGORY_TABLE\n\n"; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201005042050.o44KodLt029690>