summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-05-04 20:50:39 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-05-04 20:50:39 +0000
commit377552607e51dc1d3e6ff33833f9620bcfe815ac (patch)
tree3c3ffb5df9fa6dfb2c48b807faf73dd2943db75d /lib
parent750ce4d809c7e2a298a389a512a17652ff5be3f2 (diff)
downloadFreeBSD-src-377552607e51dc1d3e6ff33833f9620bcfe815ac.zip
FreeBSD-src-377552607e51dc1d3e6ff33833f9620bcfe815ac.tar.gz
Update LLVM to r103052.
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp24
-rw-r--r--lib/CodeGen/PHIElimination.cpp81
-rw-r--r--lib/CodeGen/PHIElimination.h2
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp13
-rw-r--r--lib/Target/ARM/NEONPreAllocPass.cpp28
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp12
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp60
-rw-r--r--lib/Target/X86/X86.td5
-rw-r--r--lib/Transforms/Scalar/GVN.cpp9
-rw-r--r--lib/VMCore/Metadata.cpp42
10 files changed, 236 insertions, 40 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 26a7190..ca9921c 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -262,6 +262,23 @@ static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
}
#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::handleVirtualRegisterDef(MachineBasicBlock *mbb,
}
} 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
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index f0057ce..1651719 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -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::getAnalysisUsage(AnalysisUsage &AU) const {
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::runOnMachineFunction(MachineFunction &Fn) {
// 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::LowerAtomicPHINode(
/// 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::SplitCriticalEdge(MachineBasicBlock *A,
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;
+}
diff --git a/lib/CodeGen/PHIElimination.h b/lib/CodeGen/PHIElimination.h
index 7dedf03..3292aa2 100644
--- a/lib/CodeGen/PHIElimination.h
+++ b/lib/CodeGen/PHIElimination.h
@@ -94,6 +94,8 @@ namespace llvm {
return I;
}
+ bool EliminateRegSequences(MachineFunction &MF);
+
typedef std::pair<unsigned, unsigned> BBVRegPair;
typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 36a1827..616942c 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -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::SelectT2IndexedLoad(SDNode *N) {
/// 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,
diff --git a/lib/Target/ARM/NEONPreAllocPass.cpp b/lib/Target/ARM/NEONPreAllocPass.cpp
index 7334259..ef6bf3a 100644
--- a/lib/Target/ARM/NEONPreAllocPass.cpp
+++ b/lib/Target/ARM/NEONPreAllocPass.cpp
@@ -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, unsigned &FirstOpnd, unsigned &NumRegs,
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::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
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::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
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;
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index c3c2b39..9afdb2b 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -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;
}
}
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index da01350..6b403c1 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -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 MCParsedAsmOperand {
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 MCParsedAsmOperand {
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(MCInst &Inst) {
}
}
+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.
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index ec86fc2..a53f973 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -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.
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 321def7..65b34b1 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -1584,7 +1584,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI,
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 *LI,
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();
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 092fe00..b894ea3 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -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() const {
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(MDNodeOperand *Op, Value *To) {
// 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;
OpenPOWER on IntegriCloud