From ojomojo at gmail.com Mon Dec 7 03:06:40 2009 From: ojomojo at gmail.com (John Mosby) Date: Mon, 07 Dec 2009 09:06:40 -0000 Subject: [llvm-commits] [llvm] r90754 - in /llvm/trunk/include/llvm/Analysis: LoopDependenceAnalysis.h LoopPass.h Message-ID: <200912070906.nB796fQV026022@zion.cs.uiuc.edu> Author: jdm Date: Mon Dec 7 03:06:37 2009 New Revision: 90754 URL: http://llvm.org/viewvc/llvm-project?rev=90754&view=rev Log: fixed some typos in method comments, reworded some comments for clarity Modified: llvm/trunk/include/llvm/Analysis/LoopDependenceAnalysis.h llvm/trunk/include/llvm/Analysis/LoopPass.h Modified: llvm/trunk/include/llvm/Analysis/LoopDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopDependenceAnalysis.h?rev=90754&r1=90753&r2=90754&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopDependenceAnalysis.h Mon Dec 7 03:06:37 2009 @@ -67,17 +67,17 @@ /// created. The third argument is set to the pair found or created. bool findOrInsertDependencePair(Value*, Value*, DependencePair*&); - /// getLoops - Collect all loops of the loop-nest L a given SCEV is variant - /// in. + /// getLoops - Collect all loops of the loop nest L in which + /// a given SCEV is variant. void getLoops(const SCEV*, DenseSet*) const; /// isLoopInvariant - True if a given SCEV is invariant in all loops of the - /// loop-nest starting at the innermost loop L. + /// loop nest starting at the innermost loop L. bool isLoopInvariant(const SCEV*) const; - /// isAffine - An SCEV is affine with respect to the loop-nest starting at + /// isAffine - An SCEV is affine with respect to the loop nest starting at /// the innermost loop L if it is of the form A+B*X where A, B are invariant - /// in the loop-nest and X is a induction variable in the loop-nest. + /// in the loop nest and X is a induction variable in the loop nest. bool isAffine(const SCEV*) const; /// TODO: doc @@ -93,8 +93,8 @@ static char ID; // Class identification, replacement for typeinfo LoopDependenceAnalysis() : LoopPass(&ID) {} - /// isDependencePair - Check wether two values can possibly give rise to a - /// data dependence: that is the case if both are instructions accessing + /// isDependencePair - Check whether two values can possibly give rise to + /// a data dependence: that is the case if both are instructions accessing /// memory and at least one of those accesses is a write. bool isDependencePair(const Value*, const Value*) const; Modified: llvm/trunk/include/llvm/Analysis/LoopPass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopPass.h?rev=90754&r1=90753&r2=90754&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopPass.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopPass.h Mon Dec 7 03:06:37 2009 @@ -52,7 +52,7 @@ // LPPassManger as expected. void preparePassManager(PMStack &PMS); - /// Assign pass manager to manager this pass + /// Assign pass manager to manage this pass virtual void assignPassManager(PMStack &PMS, PassManagerType PMT = PMT_LoopPassManager); @@ -73,7 +73,7 @@ /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block. virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {} - /// deletekAnalysisValue - Delete analysis info associated with value V. + /// deleteAnalysisValue - Delete analysis info associated with value V. virtual void deleteAnalysisValue(Value *V, Loop *L) {} }; From evan.cheng at apple.com Mon Dec 7 04:15:20 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 10:15:20 -0000 Subject: [llvm-commits] [llvm] r90759 - in /llvm/trunk: include/llvm/CodeGen/MachineSSAUpdater.h lib/CodeGen/MachineSSAUpdater.cpp lib/CodeGen/TailDuplication.cpp Message-ID: <200912071015.nB7AFKWn029279@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 04:15:19 2009 New Revision: 90759 URL: http://llvm.org/viewvc/llvm-project?rev=90759&view=rev Log: Pre-regalloc tale duplication. Work in progress. Modified: llvm/trunk/include/llvm/CodeGen/MachineSSAUpdater.h llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineSSAUpdater.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineSSAUpdater.h?rev=90759&r1=90758&r2=90759&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineSSAUpdater.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineSSAUpdater.h Mon Dec 7 04:15:19 2009 @@ -104,6 +104,7 @@ void RewriteUse(MachineOperand &U); private: + void ReplaceRegWith(unsigned OldReg, unsigned NewReg); unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB); void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT Modified: llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp?rev=90759&r1=90758&r2=90759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp Mon Dec 7 04:15:19 2009 @@ -207,6 +207,16 @@ U.setReg(NewVR); } +void MachineSSAUpdater::ReplaceRegWith(unsigned OldReg, unsigned NewReg) { + MRI->replaceRegWith(OldReg, NewReg); + + AvailableValsTy &AvailableVals = getAvailableVals(AV); + for (DenseMap::iterator + I = AvailableVals.begin(), E = AvailableVals.end(); I != E; ++I) + if (I->second == OldReg) + I->second = NewReg; +} + /// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry /// for the specified BB and if so, return it. If not, construct SSA form by /// walking predecessors inserting PHI nodes as needed until we get to a block @@ -297,7 +307,7 @@ MachineInstr *OldVal = MRI->getVRegDef(InsertedVal); // Be careful about dead loops. These RAUW's also update InsertedVal. assert(InsertedVal != SingularValue && "Dead loop?"); - MRI->replaceRegWith(InsertedVal, SingularValue); + ReplaceRegWith(InsertedVal, SingularValue); OldVal->eraseFromParent(); } Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=90759&r1=90758&r2=90759&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Dec 7 04:15:19 2009 @@ -22,12 +22,14 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" using namespace llvm; +STATISTIC(NumTails , "Number of tails duplicated"); STATISTIC(NumTailDups , "Number of tail duplicated blocks"); STATISTIC(NumInstrDups , "Additional instructions due to tail duplication"); STATISTIC(NumDeadBlocks, "Number of dead blocks removed"); @@ -38,6 +40,14 @@ cl::desc("Maximum instructions to consider tail duplicating"), cl::init(2), cl::Hidden); +static cl::opt +TailDupVerify("tail-dup-verify", + cl::desc("Verify sanity of PHI instructions during taildup"), + cl::init(false), cl::Hidden); + +static cl::opt +TailDupLimit("tail-dup-limit", cl::init(~0U), cl::Hidden); + typedef std::vector > AvailableValsTy; namespace { @@ -68,16 +78,19 @@ MachineBasicBlock *BB); void ProcessPHI(MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, - DenseMap &LocalVRMap); + DenseMap &LocalVRMap, + SmallVector, 4> &Copies); void DuplicateInstruction(MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, MachineFunction &MF, DenseMap &LocalVRMap); - void UpdateSuccessorsPHIs(MachineBasicBlock *FromBB,MachineBasicBlock *ToBB, - SmallSetVector &Succs); + void UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead, + SmallVector &TDBBs, + SmallSetVector &Succs); bool TailDuplicateBlocks(MachineFunction &MF); - bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF); + bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF, + SmallVector &TDBBs); void RemoveDeadBlock(MachineBasicBlock *MBB); }; @@ -104,28 +117,153 @@ return MadeChange; } +static void VerifyPHIs(MachineFunction &MF, bool CheckExtra) { + for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ++I) { + MachineBasicBlock *MBB = I; + SmallSetVector Preds(MBB->pred_begin(), + MBB->pred_end()); + MachineBasicBlock::iterator MI = MBB->begin(); + while (MI != MBB->end()) { + if (MI->getOpcode() != TargetInstrInfo::PHI) + break; + for (SmallSetVector::iterator PI = Preds.begin(), + PE = Preds.end(); PI != PE; ++PI) { + MachineBasicBlock *PredBB = *PI; + bool Found = false; + for (unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) { + MachineBasicBlock *PHIBB = MI->getOperand(i+1).getMBB(); + if (PHIBB == PredBB) { + Found = true; + break; + } + } + if (!Found) { + errs() << "Malformed PHI in BB#" << MBB->getNumber() << ": " << *MI; + errs() << " missing input from predecessor BB#" + << PredBB->getNumber() << '\n'; + llvm_unreachable(0); + } + } + + for (unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) { + MachineBasicBlock *PHIBB = MI->getOperand(i+1).getMBB(); + if (CheckExtra && !Preds.count(PHIBB)) { + // This is not a hard error. + errs() << "Warning: malformed PHI in BB#" << MBB->getNumber() + << ": " << *MI; + errs() << " extra input from predecessor BB#" + << PHIBB->getNumber() << '\n'; + } + if (PHIBB->getNumber() < 0) { + errs() << "Malformed PHI in BB#" << MBB->getNumber() << ": " << *MI; + errs() << " non-existing BB#" << PHIBB->getNumber() << '\n'; + llvm_unreachable(0); + } + } + ++MI; + } + } +} + /// TailDuplicateBlocks - Look for small blocks that are unconditionally /// branched to and do not fall through. Tail-duplicate their instructions /// into their predecessors to eliminate (dynamic) branches. bool TailDuplicatePass::TailDuplicateBlocks(MachineFunction &MF) { bool MadeChange = false; + if (PreRegAlloc && TailDupVerify) { + DEBUG(errs() << "\n*** Before tail-duplicating\n"); + VerifyPHIs(MF, true); + } + + SmallVector NewPHIs; + MachineSSAUpdater SSAUpdate(MF, &NewPHIs); + for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = I++; + if (NumTails == TailDupLimit) + break; + // Only duplicate blocks that end with unconditional branches. if (MBB->canFallThrough()) continue; - MadeChange |= TailDuplicate(MBB, MF); + // Save the successors list. + SmallSetVector Succs(MBB->succ_begin(), + MBB->succ_end()); + + SmallVector TDBBs; + if (TailDuplicate(MBB, MF, TDBBs)) { + ++NumTails; + + // TailBB's immediate successors are now successors of those predecessors + // which duplicated TailBB. Add the predecessors as sources to the PHI + // instructions. + bool isDead = MBB->pred_empty(); + if (PreRegAlloc) + UpdateSuccessorsPHIs(MBB, isDead, TDBBs, Succs); + + // If it is dead, remove it. + if (isDead) { + NumInstrDups -= MBB->size(); + RemoveDeadBlock(MBB); + ++NumDeadBlocks; + } + + // Update SSA form. + if (!SSAUpdateVRs.empty()) { + for (unsigned i = 0, e = SSAUpdateVRs.size(); i != e; ++i) { + unsigned VReg = SSAUpdateVRs[i]; + SSAUpdate.Initialize(VReg); + + // If the original definition is still around, add it as an available + // value. + MachineInstr *DefMI = MRI->getVRegDef(VReg); + MachineBasicBlock *DefBB = 0; + if (DefMI) { + DefBB = DefMI->getParent(); + SSAUpdate.AddAvailableValue(DefBB, VReg); + } + + // Add the new vregs as available values. + DenseMap::iterator LI = + SSAUpdateVals.find(VReg); + for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) { + MachineBasicBlock *SrcBB = LI->second[j].first; + unsigned SrcReg = LI->second[j].second; + SSAUpdate.AddAvailableValue(SrcBB, SrcReg); + } + + // Rewrite uses that are outside of the original def's block. + MachineRegisterInfo::use_iterator UI = MRI->use_begin(VReg); + while (UI != MRI->use_end()) { + MachineOperand &UseMO = UI.getOperand(); + MachineInstr *UseMI = &*UI; + ++UI; + if (UseMI->getParent() == DefBB) + continue; + SSAUpdate.RewriteUse(UseMO); + while (!NewPHIs.empty()) { + MachineInstr *NewPHI = NewPHIs.back(); + NewPHIs.pop_back(); + unsigned PHIDef = NewPHI->getOperand(0).getReg(); + for (unsigned j = 1, ee = NewPHI->getNumOperands(); j != ee; + j += 2) { + if (NewPHI->getOperand(j).getReg() == VReg) + NewPHI->getOperand(j).setReg(PHIDef); + } + } + } + } + + SSAUpdateVRs.clear(); + SSAUpdateVals.clear(); + } - // If it is dead, remove it. Don't do this if this pass is run before - // register allocation to avoid having to update PHI nodes. - if (!PreRegAlloc && MBB->pred_empty()) { - NumInstrDups -= MBB->size(); - RemoveDeadBlock(MBB); + if (PreRegAlloc && TailDupVerify) + VerifyPHIs(MF, false); MadeChange = true; - ++NumDeadBlocks; } } @@ -165,19 +303,27 @@ } } -/// ProcessPHI - Process but do not duplicate a PHI node in TailBB. Remember the -/// source register that's contributed by PredBB and update SSA update map. +/// ProcessPHI - Process PHI node in TailBB by turning it into a copy in PredBB. +/// Remember the source register that's contributed by PredBB and update SSA +/// update map. void TailDuplicatePass::ProcessPHI(MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, - DenseMap &LocalVRMap) { + DenseMap &LocalVRMap, + SmallVector, 4> &Copies) { unsigned DefReg = MI->getOperand(0).getReg(); unsigned SrcOpIdx = getPHISrcRegOpIdx(MI, PredBB); assert(SrcOpIdx && "Unable to find matching PHI source?"); unsigned SrcReg = MI->getOperand(SrcOpIdx).getReg(); + const TargetRegisterClass *RC = MRI->getRegClass(DefReg); LocalVRMap.insert(std::make_pair(DefReg, SrcReg)); + + // Insert a copy from source to the end of the block. The def register is the + // available value liveout of the block. + unsigned NewDef = MRI->createVirtualRegister(RC); + Copies.push_back(std::make_pair(NewDef, SrcReg)); if (isDefLiveOut(DefReg, TailBB, MRI)) - AddSSAUpdateEntry(DefReg, SrcReg, PredBB); + AddSSAUpdateEntry(DefReg, NewDef, PredBB); // Remove PredBB from the PHI node. MI->RemoveOperand(SrcOpIdx+1); @@ -220,8 +366,9 @@ /// UpdateSuccessorsPHIs - After FromBB is tail duplicated into its predecessor /// blocks, the successors have gained new predecessors. Update the PHI /// instructions in them accordingly. -void TailDuplicatePass::UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, - MachineBasicBlock *ToBB, +void +TailDuplicatePass::UpdateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead, + SmallVector &TDBBs, SmallSetVector &Succs) { for (SmallSetVector::iterator SI = Succs.begin(), SE = Succs.end(); SI != SE; ++SI) { @@ -230,27 +377,48 @@ II != EE; ++II) { if (II->getOpcode() != TargetInstrInfo::PHI) break; + unsigned Idx = 0; for (unsigned i = 1, e = II->getNumOperands(); i != e; i += 2) { - MachineOperand &MO1 = II->getOperand(i+1); - if (MO1.getMBB() != FromBB) - continue; - MachineOperand &MO0 = II->getOperand(i); - unsigned Reg = MO0.getReg(); - if (ToBB) { - // Folded into the previous BB. - II->RemoveOperand(i+1); - II->RemoveOperand(i); - } - DenseMap::iterator LI=SSAUpdateVals.find(Reg); - if (LI == SSAUpdateVals.end()) + MachineOperand &MO = II->getOperand(i+1); + if (MO.getMBB() == FromBB) { + Idx = i; break; + } + } + + assert(Idx != 0); + MachineOperand &MO0 = II->getOperand(Idx); + unsigned Reg = MO0.getReg(); + if (isDead) { + // Folded into the previous BB. + // There could be duplicate phi source entries. FIXME: Should sdisel + // or earlier pass fixed this? + for (unsigned i = II->getNumOperands()-2; i != Idx; i -= 2) { + MachineOperand &MO = II->getOperand(i+1); + if (MO.getMBB() == FromBB) { + II->RemoveOperand(i+1); + II->RemoveOperand(i); + } + } + II->RemoveOperand(Idx+1); + II->RemoveOperand(Idx); + } + DenseMap::iterator LI=SSAUpdateVals.find(Reg); + if (LI != SSAUpdateVals.end()) { + // This register is defined in the tail block. for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) { MachineBasicBlock *SrcBB = LI->second[j].first; unsigned SrcReg = LI->second[j].second; II->addOperand(MachineOperand::CreateReg(SrcReg, false)); II->addOperand(MachineOperand::CreateMBB(SrcBB)); } - break; + } else { + // Live in tail block, must also be live in predecessors. + for (unsigned j = 0, ee = TDBBs.size(); j != ee; ++j) { + MachineBasicBlock *SrcBB = TDBBs[j]; + II->addOperand(MachineOperand::CreateReg(Reg, false)); + II->addOperand(MachineOperand::CreateMBB(SrcBB)); + } } } } @@ -258,8 +426,9 @@ /// TailDuplicate - If it is profitable, duplicate TailBB's contents in each /// of its predecessors. -bool TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, - MachineFunction &MF) { +bool +TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF, + SmallVector &TDBBs) { // Don't try to tail-duplicate single-block loops. if (TailBB->isSuccessor(TailBB)) return false; @@ -304,6 +473,8 @@ if (InstrCount > 1 && HasCall) return false; + DEBUG(errs() << "\n*** Tail-duplicating BB#" << TailBB->getNumber() << '\n'); + // Iterate through all the unique predecessors and tail-duplicate this // block into them, if possible. Copying the list ahead of time also // avoids trouble with the predecessor list reallocating. @@ -334,11 +505,14 @@ DEBUG(errs() << "\nTail-duplicating into PredBB: " << *PredBB << "From Succ: " << *TailBB); + TDBBs.push_back(PredBB); + // Remove PredBB's unconditional branch. TII->RemoveBranch(*PredBB); // Clone the contents of TailBB into PredBB. DenseMap LocalVRMap; + SmallVector, 4> Copies; MachineBasicBlock::iterator I = TailBB->begin(); while (I != TailBB->end()) { MachineInstr *MI = &*I; @@ -346,13 +520,18 @@ if (MI->getOpcode() == TargetInstrInfo::PHI) { // Replace the uses of the def of the PHI with the register coming // from PredBB. - ProcessPHI(MI, TailBB, PredBB, LocalVRMap); + ProcessPHI(MI, TailBB, PredBB, LocalVRMap, Copies); } else { // Replace def of virtual registers with new registers, and update // uses with PHI source register or the new registers. DuplicateInstruction(MI, TailBB, PredBB, MF, LocalVRMap); } } + MachineBasicBlock::iterator Loc = PredBB->getFirstTerminator(); + for (unsigned i = 0, e = Copies.size(); i != e; ++i) { + const TargetRegisterClass *RC = MRI->getRegClass(Copies[i].first); + TII->copyRegToReg(*PredBB, Loc, Copies[i].first, Copies[i].second, RC, RC); + } NumInstrDups += TailBB->size() - 1; // subtract one for removed branch // Update the CFG. @@ -367,10 +546,6 @@ ++NumTailDups; } - // Save the successors list. - SmallSetVector Succs(TailBB->succ_begin(), - TailBB->succ_end()); - // If TailBB was duplicated into all its predecessors except for the prior // block, which falls through unconditionally, move the contents of this // block into the prior block. @@ -381,9 +556,6 @@ TII->AnalyzeBranch(*PrevBB, PriorTBB, PriorFBB, PriorCond, true); // This has to check PrevBB->succ_size() because EH edges are ignored by // AnalyzeBranch. - // If TailBB starts with PHIs, then don't bother. Let the post regalloc - // run clean it up. - MachineBasicBlock *NewTailBB = 0; if (!PriorUnAnalyzable && PriorCond.empty() && !PriorTBB && TailBB->pred_size() == 1 && PrevBB->succ_size() == 1 && !TailBB->hasAddressTaken()) { @@ -391,13 +563,14 @@ << "From MBB: " << *TailBB); if (PreRegAlloc) { DenseMap LocalVRMap; + SmallVector, 4> Copies; MachineBasicBlock::iterator I = TailBB->begin(); // Process PHI instructions first. while (I != TailBB->end() && I->getOpcode() == TargetInstrInfo::PHI) { // Replace the uses of the def of the PHI with the register coming // from PredBB. MachineInstr *MI = &*I++; - ProcessPHI(MI, TailBB, PrevBB, LocalVRMap); + ProcessPHI(MI, TailBB, PrevBB, LocalVRMap, Copies); if (MI->getParent()) MI->eraseFromParent(); } @@ -410,6 +583,11 @@ DuplicateInstruction(MI, TailBB, PrevBB, MF, LocalVRMap); MI->eraseFromParent(); } + MachineBasicBlock::iterator Loc = PrevBB->getFirstTerminator(); + for (unsigned i = 0, e = Copies.size(); i != e; ++i) { + const TargetRegisterClass *RC = MRI->getRegClass(Copies[i].first); + TII->copyRegToReg(*PrevBB, Loc, Copies[i].first, Copies[i].second, RC, RC); + } } else { // No PHIs to worry about, just splice the instructions over. PrevBB->splice(PrevBB->end(), TailBB, TailBB->begin(), TailBB->end()); @@ -417,58 +595,10 @@ PrevBB->removeSuccessor(PrevBB->succ_begin()); assert(PrevBB->succ_empty()); PrevBB->transferSuccessors(TailBB); - NewTailBB = PrevBB; + TDBBs.push_back(PrevBB); Changed = true; } - if (!PreRegAlloc) - return Changed; - - // TailBB's immediate successors are now successors of those predecessors - // which duplicated TailBB. Add the predecessors as sources to the PHI - // instructions. - UpdateSuccessorsPHIs(TailBB, NewTailBB, Succs); - - if (!SSAUpdateVRs.empty()) { - // Update SSA form. - MachineSSAUpdater SSAUpdate(MF); - for (unsigned i = 0, e = SSAUpdateVRs.size(); i != e; ++i) { - unsigned VReg = SSAUpdateVRs[i]; - SSAUpdate.Initialize(VReg); - - // If the original definition is still around, add it as an available - // value. - MachineInstr *DefMI = MRI->getVRegDef(VReg); - MachineBasicBlock *DefBB = 0; - if (DefMI) { - DefBB = DefMI->getParent(); - SSAUpdate.AddAvailableValue(DefBB, VReg); - } - - // Add the new vregs as available values. - DenseMap::iterator LI = - SSAUpdateVals.find(VReg); - for (unsigned j = 0, ee = LI->second.size(); j != ee; ++j) { - MachineBasicBlock *SrcBB = LI->second[j].first; - unsigned SrcReg = LI->second[j].second; - SSAUpdate.AddAvailableValue(SrcBB, SrcReg); - } - - // Rewrite uses that are outside of the original def's block. - MachineRegisterInfo::use_iterator UI = MRI->use_begin(VReg); - while (UI != MRI->use_end()) { - MachineOperand &UseMO = UI.getOperand(); - MachineInstr *UseMI = &*UI; - ++UI; - if (UseMI->getParent() != DefBB) - SSAUpdate.RewriteUse(UseMO); - } - } - - SSAUpdateVRs.clear(); - SSAUpdateVals.clear(); - } - return Changed; } From baldrick at free.fr Mon Dec 7 04:39:55 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 10:39:55 -0000 Subject: [llvm-commits] [dragonegg] r90761 - /dragonegg/trunk/gcc-patches/i386_static.diff Message-ID: <200912071039.nB7Adtnd030158@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 04:39:55 2009 New Revision: 90761 URL: http://llvm.org/viewvc/llvm-project?rev=90761&view=rev Log: Refreshed this patch. Modified: dragonegg/trunk/gcc-patches/i386_static.diff Modified: dragonegg/trunk/gcc-patches/i386_static.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/i386_static.diff?rev=90761&r1=90760&r2=90761&view=diff ============================================================================== --- dragonegg/trunk/gcc-patches/i386_static.diff (original) +++ dragonegg/trunk/gcc-patches/i386_static.diff Mon Dec 7 04:39:55 2009 @@ -1,8 +1,8 @@ Index: mainline/gcc/config/i386/i386.c =================================================================== ---- mainline.orig/gcc/config/i386/i386.c 2009-11-02 17:21:03.257325701 +0100 -+++ mainline/gcc/config/i386/i386.c 2009-11-03 13:26:05.384538824 +0100 -@@ -4943,7 +4943,8 @@ +--- mainline.orig/gcc/config/i386/i386.c 2009-12-05 13:39:54.356912538 +0100 ++++ mainline/gcc/config/i386/i386.c 2009-12-05 13:44:12.786890585 +0100 +@@ -4988,7 +4988,8 @@ case, we return the original mode and warn ABI change if CUM isn't NULL. */ @@ -12,7 +12,7 @@ type_natural_mode (const_tree type, CUMULATIVE_ARGS *cum) { enum machine_mode mode = TYPE_MODE (type); -@@ -5074,7 +5075,9 @@ +@@ -5119,7 +5120,9 @@ See the x86-64 PS ABI for details. */ @@ -23,7 +23,7 @@ classify_argument (enum machine_mode mode, const_tree type, enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset) { -@@ -5454,7 +5457,9 @@ +@@ -5499,7 +5502,9 @@ /* Examine the argument and return set number of register required in each class. Return 0 iff parameter should be passed in memory. */ @@ -34,7 +34,7 @@ examine_argument (enum machine_mode mode, const_tree type, int in_return, int *int_nregs, int *sse_nregs) { -@@ -6134,7 +6139,8 @@ +@@ -6179,7 +6184,8 @@ /* Return true when TYPE should be 128bit aligned for 32bit argument passing ABI. */ From baldrick at free.fr Mon Dec 7 04:40:28 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 10:40:28 -0000 Subject: [llvm-commits] [dragonegg] r90762 - /dragonegg/trunk/gcc-patches/lto_flags.diff Message-ID: <200912071040.nB7AeS3a030189@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 04:40:28 2009 New Revision: 90762 URL: http://llvm.org/viewvc/llvm-project?rev=90762&view=rev Log: A pending GCC patch that simplifies handling of LTO flags. Added: dragonegg/trunk/gcc-patches/lto_flags.diff Added: dragonegg/trunk/gcc-patches/lto_flags.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/lto_flags.diff?rev=90762&view=auto ============================================================================== --- dragonegg/trunk/gcc-patches/lto_flags.diff (added) +++ dragonegg/trunk/gcc-patches/lto_flags.diff Mon Dec 7 04:40:28 2009 @@ -0,0 +1,75 @@ +Index: mainline/gcc/cgraphunit.c +=================================================================== +--- mainline.orig/gcc/cgraphunit.c 2009-12-05 13:39:51.034414478 +0100 ++++ mainline/gcc/cgraphunit.c 2009-12-05 13:44:22.576904063 +0100 +@@ -358,8 +358,7 @@ + && !DECL_DECLARED_INLINE_P (decl) + && !node->origin)) + && !flag_whole_program +- && !flag_lto +- && !flag_whopr) ++ && !flag_generate_lto) + && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) + return true; + +Index: mainline/gcc/ipa-cp.c +=================================================================== +--- mainline.orig/gcc/ipa-cp.c 2009-12-05 13:39:51.074413887 +0100 ++++ mainline/gcc/ipa-cp.c 2009-12-05 13:44:22.576904063 +0100 +@@ -628,7 +628,7 @@ + { + /* We do not need to bother analyzing calls to unknown + functions unless they may become known during lto/whopr. */ +- if (!cs->callee->analyzed && !flag_lto && !flag_whopr) ++ if (!cs->callee->analyzed && !flag_generate_lto) + continue; + ipa_count_arguments (cs); + if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) +Index: mainline/gcc/ipa.c +=================================================================== +--- mainline.orig/gcc/ipa.c 2009-12-05 13:39:51.094413696 +0100 ++++ mainline/gcc/ipa.c 2009-12-05 13:44:22.576904063 +0100 +@@ -27,6 +27,7 @@ + #include "timevar.h" + #include "gimple.h" + #include "ggc.h" ++#include "flags.h" + + /* Fill array order with all nodes with output flag set in the reverse + topological order. */ +@@ -401,7 +402,7 @@ + static unsigned int + local_function_and_variable_visibility (void) + { +- return function_and_variable_visibility (flag_whole_program && !flag_lto && !flag_whopr); ++ return function_and_variable_visibility (flag_whole_program && !flag_generate_lto); + } + + struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility = +Index: mainline/gcc/varpool.c +=================================================================== +--- mainline.orig/gcc/varpool.c 2009-12-05 13:39:51.044386864 +0100 ++++ mainline/gcc/varpool.c 2009-12-05 13:44:22.576904063 +0100 +@@ -244,8 +244,7 @@ + COMDAT variables that must be output only when they are needed. */ + if (TREE_PUBLIC (decl) + && !flag_whole_program +- && !flag_lto +- && !flag_whopr ++ && !flag_generate_lto + && !DECL_COMDAT (decl) + && !DECL_EXTERNAL (decl)) + return true; +Index: mainline/gcc/fortran/options.c +=================================================================== +--- mainline.orig/gcc/fortran/options.c 2009-12-05 13:39:51.064386464 +0100 ++++ mainline/gcc/fortran/options.c 2009-12-05 13:44:22.576904063 +0100 +@@ -243,7 +243,7 @@ + gfc_option.flag_whole_file = 1; + + /* Enable whole-file mode if LTO is in effect. */ +- if (flag_lto || flag_whopr) ++ if (flag_generate_lto) + gfc_option.flag_whole_file = 1; + + /* -fbounds-check is equivalent to -fcheck=bounds */ From baldrick at free.fr Mon Dec 7 04:42:53 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 10:42:53 -0000 Subject: [llvm-commits] [dragonegg] r90763 - in /dragonegg/trunk: README llvm-backend.cpp Message-ID: <200912071042.nB7AgrJH030271@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 04:42:53 2009 New Revision: 90763 URL: http://llvm.org/viewvc/llvm-project?rev=90763&view=rev Log: Pretend to be GCC's LTO pass, and convert gimple to IR in much the same way that LTO converts gimple to it's ELF format. Doing it at this level rather than later at the RTL level means that we get to see aliases and thunks. Modified: dragonegg/trunk/README dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/README URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/README?rev=90763&r1=90762&r2=90763&view=diff ============================================================================== --- dragonegg/trunk/README (original) +++ dragonegg/trunk/README Mon Dec 7 04:42:53 2009 @@ -74,9 +74,6 @@ -fno-ident If the ident global asm in the LLVM IR annoys you, use this to turn it off. --fdump-rtl-all - In the dump file, each function is output both as gimple and as LLVM IR. - -fplugin-arg-dragonegg-disable-llvm-optzns Do not perform any LLVM IR optimizations even if compiling at -O1, -O2 etc. Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90763&r1=90762&r2=90763&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Mon Dec 7 04:42:53 2009 @@ -832,59 +832,10 @@ } /// emit_alias_to_llvm - Given decl and target emit alias to target. -void emit_alias_to_llvm(tree decl, tree target, tree target_decl) { - if (errorcount || sorrycount) { - TREE_ASM_WRITTEN(decl) = 1; - return; // Do not process broken code. - } - -//TODO timevar_push(TV_LLVM_GLOBALS); - +void emit_alias_to_llvm(tree decl, tree target) { // Get or create LLVM global for our alias. GlobalValue *V = cast(DECL_LLVM(decl)); - - GlobalValue *Aliasee = NULL; - - if (target_decl) - Aliasee = cast(DECL_LLVM(target_decl)); - else { - // This is something insane. Probably only LTHUNKs can be here - // Try to grab decl from IDENTIFIER_NODE - - // Query SymTab for aliasee - const char* AliaseeName = IDENTIFIER_POINTER(target); - Aliasee = - dyn_cast_or_null(TheModule-> - getValueSymbolTable().lookup(AliaseeName)); - - // Last resort. Query for name set via __asm__ - if (!Aliasee) { - std::string starred = std::string("\001") + AliaseeName; - Aliasee = - dyn_cast_or_null(TheModule-> - getValueSymbolTable().lookup(starred)); - } - - if (!Aliasee) { - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { - if (GlobalVariable *GV = dyn_cast(V)) - Aliasee = new GlobalVariable(*TheModule, GV->getType(), - GV->isConstant(), - GlobalVariable::ExternalWeakLinkage, - NULL, AliaseeName); - else if (Function *F = dyn_cast(V)) - Aliasee = Function::Create(F->getFunctionType(), - Function::ExternalWeakLinkage, - AliaseeName, TheModule); - else - assert(0 && "Unsuported global value"); - } else { - error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); -//TODO timevar_pop(TV_LLVM_GLOBALS); - return; - } - } - } + GlobalValue *Aliasee = cast(DECL_LLVM(target)); GlobalValue::LinkageTypes Linkage; @@ -910,10 +861,9 @@ V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType())); else if (!V->use_empty()) { error ("%J Alias %qD used with invalid type!", decl, decl); -//TODO timevar_pop(TV_LLVM_GLOBALS); return; } - + changeLLVMConstant(V, GA); GA->takeName(V); if (GlobalVariable *GV = dyn_cast(V)) @@ -925,9 +875,9 @@ else assert(0 && "Unsuported global value"); + // Mark the alias as written so gcc doesn't waste time outputting it. TREE_ASM_WRITTEN(decl) = 1; - -//TODO timevar_pop(TV_LLVM_GLOBALS); + return; } @@ -1079,11 +1029,6 @@ /// LLVM as a global variable. This function implements the end of /// assemble_variable. void emit_global_to_llvm(tree decl) { - if (errorcount || sorrycount) { - TREE_ASM_WRITTEN(decl) = 1; - return; // Do not process broken code. - } - // FIXME: Support alignment on globals: DECL_ALIGN. // FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'. @@ -1257,7 +1202,9 @@ if (TheDebugInfo) TheDebugInfo->EmitGlobalVariable(GV, decl); + // Mark the global as written so gcc doesn't waste time outputting it. TREE_ASM_WRITTEN(decl) = 1; + //TODO timevar_pop(TV_LLVM_GLOBALS); } @@ -1679,7 +1626,10 @@ #ifdef ENABLE_LTO // Output LLVM IR if the user requested generation of lto data. EmitIR |= flag_generate_lto != 0; - flag_generate_lto = 0; + // We have the same needs as GCC's LTO. Always claim to be doing LTO. + flag_generate_lto = 1; +#else + error ("GCC LTO support required but not enabled"); #endif } @@ -1690,35 +1640,123 @@ return !errorcount && !sorrycount; } +/// emit_function - Turn a gimple function into LLVM IR. This is called once +/// for each function in the compilation unit. +static void emit_function(struct cgraph_node *node) { + tree function = node->decl; + struct function *fn = DECL_STRUCT_FUNCTION(function); + if (!quiet_flag && DECL_NAME(function)) + errs() << IDENTIFIER_POINTER(DECL_NAME(function)); + + // Set the current function to this one. + // TODO: Make it so we don't need to do this. + assert(current_function_decl == NULL_TREE && cfun == NULL && + "Current function already set!"); + current_function_decl = function; + push_cfun (fn); + + // Convert the AST to raw/ugly LLVM code. + Function *Fn; + { + TreeToLLVM Emitter(current_function_decl); + Fn = Emitter.EmitFunction(); + } + + // TODO performLateBackendInitialization(); + createPerFunctionOptimizationPasses(); + + if (PerFunctionPasses) + PerFunctionPasses->run(*Fn); + + // TODO: Nuke the .ll code for the function at -O[01] if we don't want to + // inline it or something else. + + // Done with this function. + current_function_decl = NULL; + pop_cfun (); +} + +/// emit_same_body_alias - Turn a same-body alias or thunk into LLVM IR. Here +/// alias is a function which has the some body as node. +static void emit_same_body_alias(struct cgraph_node *alias, + struct cgraph_node *node) { + // TODO: The cgraph node contains all kinds of interesting information about + // linkage and visibility - should maybe make use of it? + emit_alias_to_llvm(alias->decl, node->decl); +} + +/// emit_functions - Turn all functions in the compilation unit into LLVM IR. +static void emit_functions(cgraph_node_set set) { + LazilyInitializeModule(); + + // Visit each function with a body, outputting it only once (the same function + // can appear in multiple cgraph nodes due to cloning). + SmallPtrSet Visited; + for (cgraph_node_set_iterator csi = csi_start(set); !csi_end_p(csi); + csi_next(&csi)) { + struct cgraph_node *node = csi_node(csi); + if (node->analyzed && Visited.insert(node->decl)) + emit_function(node); + // Output any same-body aliases or thunks. + for (struct cgraph_node *alias = node->same_body; alias; + alias = alias->next) + emit_same_body_alias(alias, node); + } +} + +/// pass_emit_functions - IPA pass that turns gimple functions into LLVM IR. +static struct ipa_opt_pass_d pass_emit_functions = { + { + IPA_PASS, + "emit_functions", /* name */ + gate_emission, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + }, + NULL, /* generate_summary */ + emit_functions, /* write_summary */ + NULL, /* read_summary */ + NULL, /* function_read_summary */ + NULL, /* TODOs */ + NULL, /* function_transform */ + NULL /* variable_transform */ +}; /// emit_variables - Output GCC global variables to the LLVM IR. -static unsigned int emit_variables(void) { +static void emit_variables(cgraph_node_set set) { LazilyInitializeModule(); // Output all externally visible global variables, whether they are used in // this compilation unit or not. Global variables that are not externally - // visible will be output when their user is, or discarded if unused. + // visible are output when their user is, or discarded if unused. struct varpool_node *vnode; FOR_EACH_STATIC_VARIABLE (vnode) { - if (TREE_PUBLIC(vnode->decl)) - // An externally visible global variable - output it. - emit_global_to_llvm(vnode->decl); - - // Mark all variables as written so gcc doesn't waste time outputting them. - TREE_ASM_WRITTEN(vnode->decl) = 1; + tree var = vnode->decl; + if (TREE_CODE(var) == VAR_DECL && TREE_PUBLIC(var)) + emit_global_to_llvm(var); } - return 0; + // Emit any aliases. + alias_pair *p; + for (unsigned i = 0; VEC_iterate(alias_pair, alias_pairs, i, p); i++) + emit_alias_to_llvm(p->decl, p->target); } /// pass_emit_variables - IPA pass that turns GCC variables into LLVM IR. -static struct simple_ipa_opt_pass pass_emit_variables = -{ +static struct ipa_opt_pass_d pass_emit_variables = { { - SIMPLE_IPA_PASS, + IPA_PASS, "emit_variables", /* name */ gate_emission, /* gate */ - emit_variables, /* execute */ + NULL, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ @@ -1726,83 +1764,48 @@ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ - 0, /* todo_flags_start */ + 0, /* todo_flags_start */ 0 /* todo_flags_finish */ - } + }, + NULL, /* generate_summary */ + emit_variables, /* write_summary */ + NULL, /* read_summary */ + NULL, /* variable_read_summary */ + NULL, /* TODOs */ + NULL, /* variable_transform */ + NULL /* variable_transform */ }; - -/// emit_function - Turn a gimple function into LLVM IR. This is called by -/// GCC once for each function in the compilation unit. -static unsigned int emit_function (void) { - LazilyInitializeModule(); - -//TODO Don't want to use sorry at this stage... -//TODO if (cfun->nonlocal_goto_save_area) -//TODO sorry("%Jnon-local gotos not supported by LLVM", fndecl); - -//TODO Do we want to do this? Will the warning set sorry_count etc? -//TODO enum symbol_visibility vis = DECL_VISIBILITY (current_function_decl); -//TODO -//TODO if (vis != VISIBILITY_DEFAULT) -//TODO // "asm_out.visibility" emits an important warning if we're using a -//TODO // visibility that's not supported by the target. -//TODO targetm.asm_out.visibility(current_function_decl, vis); - - // There's no need to defer outputting this function any more; we - // know we want to output it. - DECL_DEFER_OUTPUT(current_function_decl) = 0; - - // Convert the AST to raw/ugly LLVM code. - Function *Fn; - { - TreeToLLVM Emitter(current_function_decl); - Fn = Emitter.EmitFunction(); - } - +/// disable_rtl - Mark the current function as having been written to assembly. +static unsigned int disable_rtl(void) { // Free any data structures. execute_free_datastructures(); -//TODO performLateBackendInitialization(); - createPerFunctionOptimizationPasses(); - - if (PerFunctionPasses) - PerFunctionPasses->run(*Fn); - - // TODO: Nuke the .ll code for the function at -O[01] if we don't want to - // inline it or something else. - - // Finally, we have written out this function! + // Mark the function as written. TREE_ASM_WRITTEN(current_function_decl) = 1; - // When debugging, append the LLVM IR to the dump file. - if (dump_file) { - raw_fd_ostream dump_stream(fileno(dump_file), false); - Fn->print(dump_stream); - } - + // That's all folks! return 0; } -/// pass_emit_functions - RTL pass that turns gimple functions into LLVM IR. -static struct rtl_opt_pass pass_emit_functions = +/// pass_disable_rtl - RTL pass that pretends to codegen functions, but actually +/// only does hoop jumping required by GCC. +static struct rtl_opt_pass pass_disable_rtl = { { RTL_PASS, - "emit_functions", /* name */ - gate_emission, /* gate */ - emit_function, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - PROP_ssa | PROP_gimple_leh - | PROP_gimple_lomp | PROP_cfg, /* properties_required */ - 0, /* properties_provided */ - PROP_ssa | PROP_trees, /* properties_destroyed */ - TODO_dump_func | TODO_verify_ssa - | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ - TODO_ggc_collect /* todo_flags_finish */ + "disable_rtl", /* name */ + NULL, /* gate */ + disable_rtl, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + PROP_ssa | PROP_trees, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ } }; @@ -1997,7 +2000,7 @@ NULL, /* write_summary */ NULL, /* read_summary */ NULL, /* function_read_summary */ - 0, /* TODOs */ + NULL, /* TODOs */ NULL, /* function_transform */ NULL /* variable_transform */ }; @@ -2037,7 +2040,7 @@ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ - 0, /* todo_flags_start */ + 0, /* todo_flags_start */ 0 /* todo_flags_finish */ } }; @@ -2143,14 +2146,6 @@ // Perform late initialization just before processing the compilation unit. register_callback (plugin_name, PLUGIN_START_UNIT, llvm_start_unit, NULL); - // Add an ipa pass that emits global variables, calling emit_global_to_llvm - // for each GCC static variable. - pass_info.pass = &pass_emit_variables.pass; - pass_info.reference_pass_name = "ipa_struct_reorg"; - pass_info.ref_pass_instance_number = 0; - pass_info.pos_op = PASS_POS_INSERT_AFTER; - register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); - // Turn off all gcc optimization passes. if (!EnableGCCOptimizations) { // TODO: figure out a good way of turning off ipa optimization passes. @@ -2242,9 +2237,29 @@ register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); } - // Replace rtl expansion with gimple to LLVM conversion. This results in each - // GCC function in the compilation unit being passed to emit_function. + // Replace LTO generation with gimple to LLVM conversion. pass_info.pass = &pass_emit_functions.pass; + pass_info.reference_pass_name = "lto_gimple_out"; + pass_info.ref_pass_instance_number = 0; + pass_info.pos_op = PASS_POS_REPLACE; + register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); + + pass_info.pass = &pass_emit_variables.pass; + pass_info.reference_pass_name = "lto_decls_out"; + pass_info.ref_pass_instance_number = 0; + pass_info.pos_op = PASS_POS_REPLACE; + register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); + + // Turn off all LTO passes. + pass_info.pass = &pass_ipa_null.pass; + pass_info.reference_pass_name = "lto_wpa_fixup"; + pass_info.ref_pass_instance_number = 0; + pass_info.pos_op = PASS_POS_REPLACE; + register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info); + + // Replace rtl expansion with a pass that pretends to codegen functions, but + // actually only does the hoop jumping that GCC requires at this point. + pass_info.pass = &pass_disable_rtl.pass; pass_info.reference_pass_name = "expand"; pass_info.ref_pass_instance_number = 0; pass_info.pos_op = PASS_POS_REPLACE; From foldr at codedgers.com Mon Dec 7 04:51:55 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 10:51:55 -0000 Subject: [llvm-commits] [llvm] r90764 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200912071051.nB7Aptil030547@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 04:51:55 2009 New Revision: 90764 URL: http://llvm.org/viewvc/llvm-project?rev=90764&view=rev Log: Refactoring, no functionality change. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=90764&r1=90763&r2=90764&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Dec 7 04:51:55 2009 @@ -456,54 +456,64 @@ /// HandlerTable - A base class for function objects implemented as /// 'tables of handlers'. -template +template class HandlerTable { protected: // Implementation details. - /// Handler - - typedef void (T::* Handler) (const DagInit*); /// HandlerMap - A map from property names to property handlers typedef StringMap HandlerMap; static HandlerMap Handlers_; static bool staticMembersInitialized_; - T* childPtr; public: - HandlerTable(T* cp) : childPtr(cp) - {} - - /// operator() - Just forwards to the corresponding property - /// handler. - void operator() (Init* i) { - const DagInit& property = InitPtrToDag(i); - const std::string& property_name = GetOperatorName(property); - typename HandlerMap::iterator method = Handlers_.find(property_name); + Handler GetHandler (const std::string& HandlerName) const { + typename HandlerMap::iterator method = Handlers_.find(HandlerName); if (method != Handlers_.end()) { Handler h = method->second; - (childPtr->*h)(&property); + return h; } else { - throw "No handler found for property " + property_name + "!"; + throw "No handler found for property " + HandlerName + "!"; } } - void AddHandler(const char* Property, Handler Handl) { - Handlers_[Property] = Handl; + void AddHandler(const char* Property, Handler H) { + Handlers_[Property] = H; } + }; -template typename HandlerTable::HandlerMap -HandlerTable::Handlers_; -template bool HandlerTable::staticMembersInitialized_ = false; +template +void InvokeDagInitHandler(FunctionObject* Obj, Init* i) { + typedef void (FunctionObject::*Handler) (const DagInit*); + + const DagInit& property = InitPtrToDag(i); + const std::string& property_name = GetOperatorName(property); + Handler h = Obj->GetHandler(property_name); + + ((Obj)->*(h))(&property); +} + +template +typename HandlerTable::HandlerMap HandlerTable::Handlers_; + +template +bool HandlerTable::staticMembersInitialized_ = false; /// CollectOptionProperties - Function object for iterating over an /// option property list. -class CollectOptionProperties : public HandlerTable { +class CollectOptionProperties; +typedef void (CollectOptionProperties::* CollectOptionPropertiesHandler) +(const DagInit*); + +class CollectOptionProperties +: public HandlerTable +{ private: /// optDescs_ - OptionDescriptions table. This is where the @@ -513,7 +523,7 @@ public: explicit CollectOptionProperties(OptionDescription& OD) - : HandlerTable(this), optDesc_(OD) + : optDesc_(OD) { if (!staticMembersInitialized_) { AddHandler("extern", &CollectOptionProperties::onExtern); @@ -530,6 +540,12 @@ } } + /// operator() - Just forwards to the corresponding property + /// handler. + void operator() (Init* i) { + InvokeDagInitHandler(this, i); + } + private: /// Option property handlers -- @@ -712,7 +728,13 @@ /// CollectToolProperties - Function object for iterating over a list of /// tool property records. -class CollectToolProperties : public HandlerTable { + +class CollectToolProperties; +typedef void (CollectToolProperties::* CollectToolPropertiesHandler) +(const DagInit*); + +class CollectToolProperties : public HandlerTable +{ private: /// toolDesc_ - Properties of the current Tool. This is where the @@ -722,7 +744,7 @@ public: explicit CollectToolProperties (ToolDescription& d) - : HandlerTable(this) , toolDesc_(d) + : toolDesc_(d) { if (!staticMembersInitialized_) { @@ -738,6 +760,10 @@ } } + void operator() (Init* i) { + InvokeDagInitHandler(this, i); + } + private: /// Property handlers -- @@ -1727,90 +1753,122 @@ /// EmitActionHandlersCallback - Emit code that handles actions. Used by /// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler(). -class EmitActionHandlersCallback : ActionHandlingCallbackBase { +class EmitActionHandlersCallback; +typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler) +(const DagInit&, unsigned, raw_ostream&) const; + +class EmitActionHandlersCallback +: public ActionHandlingCallbackBase, + public HandlerTable +{ const OptionDescriptions& OptDescs; + typedef EmitActionHandlersCallbackHandler Handler; - void processActionDag(const Init* Statement, unsigned IndentLevel, - raw_ostream& O) const + void onAppendCmd (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const { - const DagInit& Dag = InitPtrToDag(Statement); - const std::string& ActionName = GetOperatorName(Dag); + checkNumberOfArguments(&Dag, 1); + const std::string& Cmd = InitPtrToString(Dag.getArg(0)); + StrVector Out; + llvm::SplitString(Cmd, Out); - if (ActionName == "append_cmd") { - checkNumberOfArguments(&Dag, 1); - const std::string& Cmd = InitPtrToString(Dag.getArg(0)); - StrVector Out; - llvm::SplitString(Cmd, Out); + for (StrVector::const_iterator B = Out.begin(), E = Out.end(); + B != E; ++B) + O.indent(IndentLevel) << "vec.push_back(\"" << *B << "\");\n"; + } - for (StrVector::const_iterator B = Out.begin(), E = Out.end(); - B != E; ++B) - O.indent(IndentLevel) << "vec.push_back(\"" << *B << "\");\n"; - } - else if (ActionName == "error") { - this->onErrorDag(Dag, IndentLevel, O); - } - else if (ActionName == "warning") { - this->onWarningDag(Dag, IndentLevel, O); - } - else if (ActionName == "forward") { - checkNumberOfArguments(&Dag, 1); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), - IndentLevel, "", O); - } - else if (ActionName == "forward_as") { - checkNumberOfArguments(&Dag, 2); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const std::string& NewName = InitPtrToString(Dag.getArg(1)); - EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), - IndentLevel, NewName, O); - } - else if (ActionName == "output_suffix") { - checkNumberOfArguments(&Dag, 1); - const std::string& OutSuf = InitPtrToString(Dag.getArg(0)); - O.indent(IndentLevel) << "output_suffix = \"" << OutSuf << "\";\n"; - } - else if (ActionName == "stop_compilation") { - O.indent(IndentLevel) << "stop_compilation = true;\n"; - } - else if (ActionName == "unpack_values") { - checkNumberOfArguments(&Dag, 1); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const OptionDescription& D = OptDescs.FindOption(Name); - - if (D.isMultiVal()) - throw std::string("Can't use unpack_values with multi-valued options!"); - - if (D.isList()) { - O.indent(IndentLevel) - << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n"; - O.indent(IndentLevel) - << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"; - O.indent(IndentLevel + Indent1) - << "llvm::SplitString(*B, vec, \",\");\n"; - } - else if (D.isParameter()){ - O.indent(IndentLevel) << "llvm::SplitString(" - << D.GenVariableName() << ", vec, \",\");\n"; - } - else { - throw "Option '" + D.Name + - "': switches can't have the 'unpack_values' property!"; - } + void onForward (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 1); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), + IndentLevel, "", O); + } + + void onForwardAs (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 2); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const std::string& NewName = InitPtrToString(Dag.getArg(1)); + EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), + IndentLevel, NewName, O); + } + + void onOutputSuffix (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 1); + const std::string& OutSuf = InitPtrToString(Dag.getArg(0)); + O.indent(IndentLevel) << "output_suffix = \"" << OutSuf << "\";\n"; + } + + void onStopCompilation (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + O.indent(IndentLevel) << "stop_compilation = true;\n"; + } + + + void onUnpackValues (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 1); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const OptionDescription& D = OptDescs.FindOption(Name); + + if (D.isMultiVal()) + throw std::string("Can't use unpack_values with multi-valued options!"); + + if (D.isList()) { + O.indent(IndentLevel) + << "for (" << D.GenTypeDeclaration() + << "::iterator B = " << D.GenVariableName() << ".begin(),\n"; + O.indent(IndentLevel) + << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"; + O.indent(IndentLevel + Indent1) + << "llvm::SplitString(*B, vec, \",\");\n"; + } + else if (D.isParameter()){ + O.indent(IndentLevel) << "llvm::SplitString(" + << D.GenVariableName() << ", vec, \",\");\n"; } else { - throw "Unknown action name: " + ActionName + "!"; + throw "Option '" + D.Name + + "': switches can't have the 'unpack_values' property!"; } } + public: - EmitActionHandlersCallback(const OptionDescriptions& OD) - : OptDescs(OD) {} + + explicit EmitActionHandlersCallback(const OptionDescriptions& OD) + : OptDescs(OD) + { + if (!staticMembersInitialized_) { + AddHandler("error", &EmitActionHandlersCallback::onErrorDag); + AddHandler("warning", &EmitActionHandlersCallback::onWarningDag); + AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd); + AddHandler("forward", &EmitActionHandlersCallback::onForward); + AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs); + AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix); + AddHandler("stop_compilation", + &EmitActionHandlersCallback::onStopCompilation); + AddHandler("unpack_values", + &EmitActionHandlersCallback::onUnpackValues); + + staticMembersInitialized_ = true; + } + } void operator()(const Init* Statement, unsigned IndentLevel, raw_ostream& O) const { - this->processActionDag(Statement, IndentLevel, O); + const DagInit& Dag = InitPtrToDag(Statement); + const std::string& ActionName = GetOperatorName(Dag); + Handler h = GetHandler(ActionName); + + ((this)->*(h))(Dag, IndentLevel, O); } }; @@ -1866,11 +1924,9 @@ return IsOutFileIndexCheckRequiredCase(CmdLine); } -// EmitGenerateActionMethod - Emit either a normal or a "join" version of the -// Tool::GenerateAction() method. -void EmitGenerateActionMethod (const ToolDescription& D, - const OptionDescriptions& OptDescs, - bool IsJoin, raw_ostream& O) { +void EmitGenerateActionMethodHeader(const ToolDescription& D, + bool IsJoin, raw_ostream& O) +{ if (IsJoin) O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n"; else @@ -1886,6 +1942,15 @@ O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n"; O.indent(Indent2) << "const char* output_suffix = \"" << D.OutputSuffix << "\";\n"; +} + +// EmitGenerateActionMethod - Emit either a normal or a "join" version of the +// Tool::GenerateAction() method. +void EmitGenerateActionMethod (const ToolDescription& D, + const OptionDescriptions& OptDescs, + bool IsJoin, raw_ostream& O) { + + EmitGenerateActionMethodHeader(D, IsJoin, O); if (!D.CmdLine) throw "Tool " + D.Name + " has no cmd_line property!"; From baldrick at free.fr Mon Dec 7 04:57:37 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 10:57:37 -0000 Subject: [llvm-commits] [dragonegg] r90765 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912071057.nB7Avb6P030750@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 04:57:37 2009 New Revision: 90765 URL: http://llvm.org/viewvc/llvm-project?rev=90765&view=rev Log: The ipa_opt_pass_d struct got an additional member. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90765&r1=90764&r2=90765&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Mon Dec 7 04:57:37 2009 @@ -1725,7 +1725,8 @@ emit_functions, /* write_summary */ NULL, /* read_summary */ NULL, /* function_read_summary */ - NULL, /* TODOs */ + NULL, /* stmt_fixup */ + 0, /* TODOs */ NULL, /* function_transform */ NULL /* variable_transform */ }; @@ -2000,7 +2001,8 @@ NULL, /* write_summary */ NULL, /* read_summary */ NULL, /* function_read_summary */ - NULL, /* TODOs */ + NULL, /* stmt_fixup */ + 0, /* TODOs */ NULL, /* function_transform */ NULL /* variable_transform */ }; From baldrick at free.fr Mon Dec 7 07:01:47 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 13:01:47 -0000 Subject: [llvm-commits] [dragonegg] r90766 - /dragonegg/trunk/gcc-patches/alloc.diff Message-ID: <200912071301.nB7D1lkv002386@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 07:01:46 2009 New Revision: 90766 URL: http://llvm.org/viewvc/llvm-project?rev=90766&view=rev Log: GCC does not allocate enough memory for IPA passes in this context. Added: dragonegg/trunk/gcc-patches/alloc.diff Added: dragonegg/trunk/gcc-patches/alloc.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/alloc.diff?rev=90766&view=auto ============================================================================== --- dragonegg/trunk/gcc-patches/alloc.diff (added) +++ dragonegg/trunk/gcc-patches/alloc.diff Mon Dec 7 07:01:46 2009 @@ -0,0 +1,27 @@ +Index: mainline/gcc/passes.c +=================================================================== +--- mainline.orig/gcc/passes.c 2009-12-07 11:58:18.483151321 +0100 ++++ mainline/gcc/passes.c 2009-12-07 12:10:09.040652447 +0100 +@@ -459,9 +459,20 @@ + if (pass->static_pass_number) + { + struct opt_pass *new_pass; ++ size_t pass_size; + +- new_pass = XNEW (struct opt_pass); +- memcpy (new_pass, pass, sizeof (*new_pass)); ++ if (pass->type != IPA_PASS) ++ { ++ new_pass = XNEW (struct opt_pass); ++ pass_size = sizeof(struct opt_pass); ++ } ++ else ++ { ++ new_pass = (struct opt_pass *)XNEW (struct ipa_opt_pass_d); ++ pass_size = sizeof(struct ipa_opt_pass_d); ++ } ++ ++ memcpy (new_pass, pass, pass_size); + new_pass->next = NULL; + + new_pass->todo_flags_start &= ~TODO_mark_first_instance; From baldrick at free.fr Mon Dec 7 07:11:56 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 13:11:56 -0000 Subject: [llvm-commits] [dragonegg] r90767 - /dragonegg/trunk/llvm-convert.cpp Message-ID: <200912071311.nB7DBufJ002764@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 07:11:56 2009 New Revision: 90767 URL: http://llvm.org/viewvc/llvm-project?rev=90767&view=rev Log: Ignore GIMPLE_EH_DISPATCH for the moment (these eh constructs turn up now because we are lowering to LLVM IR much earlier - previously they had already been lowered by GCC). Modified: dragonegg/trunk/llvm-convert.cpp Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=90767&r1=90766&r2=90767&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Mon Dec 7 07:11:56 2009 @@ -1119,6 +1119,10 @@ // TODO: Output debug info rather than just discarding it. break; + case GIMPLE_EH_DISPATCH: + // TODO: Implement this. + break; + case GIMPLE_GOTO: RenderGIMPLE_GOTO(stmt); break; From baldrick at free.fr Mon Dec 7 07:13:42 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 13:13:42 -0000 Subject: [llvm-commits] [dragonegg] r90768 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912071313.nB7DDgRX002832@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 07:13:42 2009 New Revision: 90768 URL: http://llvm.org/viewvc/llvm-project?rev=90768&view=rev Log: It turns out that in gcc-4.5 the alias target can be a simple symbol name, like in earlier GCC's. Restore the code from llvm-gcc that handles this. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90768&r1=90767&r2=90768&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Mon Dec 7 07:13:42 2009 @@ -835,7 +835,48 @@ void emit_alias_to_llvm(tree decl, tree target) { // Get or create LLVM global for our alias. GlobalValue *V = cast(DECL_LLVM(decl)); - GlobalValue *Aliasee = cast(DECL_LLVM(target)); + + GlobalValue *Aliasee; + + if (TREE_CODE(target) == IDENTIFIER_NODE) { + // This is something insane. Probably only LTHUNKs can be here + // Try to grab decl from IDENTIFIER_NODE + + // Query SymTab for aliasee + const char* AliaseeName = IDENTIFIER_POINTER(target); + Aliasee = + dyn_cast_or_null(TheModule-> + getValueSymbolTable().lookup(AliaseeName)); + + // Last resort. Query for name set via __asm__ + if (!Aliasee) { + std::string starred = std::string("\001") + AliaseeName; + Aliasee = + dyn_cast_or_null(TheModule-> + getValueSymbolTable().lookup(starred)); + } + + if (!Aliasee) { + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { + if (GlobalVariable *GV = dyn_cast(V)) + Aliasee = new GlobalVariable(*TheModule, GV->getType(), + GV->isConstant(), + GlobalVariable::ExternalWeakLinkage, + NULL, AliaseeName); + else if (Function *F = dyn_cast(V)) + Aliasee = Function::Create(F->getFunctionType(), + Function::ExternalWeakLinkage, + AliaseeName, TheModule); + else + assert(0 && "Unsuported global value"); + } else { + error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); + return; + } + } + } else { + Aliasee = cast(DECL_LLVM(target)); + } GlobalValue::LinkageTypes Linkage; From clattner at apple.com Mon Dec 7 10:27:03 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 7 Dec 2009 08:27:03 -0800 Subject: [llvm-commits] [llvm] r90759 - in /llvm/trunk: include/llvm/CodeGen/MachineSSAUpdater.h lib/CodeGen/MachineSSAUpdater.cpp lib/CodeGen/TailDuplication.cpp In-Reply-To: <200912071015.nB7AFKWn029279@zion.cs.uiuc.edu> References: <200912071015.nB7AFKWn029279@zion.cs.uiuc.edu> Message-ID: On Dec 7, 2009, at 2:15 AM, Evan Cheng wrote: > Author: evancheng > Date: Mon Dec 7 04:15:19 2009 > New Revision: 90759 > > URL: http://llvm.org/viewvc/llvm-project?rev=90759&view=rev > Log: > Pre-regalloc tale duplication. Work in progress. Hey Evan, > @@ -207,6 +207,16 @@ > > +void MachineSSAUpdater::ReplaceRegWith(unsigned OldReg, unsigned NewReg) { > + MRI->replaceRegWith(OldReg, NewReg); > + > + AvailableValsTy &AvailableVals = getAvailableVals(AV); > + for (DenseMap::iterator > + I = AvailableVals.begin(), E = AvailableVals.end(); I != E; ++I) > + if (I->second == OldReg) > + I->second = NewReg; > +} This scan can be *really* expensive: O(size of function). Would it be better to insert copies and then zap the copies at the end? -Chris From foldr at codedgers.com Mon Dec 7 11:03:05 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 17:03:05 -0000 Subject: [llvm-commits] [llvm] r90770 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td test/LLVMC/ForwardTransformedValue.td test/LLVMC/ForwardValue.td utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200912071703.nB7H35Ts011181@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 11:03:05 2009 New Revision: 90770 URL: http://llvm.org/viewvc/llvm-project?rev=90770&view=rev Log: Implement 'forward_value' and 'forward_transformed_value'. Added: llvm/trunk/test/LLVMC/ForwardTransformedValue.td llvm/trunk/test/LLVMC/ForwardValue.td Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=90770&r1=90769&r2=90770&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Mon Dec 7 11:03:05 2009 @@ -77,6 +77,8 @@ def append_cmd; def forward; def forward_as; +def forward_value; +def forward_transformed_value; def stop_compilation; def unpack_values; def warning; Added: llvm/trunk/test/LLVMC/ForwardTransformedValue.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ForwardTransformedValue.td?rev=90770&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/ForwardTransformedValue.td (added) +++ llvm/trunk/test/LLVMC/ForwardTransformedValue.td Mon Dec 7 11:03:05 2009 @@ -0,0 +1,21 @@ +// Check that forward_transformed_value works. +// The dummy tool and graph are required to silence warnings. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: grep HookA %t +// RUN: grep HookB %t + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[(parameter_option "a", (extern)), + (prefix_list_option "b", (extern))]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd $INFILE"), +(in_language "dummy"), +(out_language "dummy"), +(actions (case + (not_empty "a"), (forward_transformed_value "a", "HookA"), + (not_empty "b"), (forward_transformed_value "b", "HookB"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; Added: llvm/trunk/test/LLVMC/ForwardValue.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ForwardValue.td?rev=90770&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/ForwardValue.td (added) +++ llvm/trunk/test/LLVMC/ForwardValue.td Mon Dec 7 11:03:05 2009 @@ -0,0 +1,21 @@ +// Check that forward_value works. +// The dummy tool and graph are required to silence warnings. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: grep {vec.push_back\(AutoGeneratedParameter_a\)} %t +// RUN: grep {std::copy\(AutoGeneratedList_b.begin\(\)} %t + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[(parameter_option "a", (extern)), + (prefix_list_option "b", (extern))]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd $INFILE"), +(in_language "dummy"), +(out_language "dummy"), +(actions (case + (not_empty "a"), (forward_value "a"), + (not_empty "b"), (forward_value "b"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=90770&r1=90769&r2=90770&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Dec 7 11:03:05 2009 @@ -98,10 +98,13 @@ // checkNumberOfArguments - Ensure that the number of args in d is // greater than or equal to min_arguments, otherwise throw an exception. -void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) { - if (!d || d->getNumArgs() < min_arguments) +void checkNumberOfArguments (const DagInit* d, unsigned minArgs) { + if (!d || d->getNumArgs() < minArgs) throw GetOperatorName(d) + ": too few arguments!"; } +void checkNumberOfArguments (const DagInit& d, unsigned minArgs) { + checkNumberOfArguments(&d, minArgs); +} // isDagEmpty - is this DAG marked with an empty marker? bool isDagEmpty (const DagInit* d) { @@ -1043,6 +1046,8 @@ const DagInit& Stmt = InitPtrToDag(Statement); const std::string& ActionName = GetOperatorName(Stmt); if (ActionName == "forward" || ActionName == "forward_as" || + ActionName == "forward_value" || + ActionName == "forward_transformed_value" || ActionName == "unpack_values" || ActionName == "switch_on" || ActionName == "parameter_equals" || ActionName == "element_in_list" || ActionName == "not_empty" || ActionName == "empty") { @@ -1796,6 +1801,45 @@ IndentLevel, NewName, O); } + void onForwardValue (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 1); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const OptionDescription& D = OptDescs.FindOption(Name); + + if (D.isParameter()) { + O.indent(IndentLevel) << "vec.push_back(" + << D.GenVariableName() << ");\n"; + } + else if (D.isList()) { + O.indent(IndentLevel) << "std::copy(" << D.GenVariableName() + << ".begin(), " << D.GenVariableName() + << ".end(), std::back_inserter(vec));\n"; + } + else { + throw "'forward_value' used with a switch or an alias!"; + } + } + + void onForwardTransformedValue (const DagInit& Dag, + unsigned IndentLevel, raw_ostream& O) const + { + checkNumberOfArguments(&Dag, 2); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const std::string& Hook = InitPtrToString(Dag.getArg(1)); + const OptionDescription& D = OptDescs.FindOption(Name); + + if (D.isParameter() || D.isList()) { + O.indent(IndentLevel) << "vec.push_back(" << "hooks::" + << Hook << "(" << D.GenVariableName() << "));\n"; + } + else { + throw "'forward_transformed_value' used with a switch or an alias!"; + } + } + + void onOutputSuffix (const DagInit& Dag, unsigned IndentLevel, raw_ostream& O) const { @@ -1819,7 +1863,7 @@ const OptionDescription& D = OptDescs.FindOption(Name); if (D.isMultiVal()) - throw std::string("Can't use unpack_values with multi-valued options!"); + throw "Can't use unpack_values with multi-valued options!"; if (D.isList()) { O.indent(IndentLevel) @@ -1851,6 +1895,9 @@ AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd); AddHandler("forward", &EmitActionHandlersCallback::onForward); AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs); + AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue); + AddHandler("forward_transformed_value", + &EmitActionHandlersCallback::onForwardTransformedValue); AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix); AddHandler("stop_compilation", &EmitActionHandlersCallback::onStopCompilation); @@ -2208,7 +2255,7 @@ O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n"; } else { - throw "Can't apply 'unset_option' to alias option '" + OptName + "'"; + throw "Can't apply 'unset_option' to alias option '" + OptName + "'!"; } } @@ -2414,23 +2461,72 @@ O << "}\n\n"; } +/// HookInfo - Information about the hook type and number of arguments. +struct HookInfo { + + // A hook can either have a single parameter of type std::vector, + // or NumArgs parameters of type const char*. + enum HookType { ListHook, ArgHook }; + + HookType Type; + unsigned NumArgs; + + HookInfo() : Type(ArgHook), NumArgs(1) + {} + + HookInfo(HookType T) : Type(T), NumArgs(1) + {} + + HookInfo(unsigned N) : Type(ArgHook), NumArgs(N) + {} +}; + +typedef llvm::StringMap HookInfoMap; + /// ExtractHookNames - Extract the hook names from all instances of -/// $CALL(HookName) in the provided command line string. Helper +/// $CALL(HookName) in the provided command line string/action. Helper /// function used by FillInHookNames(). class ExtractHookNames { - llvm::StringMap& HookNames_; + HookInfoMap& HookNames_; + const OptionDescriptions& OptDescs_; public: - ExtractHookNames(llvm::StringMap& HookNames) - : HookNames_(HookNames) {} + ExtractHookNames(HookInfoMap& HookNames, const OptionDescriptions& OptDescs) + : HookNames_(HookNames), OptDescs_(OptDescs) + {} - void operator()(const Init* CmdLine) { - StrVector cmds; + void onAction (const DagInit& Dag) { + if (GetOperatorName(Dag) == "forward_transformed_value") { + checkNumberOfArguments(Dag, 2); + const std::string& OptName = InitPtrToString(Dag.getArg(0)); + const std::string& HookName = InitPtrToString(Dag.getArg(1)); + const OptionDescription& D = OptDescs_.FindOption(OptName); - // Ignore nested 'case' DAG. - if (typeid(*CmdLine) == typeid(DagInit)) + HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook + : HookInfo::ArgHook); + } + } + + void operator()(const Init* Arg) { + + // We're invoked on an action (either a dag or a dag list). + if (typeid(*Arg) == typeid(DagInit)) { + const DagInit& Dag = InitPtrToDag(Arg); + this->onAction(Dag); return; + } + else if (typeid(*Arg) == typeid(ListInit)) { + const ListInit& List = InitPtrToList(Arg); + for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E; + ++B) { + const DagInit& Dag = InitPtrToDag(*B); + this->onAction(Dag); + } + return; + } - TokenizeCmdline(InitPtrToString(CmdLine), cmds); + // We're invoked on a command line. + StrVector cmds; + TokenizeCmdline(InitPtrToString(Arg), cmds); for (StrVector::const_iterator B = cmds.begin(), E = cmds.end(); B != E; ++B) { const std::string& cmd = *B; @@ -2448,13 +2544,14 @@ ++NumArgs; } - StringMap::const_iterator H = HookNames_.find(HookName); + HookInfoMap::const_iterator H = HookNames_.find(HookName); - if (H != HookNames_.end() && H->second != NumArgs) + if (H != HookNames_.end() && H->second.NumArgs != NumArgs && + H->second.Type != HookInfo::ArgHook) throw "Overloading of hooks is not allowed. Overloaded hook: " + HookName; else - HookNames_[HookName] = NumArgs; + HookNames_[HookName] = HookInfo(NumArgs); } } @@ -2471,40 +2568,56 @@ /// FillInHookNames - Actually extract the hook names from all command /// line strings. Helper function used by EmitHookDeclarations(). void FillInHookNames(const ToolDescriptions& ToolDescs, - llvm::StringMap& HookNames) + const OptionDescriptions& OptDescs, + HookInfoMap& HookNames) { - // For all command lines: + // For all tool descriptions: for (ToolDescriptions::const_iterator B = ToolDescs.begin(), E = ToolDescs.end(); B != E; ++B) { const ToolDescription& D = *(*B); + + // Look for 'forward_transformed_value' in 'actions'. + if (D.Actions) + WalkCase(D.Actions, Id(), ExtractHookNames(HookNames, OptDescs)); + + // Look for hook invocations in 'cmd_line'. if (!D.CmdLine) continue; if (dynamic_cast(D.CmdLine)) // This is a string. - ExtractHookNames(HookNames).operator()(D.CmdLine); + ExtractHookNames(HookNames, OptDescs).operator()(D.CmdLine); else // This is a 'case' construct. - WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames)); + WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames, OptDescs)); } } /// EmitHookDeclarations - Parse CmdLine fields of all the tool /// property records and emit hook function declaration for each /// instance of $CALL(HookName). -void EmitHookDeclarations(const ToolDescriptions& ToolDescs, raw_ostream& O) { - llvm::StringMap HookNames; +void EmitHookDeclarations(const ToolDescriptions& ToolDescs, + const OptionDescriptions& OptDescs, raw_ostream& O) { + HookInfoMap HookNames; - FillInHookNames(ToolDescs, HookNames); + FillInHookNames(ToolDescs, OptDescs, HookNames); if (HookNames.empty()) return; O << "namespace hooks {\n"; - for (StringMap::const_iterator B = HookNames.begin(), + for (HookInfoMap::const_iterator B = HookNames.begin(), E = HookNames.end(); B != E; ++B) { - O.indent(Indent1) << "std::string " << B->first() << "("; + const char* HookName = B->first(); + const HookInfo& Info = B->second; + + O.indent(Indent1) << "std::string " << HookName << "("; - for (unsigned i = 0, j = B->second; i < j; ++i) { - O << "const char* Arg" << i << (i+1 == j ? "" : ", "); + if (Info.Type == HookInfo::ArgHook) { + for (unsigned i = 0, j = Info.NumArgs; i < j; ++i) { + O << "const char* Arg" << i << (i+1 == j ? "" : ", "); + } + } + else { + O << "const std::vector& Arg"; } O <<");\n"; @@ -2541,7 +2654,9 @@ << "#include \"llvm/Support/CommandLine.h\"\n" << "#include \"llvm/Support/raw_ostream.h\"\n\n" + << "#include \n" << "#include \n" + << "#include \n" << "#include \n\n" << "using namespace llvm;\n" @@ -2635,7 +2750,7 @@ EmitOptionDefinitions(Data.OptDescs, Data.HasSink, Data.HasExterns, O); // Emit hook declarations. - EmitHookDeclarations(Data.ToolDescs, O); + EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O); O << "namespace {\n\n"; From foldr at codedgers.com Mon Dec 7 11:03:21 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 17:03:21 -0000 Subject: [llvm-commits] [llvm] r90771 - in /llvm/trunk/tools/llvmc/plugins/Base: Base.td.in Hooks.cpp Message-ID: <200912071703.nB7H3Lk3011204@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 11:03:21 2009 New Revision: 90771 URL: http://llvm.org/viewvc/llvm-project?rev=90771&view=rev Log: Pass '-msse' and friends to llc as '-mattr=+/-'. Added: llvm/trunk/tools/llvmc/plugins/Base/Hooks.cpp Modified: llvm/trunk/tools/llvmc/plugins/Base/Base.td.in Modified: llvm/trunk/tools/llvmc/plugins/Base/Base.td.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Base.td.in?rev=90771&r1=90770&r2=90771&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Base/Base.td.in (original) +++ llvm/trunk/tools/llvmc/plugins/Base/Base.td.in Mon Dec 7 11:03:21 2009 @@ -82,7 +82,10 @@ (prefix_list_option "Wl,", (help "Pass options to linker")), (prefix_list_option "Wo,", - (help "Pass options to opt")) + (help "Pass options to opt")), + (prefix_list_option "m", + (help "Enable or disable various extensions (-mmmx, -msse, etc.)"), + (hidden)) ]>; // Option preprocessor. @@ -132,6 +135,7 @@ (not_empty "march"), (forward "march"), (not_empty "mtune"), (forward "mtune"), (not_empty "mcpu"), (forward "mcpu"), + (not_empty "m"), (forward "m"), (switch_on "m32"), (forward "m32"), (switch_on "m64"), (forward "m64"), (switch_on "O1"), (forward "O1"), @@ -197,6 +201,7 @@ (not_empty "march"), (forward "mcpu"), (not_empty "mtune"), (forward "mcpu"), (not_empty "mcpu"), (forward "mcpu"), + (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"), (not_empty "Wllc,"), (unpack_values "Wllc,"))) ]>; Added: llvm/trunk/tools/llvmc/plugins/Base/Hooks.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Hooks.cpp?rev=90771&view=auto ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Base/Hooks.cpp (added) +++ llvm/trunk/tools/llvmc/plugins/Base/Hooks.cpp Mon Dec 7 11:03:21 2009 @@ -0,0 +1,33 @@ +#include +#include + +namespace hooks { +typedef std::vector StrVec; + +/// ConvertToMAttr - Convert -m* and -mno-* to -mattr=+*,-* +std::string ConvertToMAttr(const StrVec& Opts) { + std::string out("-mattr="); + + bool firstIter = true; + for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) { + const std::string& Arg = *B; + + if (firstIter) + firstIter = false; + else + out += ","; + + if (Arg.find("no-") == 0 && Arg[3] != 0) { + out += '-'; + out += Arg.c_str() + 3; + } + else { + out += '+'; + out += Arg; + } + } + + return out; +} + +} From evan.cheng at apple.com Mon Dec 7 12:08:48 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 7 Dec 2009 10:08:48 -0800 Subject: [llvm-commits] [llvm] r90759 - in /llvm/trunk: include/llvm/CodeGen/MachineSSAUpdater.h lib/CodeGen/MachineSSAUpdater.cpp lib/CodeGen/TailDuplication.cpp In-Reply-To: References: <200912071015.nB7AFKWn029279@zion.cs.uiuc.edu> Message-ID: On Dec 7, 2009, at 8:27 AM, Chris Lattner wrote: > > On Dec 7, 2009, at 2:15 AM, Evan Cheng wrote: > >> Author: evancheng >> Date: Mon Dec 7 04:15:19 2009 >> New Revision: 90759 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=90759&view=rev >> Log: >> Pre-regalloc tale duplication. Work in progress. > > Hey Evan, > >> @@ -207,6 +207,16 @@ >> >> +void MachineSSAUpdater::ReplaceRegWith(unsigned OldReg, unsigned NewReg) { >> + MRI->replaceRegWith(OldReg, NewReg); >> + >> + AvailableValsTy &AvailableVals = getAvailableVals(AV); >> + for (DenseMap::iterator >> + I = AvailableVals.begin(), E = AvailableVals.end(); I != E; ++I) >> + if (I->second == OldReg) >> + I->second = NewReg; >> +} > > This scan can be *really* expensive: O(size of function). Would it be better to insert copies and then zap the copies at the end? I know it's expensive. But I have not identified a solution. AvailableVals is the internal data structure tracking reaching definition. I am not sure what you mean by inserting copies. This function is called when it recognize the "cookie" phi instruction is not needed. Right now the pre-regalloc tail duplication pass is totally useless anyway. It's severely pessmizing code. All the new PHI instructions and copies are not being zapped. Evan > > -Chris From foldr at codedgers.com Mon Dec 7 12:25:54 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 18:25:54 -0000 Subject: [llvm-commits] [llvm] r90774 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td tools/llvmc/plugins/Base/Base.td.in tools/llvmc/plugins/Clang/Clang.td utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200912071825.nB7IPs2X014092@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 12:25:54 2009 New Revision: 90774 URL: http://llvm.org/viewvc/llvm-project?rev=90774&view=rev Log: Deprecate 'unpack_values'. Use 'forward_values' + 'comma_separated' instead. Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td llvm/trunk/tools/llvmc/plugins/Base/Base.td.in llvm/trunk/tools/llvmc/plugins/Clang/Clang.td llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=90774&r1=90773&r2=90774&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Mon Dec 7 12:25:54 2009 @@ -45,6 +45,7 @@ def really_hidden; def required; def zero_or_one; +def comma_separated; // The 'case' construct. def case; Modified: llvm/trunk/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td?rev=90774&r1=90773&r2=90774&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td (original) +++ llvm/trunk/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td Mon Dec 7 12:25:54 2009 @@ -41,9 +41,9 @@ // (help "Optimization level 2. (Default)")), // (parameter_option "pre-RA-sched", // (help "Example of an option that is passed to llc")), - (prefix_list_option "Wa,", + (prefix_list_option "Wa,", (comma_separated), (help "Pass options to native assembler")), - (prefix_list_option "Wl,", + (prefix_list_option "Wl,", (comma_separated), (help "Pass options to native linker")) // (prefix_list_option "Wllc,", // (help "Pass options to llc")), @@ -58,11 +58,11 @@ (output_suffix "bc"), (cmd_line (case (switch_on "E"), - (case + (case (not_empty "o"), !strconcat(cmd, " -E $INFILE -o $OUTFILE"), (default), !strconcat(cmd, " -E $INFILE")), (default), !strconcat(cmd, " $INFILE -o $OUTFILE"))), - (actions (case + (actions (case (and (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), (error "cannot specify -o with -c or -S with multiple files"), (switch_on "E"), [(stop_compilation), (output_suffix ext_E)], @@ -138,7 +138,7 @@ (actions (case (switch_on "c"), (stop_compilation), (switch_on "g"), (append_cmd "-g"), - (not_empty "Wa,"), (unpack_values "Wa,"))) + (not_empty "Wa,"), (forward_value "Wa,"))) ]>; def mplink : Tool<[ @@ -147,13 +147,13 @@ (output_suffix "cof"), (cmd_line "$CALL(GetBinDir)mplink.exe -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) -p 16f1937 intrinsics.lib devices.lib $INFILE -o $OUTFILE"), (actions (case - (not_empty "Wl,"), (unpack_values "Wl,"), + (not_empty "Wl,"), (forward_value "Wl,"), (not_empty "L"), (forward_as "L", "-l"), (not_empty "K"), (forward_as "K", "-k"), (not_empty "m"), (forward "m"), // (not_empty "l"), [(unpack_values "l"),(append_cmd ".lib")])), - (not_empty "k"), (unpack_values "k"), - (not_empty "l"), (unpack_values "l"))), + (not_empty "k"), (forward_value "k"), + (not_empty "l"), (forward_value "l"))), (join) ]>; @@ -175,13 +175,13 @@ def CompilationGraph : CompilationGraph<[ Edge<"root", "clang_cc">, Edge<"root", "llvm_ld">, - OptionalEdge<"root", "llvm_ld_optimizer", (case + OptionalEdge<"root", "llvm_ld_optimizer", (case (switch_on "S"), (inc_weight), (switch_on "c"), (inc_weight))>, Edge<"root", "gpasm">, Edge<"root", "mplink">, Edge<"clang_cc", "llvm_ld">, - OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case + OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case (switch_on "S"), (inc_weight), (switch_on "c"), (inc_weight))>, Edge<"llvm_ld", "pic16passes">, Modified: llvm/trunk/tools/llvmc/plugins/Base/Base.td.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Base.td.in?rev=90774&r1=90773&r2=90774&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Base/Base.td.in (original) +++ llvm/trunk/tools/llvmc/plugins/Base/Base.td.in Mon Dec 7 12:25:54 2009 @@ -71,9 +71,9 @@ (help "Add a directory to include path")), (prefix_list_option "D", (help "Define a macro")), - (prefix_list_option "Wa,", + (prefix_list_option "Wa,", (comma_separated), (help "Pass options to assembler")), - (prefix_list_option "Wllc,", + (prefix_list_option "Wllc,", (comma_separated), (help "Pass options to llc")), (prefix_list_option "L", (help "Add a directory to link path")), @@ -81,7 +81,7 @@ (help "Search a library when linking")), (prefix_list_option "Wl,", (help "Pass options to linker")), - (prefix_list_option "Wo,", + (prefix_list_option "Wo,", (comma_separated), (help "Pass options to opt")), (prefix_list_option "m", (help "Enable or disable various extensions (-mmmx, -msse, etc.)"), @@ -159,7 +159,7 @@ [(in_language "llvm-bitcode"), (out_language "llvm-bitcode"), (output_suffix "bc"), - (actions (case (not_empty "Wo,"), (unpack_values "Wo,"), + (actions (case (not_empty "Wo,"), (forward_value "Wo,"), (switch_on "O1"), (forward "O1"), (switch_on "O2"), (forward "O2"), (switch_on "O3"), (forward "O3"))), @@ -181,7 +181,7 @@ (cmd_line "@LLVMGCCCOMMAND@ -c -x assembler $INFILE -o $OUTFILE"), (actions (case (switch_on "c"), (stop_compilation), - (not_empty "Wa,"), (unpack_values "Wa,"))) + (not_empty "Wa,"), (forward_value "Wa,"))) ]>; def llc : Tool< @@ -202,7 +202,7 @@ (not_empty "mtune"), (forward "mcpu"), (not_empty "mcpu"), (forward "mcpu"), (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"), - (not_empty "Wllc,"), (unpack_values "Wllc,"))) + (not_empty "Wllc,"), (forward_value "Wllc,"))) ]>; // Base class for linkers Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?rev=90774&r1=90773&r2=90774&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Mon Dec 7 12:25:54 2009 @@ -68,7 +68,7 @@ (out_language "object-code"), (output_suffix "o"), (cmd_line "as $INFILE -o $OUTFILE"), - (actions (case (not_empty "Wa,"), (unpack_values "Wa,"), + (actions (case (not_empty "Wa,"), (forward_value "Wa,"), (switch_on "c"), (stop_compilation))) ]>; @@ -82,7 +82,7 @@ (switch_on "pthread"), (append_cmd "-lpthread"), (not_empty "L"), (forward "L"), (not_empty "l"), (forward "l"), - (not_empty "Wl,"), (unpack_values "Wl,"))), + (not_empty "Wl,"), (forward_value "Wl,"))), (join) ]>; Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=90774&r1=90773&r2=90774&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Dec 7 12:25:54 2009 @@ -211,7 +211,8 @@ namespace OptionDescriptionFlags { enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, ReallyHidden = 0x4, Extern = 0x8, - OneOrMore = 0x10, ZeroOrOne = 0x20 }; + OneOrMore = 0x10, ZeroOrOne = 0x20, + CommaSeparated = 0x40 }; } /// OptionDescription - Represents data contained in a single @@ -247,6 +248,9 @@ bool isMultiVal() const; + bool isCommaSeparated() const; + void setCommaSeparated(); + bool isExtern() const; void setExtern(); @@ -299,6 +303,13 @@ return MultiVal > 1; } +bool OptionDescription::isCommaSeparated() const { + return Flags & OptionDescriptionFlags::CommaSeparated; +} +void OptionDescription::setCommaSeparated() { + Flags |= OptionDescriptionFlags::CommaSeparated; +} + bool OptionDescription::isExtern() const { return Flags & OptionDescriptionFlags::Extern; } @@ -538,6 +549,7 @@ AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); AddHandler("required", &CollectOptionProperties::onRequired); AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne); + AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated); staticMembersInitialized_ = true; } @@ -574,11 +586,18 @@ optDesc_.setReallyHidden(); } + void onCommaSeparated (const DagInit* d) { + checkNumberOfArguments(d, 0); + if (!optDesc_.isList()) + throw "'comma_separated' is valid only on list options!"; + optDesc_.setCommaSeparated(); + } + void onRequired (const DagInit* d) { checkNumberOfArguments(d, 0); - if (optDesc_.isOneOrMore()) - throw std::string("An option can't have both (required) " - "and (one_or_more) properties!"); + if (optDesc_.isOneOrMore() || optDesc_.isZeroOrOne()) + throw "Only one of (required), (zero_or_one) or " + "(one_or_more) properties is allowed!"; optDesc_.setRequired(); } @@ -591,7 +610,7 @@ correct |= (optDesc_.isSwitch() && (str == "true" || str == "false")); if (!correct) - throw std::string("Incorrect usage of the 'init' option property!"); + throw "Incorrect usage of the 'init' option property!"; optDesc_.InitVal = i; } @@ -599,8 +618,8 @@ void onOneOrMore (const DagInit* d) { checkNumberOfArguments(d, 0); if (optDesc_.isRequired() || optDesc_.isZeroOrOne()) - throw std::string("Only one of (required), (zero_or_one) or " - "(one_or_more) properties is allowed!"); + throw "Only one of (required), (zero_or_one) or " + "(one_or_more) properties is allowed!"; if (!OptionType::IsList(optDesc_.Type)) llvm::errs() << "Warning: specifying the 'one_or_more' property " "on a non-list option will have no effect.\n"; @@ -610,8 +629,8 @@ void onZeroOrOne (const DagInit* d) { checkNumberOfArguments(d, 0); if (optDesc_.isRequired() || optDesc_.isOneOrMore()) - throw std::string("Only one of (required), (zero_or_one) or " - "(one_or_more) properties is allowed!"); + throw "Only one of (required), (zero_or_one) or " + "(one_or_more) properties is allowed!"; if (!OptionType::IsList(optDesc_.Type)) llvm::errs() << "Warning: specifying the 'zero_or_one' property" "on a non-list option will have no effect.\n"; @@ -622,11 +641,10 @@ checkNumberOfArguments(d, 1); int val = InitPtrToInt(d->getArg(0)); if (val < 2) - throw std::string("Error in the 'multi_val' property: " - "the value must be greater than 1!"); + throw "Error in the 'multi_val' property: " + "the value must be greater than 1!"; if (!OptionType::IsList(optDesc_.Type)) - throw std::string("The multi_val property is valid only " - "on list options!"); + throw "The multi_val property is valid only on list options!"; optDesc_.MultiVal = val; } @@ -1048,9 +1066,9 @@ if (ActionName == "forward" || ActionName == "forward_as" || ActionName == "forward_value" || ActionName == "forward_transformed_value" || - ActionName == "unpack_values" || ActionName == "switch_on" || - ActionName == "parameter_equals" || ActionName == "element_in_list" || - ActionName == "not_empty" || ActionName == "empty") { + ActionName == "switch_on" || ActionName == "parameter_equals" || + ActionName == "element_in_list" || ActionName == "not_empty" || + ActionName == "empty") { checkNumberOfArguments(&Stmt, 1); const std::string& Name = InitPtrToString(Stmt.getArg(0)); OptionNames_.insert(Name); @@ -1858,30 +1876,8 @@ void onUnpackValues (const DagInit& Dag, unsigned IndentLevel, raw_ostream& O) const { - checkNumberOfArguments(&Dag, 1); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const OptionDescription& D = OptDescs.FindOption(Name); - - if (D.isMultiVal()) - throw "Can't use unpack_values with multi-valued options!"; - - if (D.isList()) { - O.indent(IndentLevel) - << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n"; - O.indent(IndentLevel) - << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"; - O.indent(IndentLevel + Indent1) - << "llvm::SplitString(*B, vec, \",\");\n"; - } - else if (D.isParameter()){ - O.indent(IndentLevel) << "llvm::SplitString(" - << D.GenVariableName() << ", vec, \",\");\n"; - } - else { - throw "Option '" + D.Name + - "': switches can't have the 'unpack_values' property!"; - } + throw "'unpack_values' is deprecated. " + "Use 'comma_separated' + 'forward_value' instead!"; } public: @@ -2191,12 +2187,13 @@ O << ", cl::ZeroOrOne"; } - if (val.isReallyHidden()) { + if (val.isReallyHidden()) O << ", cl::ReallyHidden"; - } - else if (val.isHidden()) { + else if (val.isHidden()) O << ", cl::Hidden"; - } + + if (val.isCommaSeparated()) + O << ", cl::CommaSeparated"; if (val.MultiVal > 1) O << ", cl::multi_val(" << val.MultiVal << ')'; @@ -2650,7 +2647,6 @@ << "#include \"llvm/CompilerDriver/Plugin.h\"\n" << "#include \"llvm/CompilerDriver/Tool.h\"\n\n" - << "#include \"llvm/ADT/StringExtras.h\"\n" << "#include \"llvm/Support/CommandLine.h\"\n" << "#include \"llvm/Support/raw_ostream.h\"\n\n" From foldr at codedgers.com Mon Dec 7 12:26:11 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 18:26:11 -0000 Subject: [llvm-commits] [llvm] r90775 - /llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Message-ID: <200912071826.nB7IQBD2014109@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 12:26:11 2009 New Revision: 90775 URL: http://llvm.org/viewvc/llvm-project?rev=90775&view=rev Log: Documentation update. Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=90775&r1=90774&r2=90775&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Mon Dec 7 12:26:11 2009 @@ -347,6 +347,12 @@ - ``really_hidden`` - the option will not be mentioned in any help output. + - ``comma_separated`` - Indicates that any commas specified for an option's + value should be used to split the value up into multiple values for the + option. This property is valid only for list options. In conjunction with + ``forward_value`` can be used to implement option forwarding in style of + gcc's ``-Wa,``. + - ``multi_val n`` - this option takes *n* arguments (can be useful in some special cases). Usage example: ``(parameter_list_option "foo", (multi_val 3))``; the command-line syntax is '-foo a b c'. Only list options can have @@ -359,7 +365,11 @@ examples: ``(switch_option "foo", (init true))``; ``(prefix_option "bar", (init "baz"))``. - - ``extern`` - this option is defined in some other plugin, see below. + - ``extern`` - this option is defined in some other plugin, see `below`__. + + __ extern_ + +.. _extern: External options ---------------- @@ -547,7 +557,11 @@ - ``actions`` - A single big ``case`` expression that specifies how this tool reacts on command-line options (described in more detail - below). + `below`__). + +__ actions_ + +.. _actions: Actions ------- @@ -585,35 +599,42 @@ * Possible actions: - - ``append_cmd`` - append a string to the tool invocation - command. - Example: ``(case (switch_on "pthread"), (append_cmd - "-lpthread"))`` + - ``append_cmd`` - Append a string to the tool invocation command. + Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))``. - - ``error`` - exit with error. + - ``error`` - Exit with error. Example: ``(error "Mixing -c and -S is not allowed!")``. - - ``warning`` - print a warning. + - ``warning`` - Print a warning. Example: ``(warning "Specifying both -O1 and -O2 is meaningless!")``. - - ``forward`` - forward an option unchanged. Example: ``(forward "Wall")``. + - ``forward`` - Forward the option unchanged. + Example: ``(forward "Wall")``. - - ``forward_as`` - Change the name of an option, but forward the - argument unchanged. + - ``forward_as`` - Change the option's name, but forward the argument + unchanged. Example: ``(forward_as "O0", "--disable-optimization")``. - - ``output_suffix`` - modify the output suffix of this - tool. + - ``forward_value`` - Forward only option's value. Cannot be used with switch + options (since they don't have values), but works fine with lists. + Example: ``(forward_value "Wa,")``. + + - ``forward_transformed_value`` - As above, but applies a hook to the + option's value before forwarding (see `below`__). When + ``forward_transformed_value`` is applied to a list + option, the hook must have signature + ``std::string hooks::HookName (const std::vector&)``. + Example: ``(forward_transformed_value "m", "ConvertToMAttr")``. + + __ hooks_ + + - ``output_suffix`` - Modify the output suffix of this tool. Example: ``(output_suffix "i")``. - - ``stop_compilation`` - stop compilation after this tool processes - its input. Used without arguments. + - ``stop_compilation`` - Stop compilation after this tool processes its + input. Used without arguments. + Example: ``(stop_compilation)``. - - ``unpack_values`` - used for for splitting and forwarding - comma-separated lists of options, e.g. ``-Wa,-foo=bar,-baz`` is - converted to ``-foo=bar -baz`` and appended to the tool invocation - command. - Example: ``(unpack_values "Wa,")``. Language map ============ @@ -760,6 +781,8 @@ extern const char* ProgramName; } + namespace hooks { + std::string MyHook() { //... if (strcmp(ProgramName, "mydriver") == 0) { @@ -767,6 +790,8 @@ } + } // end namespace hooks + In general, you're encouraged not to make the behaviour dependent on the executable file name, and use command-line switches instead. See for example how the ``Base`` plugin behaves when it needs to choose the correct linker options From foldr at codedgers.com Mon Dec 7 12:26:24 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 18:26:24 -0000 Subject: [llvm-commits] [llvm] r90776 - /llvm/trunk/docs/CompilerDriver.html Message-ID: <200912071826.nB7IQOgx014129@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 12:26:24 2009 New Revision: 90776 URL: http://llvm.org/viewvc/llvm-project?rev=90776&view=rev Log: Regenerate. Modified: llvm/trunk/docs/CompilerDriver.html Modified: llvm/trunk/docs/CompilerDriver.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CompilerDriver.html?rev=90776&r1=90775&r2=90776&view=diff ============================================================================== --- llvm/trunk/docs/CompilerDriver.html (original) +++ llvm/trunk/docs/CompilerDriver.html Mon Dec 7 12:26:24 2009 @@ -17,28 +17,28 @@

Contents

-

Conditional evaluation

+

Conditional evaluation

The 'case' construct is the main means by which programmability is achieved in LLVMC. It can be used to calculate edge weights, program actions and modify the shell commands to be executed. The 'case' @@ -433,7 +438,7 @@ Example: (parameter_equals "W", "all").

  • element_in_list - Returns true if a command-line parameter list contains a given value. -Example: (parameter_in_list "l", "pthread").
  • +Example: (element_in_list "l", "pthread").
  • input_languages_contain - Returns true if a given language belongs to the current input language set. Example: (input_languages_contain "c++").
  • @@ -475,7 +480,7 @@
    -

    Writing a tool description

    +

    Writing a tool description

    As was said earlier, nodes in the compilation graph represent tools, which are described separately. A tool definition looks like this (taken from the include/llvm/CompilerDriver/Tools.td file):

    @@ -512,12 +517,12 @@ tools are passed to this tool.
  • actions - A single big case expression that specifies how this tool reacts on command-line options (described in more detail -below).
  • +below). -
    -

    Actions

    +
    +

    Actions

    A tool often needs to react to command-line options, and this is precisely what the actions property is for. The next example illustrates this feature:

    @@ -550,28 +555,31 @@
  • Possible actions:

      -
    • append_cmd - append a string to the tool invocation -command. -Example: (case (switch_on "pthread"), (append_cmd -"-lpthread"))
    • -
    • error - exit with error. +
    • append_cmd - Append a string to the tool invocation command. +Example: (case (switch_on "pthread"), (append_cmd "-lpthread")).
    • +
    • error - Exit with error. Example: (error "Mixing -c and -S is not allowed!").
    • -
    • warning - print a warning. +
    • warning - Print a warning. Example: (warning "Specifying both -O1 and -O2 is meaningless!").
    • -
    • forward - forward an option unchanged. Example: (forward "Wall").
    • -
    • forward_as - Change the name of an option, but forward the -argument unchanged. +
    • forward - Forward the option unchanged. +Example: (forward "Wall").
    • +
    • forward_as - Change the option's name, but forward the argument +unchanged. Example: (forward_as "O0", "--disable-optimization").
    • -
    • output_suffix - modify the output suffix of this -tool. +
    • forward_value - Forward only option's value. Cannot be used with switch +options (since they don't have values), but works fine with lists. +Example: (forward_value "Wa,").
    • +
    • forward_transformed_value - As above, but applies a hook to the +option's value before forwarding (see below). When +forward_transformed_value is applied to a list +option, the hook must have signature +std::string hooks::HookName (const std::vector<std::string>&). +Example: (forward_transformed_value "m", "ConvertToMAttr").
    • +
    • output_suffix - Modify the output suffix of this tool. Example: (output_suffix "i").
    • -
    • stop_compilation - stop compilation after this tool processes -its input. Used without arguments.
    • -
    • unpack_values - used for for splitting and forwarding -comma-separated lists of options, e.g. -Wa,-foo=bar,-baz is -converted to -foo=bar -baz and appended to the tool invocation -command. -Example: (unpack_values "Wa,").
    • +
    • stop_compilation - Stop compilation after this tool processes its +input. Used without arguments. +Example: (stop_compilation).
  • @@ -579,7 +587,7 @@
    -

    Language map

    +

    Language map

    If you are adding support for a new language to LLVMC, you'll need to modify the language map, which defines mappings from file extensions to language names. It is used to choose the proper toolchain(s) for a @@ -602,7 +610,7 @@ output languages should match. This is enforced at compile-time.

    -

    Option preprocessor

    +

    Option preprocessor

    It is sometimes useful to run error-checking code before processing the compilation graph. For example, if optimization options "-O1" and "-O2" are implemented as switches, we might want to output a warning if the user invokes @@ -629,9 +637,9 @@ convenience, unset_option also works on lists.

    -

    More advanced topics

    +

    More advanced topics

    -

    Hooks and environment variables

    +

    Hooks and environment variables

    Normally, LLVMC executes programs from the system PATH. Sometimes, this is not sufficient: for example, we may want to specify tool paths or names in the configuration file. This can be easily achieved via @@ -664,7 +672,7 @@

    -

    How plugins are loaded

    +

    How plugins are loaded

    It is possible for LLVMC plugins to depend on each other. For example, one can create edges between nodes defined in some other plugin. To make this work, however, that plugin should be loaded first. To @@ -680,7 +688,7 @@ loaded last.

    -

    Debugging

    +

    Debugging

    When writing LLVMC plugins, it can be useful to get a visual view of the resulting compilation graph. This can be achieved via the command line option --view-graph. This command assumes that Graphviz and @@ -696,7 +704,7 @@ errors as its status code.

    -

    Conditioning on the executable name

    +

    Conditioning on the executable name

    For now, the executable name (the value passed to the driver in argv[0]) is accessible only in the C++ code (i.e. hooks). Use the following code:

    @@ -704,12 +712,16 @@
     extern const char* ProgramName;
     }
     
    +namespace hooks {
    +
     std::string MyHook() {
     //...
     if (strcmp(ProgramName, "mydriver") == 0) {
        //...
     
     }
    +
    +} // end namespace hooks
     

    In general, you're encouraged not to make the behaviour dependent on the executable file name, and use command-line switches instead. See for example how @@ -727,7 +739,7 @@ Mikhail Glushenkov
    LLVM Compiler Infrastructure
    -Last modified: $Date$ +Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $

    From sabre at nondot.org Mon Dec 7 12:36:53 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Dec 2009 18:36:53 -0000 Subject: [llvm-commits] [llvm] r90779 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912071836.nB7IarRZ014517@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 7 12:36:53 2009 New Revision: 90779 URL: http://llvm.org/viewvc/llvm-project?rev=90779&view=rev Log: checkpoint of the new PHITransAddr code, still not done and not used by anything. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90779&r1=90778&r2=90779&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Mon Dec 7 12:36:53 2009 @@ -35,10 +35,13 @@ /// Addr - The actual address we're analyzing. Value *Addr; + /// TD - The target data we are playing with if known, otherwise null. + const TargetData *TD; + /// InstInputs - The inputs for our symbolic address. SmallVector InstInputs; public: - PHITransAddr(Value *addr) : Addr(addr) { + PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) { // If the address is an instruction, the whole thing is considered an input. if (Instruction *I = dyn_cast(Addr)) InstInputs.push_back(I); @@ -55,35 +58,44 @@ return false; } - /// IsPHITranslatable - If this needs PHI translation, return true if we have - /// some hope of doing it. This should be used as a filter to avoid calling - /// GetPHITranslatedValue in hopeless situations. - bool IsPHITranslatable() const; - - /// GetPHITranslatedValue - Given a computation that satisfied the - /// isPHITranslatable predicate, see if we can translate the computation into - /// the specified predecessor block. If so, return that value, otherwise - /// return null. - Value *GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, - BasicBlock *Pred, const TargetData *TD) const; - - /// GetAvailablePHITranslatePointer - Return the value computed by - /// PHITranslatePointer if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const; + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true + /// if we have some hope of doing it. This should be used as a filter to + /// avoid calling PHITranslateValue in hopeless situations. + bool IsPotentiallyPHITranslatable() const; + + /// PHITranslateValue - PHI translate the current address up the CFG from + /// CurBB to Pred, updating our state the reflect any needed changes. This + /// returns true on failure. + bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); + + /// PHITranslateWithInsertion - PHI translate this value into the specified + /// predecessor block, inserting a computation of the value if it is + /// unavailable. + /// + /// All newly created instructions are added to the NewInsts list. This + /// returns null on failure. + /// + Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl &NewInsts); +private: + Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); + + + /// GetAvailablePHITranslatedSubExpr - Return the value computed by + /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. + Value *GetAvailablePHITranslatedSubExpr(Value *V, + BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT); - /// InsertPHITranslatedPointer - Insert a computation of the PHI translated + /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// - Value *InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB, - BasicBlock *PredBB, const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const; - + Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl &NewInsts); }; } // end namespace llvm Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90779&r1=90778&r2=90779&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Mon Dec 7 12:36:53 2009 @@ -13,36 +13,178 @@ #include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/InstructionSimplify.h" using namespace llvm; -/// IsPHITranslatable - If this needs PHI translation, return true if we have -/// some hope of doing it. This should be used as a filter to avoid calling -/// GetPHITranslatedValue in hopeless situations. -bool PHITransAddr::IsPHITranslatable() const { - return true; // not a good filter. +/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true +/// if we have some hope of doing it. This should be used as a filter to +/// avoid calling PHITranslateValue in hopeless situations. +bool PHITransAddr::IsPotentiallyPHITranslatable() const { + // If the input value is not an instruction, or if it is not defined in CurBB, + // then we don't need to phi translate it. + Instruction *Inst = dyn_cast(Addr); + if (isa(Inst) || + isa(Inst) || + isa(Inst) || + (Inst->getOpcode() == Instruction::And && + isa(Inst->getOperand(1)))) + return true; + + // cerr << "MEMDEP: Could not PHI translate: " << *Pointer; + // if (isa(PtrInst) || isa(PtrInst)) + // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); + + return false; } -/// GetPHITranslatedValue - Given a computation that satisfied the -/// isPHITranslatable predicate, see if we can translate the computation into -/// the specified predecessor block. If so, return that value, otherwise -/// return null. -Value *PHITransAddr::GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, - BasicBlock *Pred, - const TargetData *TD) const { - // Not a great implementation. - return 0; + +Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, + BasicBlock *PredBB) { + // If this is a non-instruction value, it can't require PHI translation. + Instruction *Inst = dyn_cast(V); + if (Inst == 0) return V; + + // Determine whether 'Inst' is an input to our PHI translatable expression. + bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); + + // If 'Inst' is not defined in this block, it is either an input, or an + // intermediate result. + if (Inst->getParent() != CurBB) { + // If it is an input, then it remains an input. + if (isInput) + return Inst; + + // Otherwise, it must be an intermediate result. See if its operands need + // to be phi translated, and if so, reconstruct it. + + if (BitCastInst *BC = dyn_cast(Inst)) { + Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB); + if (PHIIn == 0) return 0; + if (PHIIn == BC->getOperand(0)) + return BC; + + // Find an available version of this cast. + + // Constants are trivial to find. + if (Constant *C = dyn_cast(PHIIn)) + return ConstantExpr::getBitCast(C, BC->getType()); + + // Otherwise we have to see if a bitcasted version of the incoming pointer + // is available. If so, we can use it, otherwise we have to fail. + for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end(); + UI != E; ++UI) { + if (BitCastInst *BCI = dyn_cast(*UI)) + if (BCI->getType() == BC->getType()) + return BCI; + } + return 0; + } + + // Handle getelementptr with at least one PHI translatable operand. + if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + SmallVector GEPOps; + BasicBlock *CurBB = GEP->getParent(); + bool AnyChanged = false; + for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { + Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); + if (GEPOp == 0) return 0; + + AnyChanged = GEPOp != GEP->getOperand(i); + GEPOps.push_back(GEPOp); + } + + if (!AnyChanged) + return GEP; + + // Simplify the GEP to handle 'gep x, 0' -> x etc. + if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) + return V; + + // Scan to see if we have this GEP available. + Value *APHIOp = GEPOps[0]; + for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end(); + UI != E; ++UI) { + if (GetElementPtrInst *GEPI = dyn_cast(*UI)) + if (GEPI->getType() == GEP->getType() && + GEPI->getNumOperands() == GEPOps.size() && + GEPI->getParent()->getParent() == CurBB->getParent()) { + bool Mismatch = false; + for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) + if (GEPI->getOperand(i) != GEPOps[i]) { + Mismatch = true; + break; + } + if (!Mismatch) + return GEPI; + } + } + return 0; + } + + // Handle add with a constant RHS. + if (Inst->getOpcode() == Instruction::Add && + isa(Inst->getOperand(1))) { + // PHI translate the LHS. + Constant *RHS = cast(Inst->getOperand(1)); + bool isNSW = cast(Inst)->hasNoSignedWrap(); + bool isNUW = cast(Inst)->hasNoUnsignedWrap(); + + Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB); + if (LHS == 0) return 0; + + // If the PHI translated LHS is an add of a constant, fold the immediates. + if (BinaryOperator *BOp = dyn_cast(LHS)) + if (BOp->getOpcode() == Instruction::Add) + if (ConstantInt *CI = dyn_cast(BOp->getOperand(1))) { + LHS = BOp->getOperand(0); + RHS = ConstantExpr::getAdd(RHS, CI); + isNSW = isNUW = false; + } + + // See if the add simplifies away. + if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) + return Res; + + // Otherwise, see if we have this add available somewhere. + for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); + UI != E; ++UI) { + if (BinaryOperator *BO = dyn_cast(*UI)) + if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && + BO->getParent()->getParent() == CurBB->getParent()) + return BO; + } + + return 0; + } + + // Otherwise, we failed. + return 0; + } + + // Otherwise, it is defined in this block. It must be an input and must be + // phi translated. + assert(isInput && "Instruction defined in block must be an input"); + + + abort(); // unimplemented so far. } -/// GetAvailablePHITranslatePointer - Return the value computed by -/// PHITranslatePointer if it dominates PredBB, otherwise return null. + +/// PHITranslateValue - PHI translate the current address up the CFG from +/// CurBB to Pred, updating our state the reflect any needed changes. This +/// returns true on failure. +bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) { + Addr = PHITranslateSubExpr(Addr, CurBB, PredBB); + return Addr == 0; +} + +/// GetAvailablePHITranslatedSubExpr - Return the value computed by +/// PHITranslateSubExpr if it dominates PredBB, otherwise return null. Value *PHITransAddr:: -GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const { +GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB, + const DominatorTree &DT) { // See if PHI translation succeeds. - V = GetPHITranslatedValue(V, CurBB, PredBB, TD); - if (V == 0) return 0; + V = PHITranslateSubExpr(V, CurBB, PredBB); // Make sure the value is live in the predecessor. if (Instruction *Inst = dyn_cast_or_null(V)) @@ -51,21 +193,107 @@ return V; } + +/// PHITranslateWithInsertion - PHI translate this value into the specified +/// predecessor block, inserting a computation of the value if it is +/// unavailable. +/// +/// All newly created instructions are added to the NewInsts list. This +/// returns null on failure. +/// +Value *PHITransAddr:: +PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl &NewInsts) { + unsigned NISize = NewInsts.size(); + + // Attempt to PHI translate with insertion. + Addr = InsertPHITranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts); + + // If successful, return the new value. + if (Addr) return Addr; + + // If not, destroy any intermediate instructions inserted. + while (NewInsts.size() != NISize) + NewInsts.pop_back_val()->eraseFromParent(); + return 0; +} + + /// InsertPHITranslatedPointer - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// Value *PHITransAddr:: -InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB, - BasicBlock *PredBB, const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const { +InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl &NewInsts) { // See if we have a version of this value already available and dominating - // PredBB. If so, there is no need to insert a new copy. - if (Value *Res = GetAvailablePHITranslatedValue(InVal, CurBB, PredBB, TD, DT)) + // PredBB. If so, there is no need to insert a new instance of it. + if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT)) return Res; - // Not a great implementation. + // If we don't have an available version of this value, it must be an + // instruction. + Instruction *Inst = cast(InVal); + + // Handle bitcast of PHI translatable value. + if (BitCastInst *BC = dyn_cast(Inst)) { + Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + + // Otherwise insert a bitcast at the end of PredBB. + BitCastInst *New = new BitCastInst(OpVal, InVal->getType(), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + NewInsts.push_back(New); + return New; + } + + // Handle getelementptr with at least one PHI operand. + if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + SmallVector GEPOps; + BasicBlock *CurBB = GEP->getParent(); + for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { + Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + GEPOps.push_back(OpVal); + } + + GetElementPtrInst *Result = + GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + Result->setIsInBounds(GEP->isInBounds()); + NewInsts.push_back(Result); + return Result; + } + +#if 0 + // FIXME: This code works, but it is unclear that we actually want to insert + // a big chain of computation in order to make a value available in a block. + // This needs to be evaluated carefully to consider its cost trade offs. + + // Handle add with a constant RHS. + if (Inst->getOpcode() == Instruction::Add && + isa(Inst->getOperand(1))) { + // PHI translate the LHS. + Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + + BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + Res->setHasNoSignedWrap(cast(Inst)->hasNoSignedWrap()); + Res->setHasNoUnsignedWrap(cast(Inst)->hasNoUnsignedWrap()); + NewInsts.push_back(Res); + return Res; + } +#endif + return 0; } From clattner at apple.com Mon Dec 7 12:44:24 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 7 Dec 2009 10:44:24 -0800 Subject: [llvm-commits] [llvm] r90759 - in /llvm/trunk: include/llvm/CodeGen/MachineSSAUpdater.h lib/CodeGen/MachineSSAUpdater.cpp lib/CodeGen/TailDuplication.cpp In-Reply-To: References: <200912071015.nB7AFKWn029279@zion.cs.uiuc.edu> Message-ID: <7628453A-56D5-42E7-AA5C-7685618E54BB@apple.com> On Dec 7, 2009, at 10:08 AM, Evan Cheng wrote: >>> + if (I->second == OldReg) >>> + I->second = NewReg; >>> +} >> >> This scan can be *really* expensive: O(size of function). Would it >> be better to insert copies and then zap the copies at the end? > > I know it's expensive. But I have not identified a solution. > AvailableVals is the internal data structure tracking reaching > definition. I am not sure what you mean by inserting copies. This > function is called when it recognize the "cookie" phi instruction is > not needed. The idea of the 'cookie' is that it is almost never needed, this means that you'll be rescanning all the time. > Right now the pre-regalloc tail duplication pass is totally useless > anyway. It's severely pessmizing code. All the new PHI instructions > and copies are not being zapped. Ok, I'm not worried about it until you get to the point where you want to turn it on, we can talk about solutions at that point. -Chris From gohman at apple.com Mon Dec 7 13:04:31 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 07 Dec 2009 19:04:31 -0000 Subject: [llvm-commits] [llvm] r90781 - in /llvm/trunk: lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/2007-01-08-InstrSched.ll test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll test/CodeGen/X86/sink-hoist.ll test/CodeGen/X86/sse2.ll test/CodeGen/X86/sse3.ll test/CodeGen/X86/tail-opts.ll test/CodeGen/X86/tailcallstack64.ll test/CodeGen/X86/widen_arith-3.ll Message-ID: <200912071904.nB7J4W3D015692@zion.cs.uiuc.edu> Author: djg Date: Mon Dec 7 13:04:31 2009 New Revision: 90781 URL: http://llvm.org/viewvc/llvm-project?rev=90781&view=rev Log: Don't enable the post-RA scheduler on x86 except at -O3. In its current form, it is too expensive in compile time. Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll llvm/trunk/test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll llvm/trunk/test/CodeGen/X86/sink-hoist.ll llvm/trunk/test/CodeGen/X86/sse2.ll llvm/trunk/test/CodeGen/X86/sse3.ll llvm/trunk/test/CodeGen/X86/tail-opts.ll llvm/trunk/test/CodeGen/X86/tailcallstack64.ll llvm/trunk/test/CodeGen/X86/widen_arith-3.ll Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Mon Dec 7 13:04:31 2009 @@ -367,5 +367,5 @@ RegClassVector& CriticalPathRCs) const { Mode = TargetSubtarget::ANTIDEP_CRITICAL; CriticalPathRCs.clear(); - return OptLevel >= CodeGenOpt::Default; + return OptLevel >= CodeGenOpt::Aggressive; } Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-01-08-InstrSched.ll Mon Dec 7 13:04:31 2009 @@ -1,5 +1,5 @@ ; PR1075 -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin -O3 | FileCheck %s define float @foo(float %x) nounwind { %tmp1 = fmul float %x, 3.000000e+00 Modified: llvm/trunk/test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-09-19-SchedCustomLoweringBug.ll Mon Dec 7 13:04:31 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin10 | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin10 -post-RA-scheduler=true | FileCheck %s ; PR4958 Modified: llvm/trunk/test/CodeGen/X86/sink-hoist.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sink-hoist.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sink-hoist.ll (original) +++ llvm/trunk/test/CodeGen/X86/sink-hoist.ll Mon Dec 7 13:04:31 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 -asm-verbose=false -mtriple=x86_64-unknown-linux-gnu | FileCheck %s +; RUN: llc < %s -march=x86-64 -asm-verbose=false -mtriple=x86_64-unknown-linux-gnu -post-RA-scheduler=true | FileCheck %s ; Currently, floating-point selects are lowered to CFG triangles. ; This means that one side of the select is always unconditionally Modified: llvm/trunk/test/CodeGen/X86/sse2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse2.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse2.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse2.ll Mon Dec 7 13:04:31 2009 @@ -1,5 +1,5 @@ ; Tests for SSE2 and below, without SSE3+. -; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=pentium4 | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=pentium4 -O3 | FileCheck %s define void @t1(<2 x double>* %r, <2 x double>* %A, double %B) nounwind { %tmp3 = load <2 x double>* %A, align 16 Modified: llvm/trunk/test/CodeGen/X86/sse3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse3.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse3.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse3.ll Mon Dec 7 13:04:31 2009 @@ -1,6 +1,6 @@ ; These are tests for SSE3 codegen. Yonah has SSE3 and earlier but not SSSE3+. -; RUN: llc < %s -march=x86-64 -mcpu=yonah -mtriple=i686-apple-darwin9\ +; RUN: llc < %s -march=x86-64 -mcpu=yonah -mtriple=i686-apple-darwin9 -O3 \ ; RUN: | FileCheck %s --check-prefix=X64 ; Test for v8xi16 lowering where we extract the first element of the vector and Modified: llvm/trunk/test/CodeGen/X86/tail-opts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-opts.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tail-opts.ll (original) +++ llvm/trunk/test/CodeGen/X86/tail-opts.ll Mon Dec 7 13:04:31 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false | FileCheck %s +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false -post-RA-scheduler=true | FileCheck %s declare void @bar(i32) declare void @car(i32) Modified: llvm/trunk/test/CodeGen/X86/tailcallstack64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallstack64.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallstack64.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcallstack64.ll Mon Dec 7 13:04:31 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -tailcallopt -march=x86-64 | FileCheck %s +; RUN: llc < %s -tailcallopt -march=x86-64 -post-RA-scheduler=true | FileCheck %s ; Check that lowered arguments on the stack do not overwrite each other. ; Add %in1 %p1 to a different temporary register (%eax). Modified: llvm/trunk/test/CodeGen/X86/widen_arith-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/widen_arith-3.ll?rev=90781&r1=90780&r2=90781&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/widen_arith-3.ll (original) +++ llvm/trunk/test/CodeGen/X86/widen_arith-3.ll Mon Dec 7 13:04:31 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+sse42 -disable-mmx | FileCheck %s +; RUN: llc < %s -march=x86 -mattr=+sse42 -disable-mmx -post-RA-scheduler=true | FileCheck %s ; CHECK: paddw ; CHECK: pextrw ; CHECK: movd From sabre at nondot.org Mon Dec 7 13:04:49 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Dec 2009 19:04:49 -0000 Subject: [llvm-commits] [llvm] r90782 - /llvm/trunk/lib/Analysis/PHITransAddr.cpp Message-ID: <200912071904.nB7J4nsq015712@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 7 13:04:49 2009 New Revision: 90782 URL: http://llvm.org/viewvc/llvm-project?rev=90782&view=rev Log: add support for phi translation and incorpation of new expression. Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90782&r1=90781&r2=90782&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Mon Dec 7 13:04:49 2009 @@ -16,27 +16,32 @@ #include "llvm/Analysis/InstructionSimplify.h" using namespace llvm; -/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true -/// if we have some hope of doing it. This should be used as a filter to -/// avoid calling PHITranslateValue in hopeless situations. -bool PHITransAddr::IsPotentiallyPHITranslatable() const { - // If the input value is not an instruction, or if it is not defined in CurBB, - // then we don't need to phi translate it. - Instruction *Inst = dyn_cast(Addr); +static bool CanPHITrans(Instruction *Inst) { if (isa(Inst) || isa(Inst) || - isa(Inst) || - (Inst->getOpcode() == Instruction::And && - isa(Inst->getOperand(1)))) + isa(Inst)) return true; - + + if (Inst->getOpcode() == Instruction::And && + isa(Inst->getOperand(1))) + return true; + // cerr << "MEMDEP: Could not PHI translate: " << *Pointer; // if (isa(PtrInst) || isa(PtrInst)) // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); - return false; } +/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true +/// if we have some hope of doing it. This should be used as a filter to +/// avoid calling PHITranslateValue in hopeless situations. +bool PHITransAddr::IsPotentiallyPHITranslatable() const { + // If the input value is not an instruction, or if it is not defined in CurBB, + // then we don't need to phi translate it. + Instruction *Inst = dyn_cast(Addr); + return Inst == 0 || CanPHITrans(Inst); +} + Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB) { @@ -44,129 +49,147 @@ Instruction *Inst = dyn_cast(V); if (Inst == 0) return V; - // Determine whether 'Inst' is an input to our PHI translatable expression. - bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); - - // If 'Inst' is not defined in this block, it is either an input, or an - // intermediate result. - if (Inst->getParent() != CurBB) { - // If it is an input, then it remains an input. + // If 'Inst' is defined in this block, it must be an input that needs to be + // phi translated or an intermediate expression that needs to be incorporated + // into the expression. + if (Inst->getParent() == CurBB) { + assert(std::count(InstInputs.begin(), InstInputs.end(), Inst) && + "Not an input?"); + + // If this is a PHI, go ahead and translate it. + if (PHINode *PN = dyn_cast(Inst)) + return PN->getIncomingValueForBlock(PredBB); + + + // If this is a non-phi value, and it is analyzable, we can incorporate it + // into the expression by making all instruction operands be inputs. + if (!CanPHITrans(Inst)) + return 0; + + // Okay, we can incorporate it, this instruction is no longer an input. + InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst)); + + // All instruction operands are now inputs (and of course, they may also be + // defined in this block, so they may need to be phi translated themselves. + for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) + if (Instruction *Op = dyn_cast(Inst->getOperand(i))) + InstInputs.push_back(Op); + + } else { + // Determine whether 'Inst' is an input to our PHI translatable expression. + bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); + + // If it is an input defined in a different block, then it remains an input. if (isInput) return Inst; + } + + // Ok, it must be an intermediate result (either because it started that way + // or because we just incorporated it into the expression). See if its + // operands need to be phi translated, and if so, reconstruct it. - // Otherwise, it must be an intermediate result. See if its operands need - // to be phi translated, and if so, reconstruct it. + if (BitCastInst *BC = dyn_cast(Inst)) { + Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB); + if (PHIIn == 0) return 0; + if (PHIIn == BC->getOperand(0)) + return BC; - if (BitCastInst *BC = dyn_cast(Inst)) { - Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB); - if (PHIIn == 0) return 0; - if (PHIIn == BC->getOperand(0)) - return BC; - - // Find an available version of this cast. - - // Constants are trivial to find. - if (Constant *C = dyn_cast(PHIIn)) - return ConstantExpr::getBitCast(C, BC->getType()); + // Find an available version of this cast. + + // Constants are trivial to find. + if (Constant *C = dyn_cast(PHIIn)) + return ConstantExpr::getBitCast(C, BC->getType()); + + // Otherwise we have to see if a bitcasted version of the incoming pointer + // is available. If so, we can use it, otherwise we have to fail. + for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end(); + UI != E; ++UI) { + if (BitCastInst *BCI = dyn_cast(*UI)) + if (BCI->getType() == BC->getType()) + return BCI; + } + return 0; + } + + // Handle getelementptr with at least one PHI translatable operand. + if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + SmallVector GEPOps; + BasicBlock *CurBB = GEP->getParent(); + bool AnyChanged = false; + for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { + Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); + if (GEPOp == 0) return 0; - // Otherwise we have to see if a bitcasted version of the incoming pointer - // is available. If so, we can use it, otherwise we have to fail. - for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end(); - UI != E; ++UI) { - if (BitCastInst *BCI = dyn_cast(*UI)) - if (BCI->getType() == BC->getType()) - return BCI; - } - return 0; + AnyChanged = GEPOp != GEP->getOperand(i); + GEPOps.push_back(GEPOp); } - // Handle getelementptr with at least one PHI translatable operand. - if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - SmallVector GEPOps; - BasicBlock *CurBB = GEP->getParent(); - bool AnyChanged = false; - for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { - Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); - if (GEPOp == 0) return 0; - - AnyChanged = GEPOp != GEP->getOperand(i); - GEPOps.push_back(GEPOp); - } - - if (!AnyChanged) - return GEP; - - // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) - return V; - - // Scan to see if we have this GEP available. - Value *APHIOp = GEPOps[0]; - for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end(); - UI != E; ++UI) { - if (GetElementPtrInst *GEPI = dyn_cast(*UI)) - if (GEPI->getType() == GEP->getType() && - GEPI->getNumOperands() == GEPOps.size() && - GEPI->getParent()->getParent() == CurBB->getParent()) { - bool Mismatch = false; - for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) - if (GEPI->getOperand(i) != GEPOps[i]) { - Mismatch = true; - break; - } - if (!Mismatch) - return GEPI; - } - } - return 0; + if (!AnyChanged) + return GEP; + + // Simplify the GEP to handle 'gep x, 0' -> x etc. + if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) + return V; + + // Scan to see if we have this GEP available. + Value *APHIOp = GEPOps[0]; + for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end(); + UI != E; ++UI) { + if (GetElementPtrInst *GEPI = dyn_cast(*UI)) + if (GEPI->getType() == GEP->getType() && + GEPI->getNumOperands() == GEPOps.size() && + GEPI->getParent()->getParent() == CurBB->getParent()) { + bool Mismatch = false; + for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) + if (GEPI->getOperand(i) != GEPOps[i]) { + Mismatch = true; + break; + } + if (!Mismatch) + return GEPI; + } } + return 0; + } + + // Handle add with a constant RHS. + if (Inst->getOpcode() == Instruction::Add && + isa(Inst->getOperand(1))) { + // PHI translate the LHS. + Constant *RHS = cast(Inst->getOperand(1)); + bool isNSW = cast(Inst)->hasNoSignedWrap(); + bool isNUW = cast(Inst)->hasNoUnsignedWrap(); - // Handle add with a constant RHS. - if (Inst->getOpcode() == Instruction::Add && - isa(Inst->getOperand(1))) { - // PHI translate the LHS. - Constant *RHS = cast(Inst->getOperand(1)); - bool isNSW = cast(Inst)->hasNoSignedWrap(); - bool isNUW = cast(Inst)->hasNoUnsignedWrap(); - - Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB); - if (LHS == 0) return 0; - - // If the PHI translated LHS is an add of a constant, fold the immediates. - if (BinaryOperator *BOp = dyn_cast(LHS)) - if (BOp->getOpcode() == Instruction::Add) - if (ConstantInt *CI = dyn_cast(BOp->getOperand(1))) { - LHS = BOp->getOperand(0); - RHS = ConstantExpr::getAdd(RHS, CI); - isNSW = isNUW = false; - } - - // See if the add simplifies away. - if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) - return Res; - - // Otherwise, see if we have this add available somewhere. - for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); - UI != E; ++UI) { - if (BinaryOperator *BO = dyn_cast(*UI)) - if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && - BO->getParent()->getParent() == CurBB->getParent()) - return BO; - } - - return 0; + Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB); + if (LHS == 0) return 0; + + // If the PHI translated LHS is an add of a constant, fold the immediates. + if (BinaryOperator *BOp = dyn_cast(LHS)) + if (BOp->getOpcode() == Instruction::Add) + if (ConstantInt *CI = dyn_cast(BOp->getOperand(1))) { + LHS = BOp->getOperand(0); + RHS = ConstantExpr::getAdd(RHS, CI); + isNSW = isNUW = false; + } + + // See if the add simplifies away. + if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) + return Res; + + // Otherwise, see if we have this add available somewhere. + for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); + UI != E; ++UI) { + if (BinaryOperator *BO = dyn_cast(*UI)) + if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && + BO->getParent()->getParent() == CurBB->getParent()) + return BO; } - // Otherwise, we failed. return 0; } - - // Otherwise, it is defined in this block. It must be an input and must be - // phi translated. - assert(isInput && "Instruction defined in block must be an input"); - - abort(); // unimplemented so far. + // Otherwise, we failed. + return 0; } From foldr at codedgers.com Mon Dec 7 13:15:57 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 19:15:57 -0000 Subject: [llvm-commits] [llvm] r90784 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200912071915.nB7JFwsN016142@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 13:15:57 2009 New Revision: 90784 URL: http://llvm.org/viewvc/llvm-project?rev=90784&view=rev Log: Throw 'const char*' instead of 'std::string'. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=90784&r1=90783&r2=90784&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Dec 7 13:15:57 2009 @@ -796,8 +796,7 @@ Init* Case = d->getArg(0); if (typeid(*Case) != typeid(DagInit) || GetOperatorName(static_cast(Case)) != "case") - throw - std::string("The argument to (actions) should be a 'case' construct!"); + throw "The argument to (actions) should be a 'case' construct!"; toolDesc_.Actions = Case; } @@ -898,8 +897,8 @@ priority = static_cast((*B)->getValueAsInt("priority")); if (++B != E) - throw std::string("More than one 'PluginPriority' instance found: " - "most probably an error!"); + throw "More than one 'PluginPriority' instance found: " + "most probably an error!"; } return priority; @@ -990,7 +989,7 @@ } if (NodeB == "root") - throw std::string("Edges back to the root are not allowed!"); + throw "Edges back to the root are not allowed!"; } } @@ -1010,7 +1009,7 @@ // Error checks. if (GetOperatorName(d) != "case") - throw std::string("WalkCase should be invoked only on 'case' expressions!"); + throw "WalkCase should be invoked only on 'case' expressions!"; if (d.getNumArgs() < 2) throw "There should be at least one clause in the 'case' expression:\n" @@ -1030,8 +1029,8 @@ const DagInit& Test = InitPtrToDag(arg); if (GetOperatorName(Test) == "default" && (i+1 != numArgs)) - throw std::string("The 'default' clause should be the last in the" - "'case' construct!"); + throw "The 'default' clause should be the last in the " + "'case' construct!"; if (i == numArgs) throw "Case construct handler: no corresponding action " "found for the test " + Test.getAsString() + '!'; @@ -1551,7 +1550,7 @@ const std::string& CmdName = *Pos; if (CmdName == ")") - throw std::string("$CALL invocation: empty argument list!"); + throw "$CALL invocation: empty argument list!"; O << "hooks::"; O << CmdName << "("; @@ -1746,7 +1745,7 @@ break; case OptionType::Alias: default: - throw std::string("Aliases are not allowed in tool option descriptions!"); + throw "Aliases are not allowed in tool option descriptions!"; } } @@ -2330,7 +2329,7 @@ ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map"); if (!LangsToSuffixesList) - throw std::string("Error in the language map definition!"); + throw "Error in the language map definition!"; for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) { const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i); From foldr at codedgers.com Mon Dec 7 13:16:13 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 07 Dec 2009 19:16:13 -0000 Subject: [llvm-commits] [llvm] r90785 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200912071916.nB7JGDr5016161@zion.cs.uiuc.edu> Author: foldr Date: Mon Dec 7 13:16:13 2009 New Revision: 90785 URL: http://llvm.org/viewvc/llvm-project?rev=90785&view=rev Log: Simplify a bit. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=90785&r1=90784&r2=90785&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Dec 7 13:16:13 2009 @@ -1823,20 +1823,17 @@ { checkNumberOfArguments(&Dag, 1); const std::string& Name = InitPtrToString(Dag.getArg(0)); - const OptionDescription& D = OptDescs.FindOption(Name); + const OptionDescription& D = OptDescs.FindListOrParameter(Name); if (D.isParameter()) { O.indent(IndentLevel) << "vec.push_back(" << D.GenVariableName() << ");\n"; } - else if (D.isList()) { + else { O.indent(IndentLevel) << "std::copy(" << D.GenVariableName() << ".begin(), " << D.GenVariableName() << ".end(), std::back_inserter(vec));\n"; } - else { - throw "'forward_value' used with a switch or an alias!"; - } } void onForwardTransformedValue (const DagInit& Dag, @@ -1845,15 +1842,10 @@ checkNumberOfArguments(&Dag, 2); const std::string& Name = InitPtrToString(Dag.getArg(0)); const std::string& Hook = InitPtrToString(Dag.getArg(1)); - const OptionDescription& D = OptDescs.FindOption(Name); + const OptionDescription& D = OptDescs.FindListOrParameter(Name); - if (D.isParameter() || D.isList()) { - O.indent(IndentLevel) << "vec.push_back(" << "hooks::" - << Hook << "(" << D.GenVariableName() << "));\n"; - } - else { - throw "'forward_transformed_value' used with a switch or an alias!"; - } + O.indent(IndentLevel) << "vec.push_back(" << "hooks::" + << Hook << "(" << D.GenVariableName() << "));\n"; } From evan.cheng at apple.com Mon Dec 7 13:23:25 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 19:23:25 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r90787 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200912071923.nB7JNPg4016456@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 13:23:24 2009 New Revision: 90787 URL: http://llvm.org/viewvc/llvm-project?rev=90787&view=rev Log: Set alignment on bitfield access. Patch by Chris Lattner. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=90787&r1=90786&r2=90787&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Dec 7 13:23:24 2009 @@ -6734,9 +6734,9 @@ // Okay, everything is good. Return this as a bitfield if we can't // return it as a normal l-value. (e.g. "struct X { int X : 32 };" ). - // Conservatively return LValue with alignment 1. if (BitfieldSize != LLVMValueBitSize || BitStart != 0) - return LValue(FieldPtr, 1, BitStart, BitfieldSize); + return LValue(FieldPtr, LVAlign, BitStart, BitfieldSize); + } else { // Make sure we return a pointer to the right type. const Type *EltTy = ConvertType(TREE_TYPE(exp)); From vhernandez at apple.com Mon Dec 7 13:36:34 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 07 Dec 2009 19:36:34 -0000 Subject: [llvm-commits] [llvm] r90788 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/IntrinsicInst.h include/llvm/Intrinsics.td lib/Analysis/DebugInfo.cpp Message-ID: <200912071936.nB7JaZDe016960@zion.cs.uiuc.edu> Author: hernande Date: Mon Dec 7 13:36:34 2009 New Revision: 90788 URL: http://llvm.org/viewvc/llvm-project?rev=90788&view=rev Log: Introduce the "@llvm.dbg.value" debug intrinsic. The semantics of llvm.dbg.value are that starting from where it is executed, an offset into the specified user source variable is specified to get a new value. An example: call void @llvm.dbg.value(metadata !{ i32 7 }, i64 0, metadata !2) Here the user source variable associated with metadata #2 gets the value "i32 7" at offset 0. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/include/llvm/IntrinsicInst.h llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90788&r1=90787&r2=90788&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Dec 7 13:36:34 2009 @@ -492,6 +492,7 @@ const Type *EmptyStructPtr; // "{}*". Function *DeclareFn; // llvm.dbg.declare + Function *ValueFn; // llvm.dbg.value DIFactory(const DIFactory &); // DO NOT IMPLEMENT void operator=(const DIFactory&); // DO NOT IMPLEMENT @@ -639,6 +640,13 @@ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, Instruction *InsertBefore); + /// InsertValue - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, + DIVariable D, BasicBlock *InsertAtEnd); + + /// InsertValue - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, + DIVariable D, Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); }; Modified: llvm/trunk/include/llvm/IntrinsicInst.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicInst.h?rev=90788&r1=90787&r2=90788&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicInst.h (original) +++ llvm/trunk/include/llvm/IntrinsicInst.h Mon Dec 7 13:36:34 2009 @@ -70,6 +70,7 @@ case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_end: case Intrinsic::dbg_declare: + case Intrinsic::dbg_value: return true; default: return false; } @@ -171,6 +172,25 @@ } }; + /// DbgValueInst - This represents the llvm.dbg.value instruction. + /// + struct DbgValueInst : public DbgInfoIntrinsic { + Value *getValue() const { + return cast(getOperand(1))->getElement(0); + } + Value *getOffset() const { return getOperand(2); } + MDNode *getVariable() const { return cast(getOperand(3)); } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const DbgValueInst *) { return true; } + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::dbg_value; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. /// struct MemIntrinsic : public IntrinsicInst { Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=90788&r1=90787&r2=90788&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Mon Dec 7 13:36:34 2009 @@ -290,6 +290,9 @@ def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; def int_dbg_declare : Intrinsic<[llvm_void_ty], [llvm_descriptor_ty, llvm_metadata_ty]>; + def int_dbg_value : Intrinsic<[llvm_void_ty], + [llvm_metadata_ty, llvm_i64_ty, + llvm_metadata_ty]>; } //===------------------ Exception Handling Intrinsics----------------------===// Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=90788&r1=90787&r2=90788&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Dec 7 13:36:34 2009 @@ -1050,6 +1050,35 @@ return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); } +/// InsertValue - Insert a new llvm.dbg.value intrinsic call. +Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D, + Instruction *InsertBefore) { + assert(V && "no value passed to dbg.value"); + assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && + "offset must be i64"); + if (!ValueFn) + ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); + + Value *Elts[] = { V }; + Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset, + D.getNode() }; + return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore); +} + +/// InsertValue - Insert a new llvm.dbg.value intrinsic call. +Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D, + BasicBlock *InsertAtEnd) { + assert(V && "no value passed to dbg.value"); + assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && + "offset must be i64"); + if (!ValueFn) + ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); + + Value *Elts[] = { V }; + Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset, + D.getNode() }; + return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd); +} //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. From gohman at apple.com Mon Dec 7 13:38:26 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 07 Dec 2009 19:38:26 -0000 Subject: [llvm-commits] [llvm] r90789 - /llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Message-ID: <200912071938.nB7JcQ3w017023@zion.cs.uiuc.edu> Author: djg Date: Mon Dec 7 13:38:26 2009 New Revision: 90789 URL: http://llvm.org/viewvc/llvm-project?rev=90789&view=rev Log: Apply Pekka J??skel?inen's patch to raise the first virtual register number in order to accomodate targets with more than 1024 registers. Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=90789&r1=90788&r2=90789&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Mon Dec 7 13:38:26 2009 @@ -299,8 +299,8 @@ /// FirstVirtualRegister - This is the first register number that is /// considered to be a 'virtual' register, which is part of the SSA /// namespace. This must be the same for all targets, which means that each - /// target is limited to 1024 registers. - FirstVirtualRegister = 1024 + /// target is limited to this fixed number of registers. + FirstVirtualRegister = 16384 }; /// isPhysicalRegister - Return true if the specified register number is in From greened at obbligato.org Mon Dec 7 13:40:27 2009 From: greened at obbligato.org (David Greene) Date: Mon, 07 Dec 2009 19:40:27 -0000 Subject: [llvm-commits] [llvm] r90790 - /llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll Message-ID: <200912071940.nB7JeRLX017092@zion.cs.uiuc.edu> Author: greened Date: Mon Dec 7 13:40:26 2009 New Revision: 90790 URL: http://llvm.org/viewvc/llvm-project?rev=90790&view=rev Log: Use FileCheck and set nounwind on calls. Modified: llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll Modified: llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll?rev=90790&r1=90789&r2=90790&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll (original) +++ llvm/trunk/test/CodeGen/X86/2009-09-10-SpillComments.ll Mon Dec 7 13:40:26 2009 @@ -1,6 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-unknown-linux | grep "Spill" -; RUN: llc < %s -mtriple=x86_64-unknown-linux | grep "Folded Spill" -; RUN: llc < %s -mtriple=x86_64-unknown-linux | grep "Reload" +; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s %struct..0anon = type { i32 } %struct.rtvec_def = type { i32, [1 x %struct..0anon] } @@ -12,6 +10,9 @@ define %struct.rtx_def* @walk_fixup_memory_subreg(%struct.rtx_def* %x, %struct.rtx_def* %insn) { entry: +; CHECK: Spill +; CHECK: Folded Spill +; CHECK: Reload %tmp2 = icmp eq %struct.rtx_def* %x, null ; [#uses=1] br i1 %tmp2, label %UnifiedReturnBlock, label %cond_next @@ -32,7 +33,7 @@ br i1 %tmp22, label %cond_true25, label %cond_next32 cond_true25: ; preds = %cond_true13 - %tmp29 = tail call %struct.rtx_def* @fixup_memory_subreg( %struct.rtx_def* %x, %struct.rtx_def* %insn, i32 1 ) ; <%struct.rtx_def*> [#uses=1] + %tmp29 = tail call %struct.rtx_def* @fixup_memory_subreg( %struct.rtx_def* %x, %struct.rtx_def* %insn, i32 1 ) nounwind ; <%struct.rtx_def*> [#uses=1] ret %struct.rtx_def* %tmp29 cond_next32: ; preds = %cond_true13, %cond_next @@ -58,7 +59,7 @@ %tmp52 = getelementptr %struct.rtx_def* %x, i32 0, i32 3, i32 %i.01.0 ; <%struct..0anon*> [#uses=1] %tmp5354 = bitcast %struct..0anon* %tmp52 to %struct.rtx_def** ; <%struct.rtx_def**> [#uses=1] %tmp55 = load %struct.rtx_def** %tmp5354 ; <%struct.rtx_def*> [#uses=1] - %tmp58 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp55, %struct.rtx_def* %insn ) ; <%struct.rtx_def*> [#uses=1] + %tmp58 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp55, %struct.rtx_def* %insn ) nounwind ; <%struct.rtx_def*> [#uses=1] %tmp62 = getelementptr %struct.rtx_def* %x, i32 0, i32 3, i32 %i.01.0, i32 0 ; [#uses=1] %tmp58.c = ptrtoint %struct.rtx_def* %tmp58 to i32 ; [#uses=1] store i32 %tmp58.c, i32* %tmp62 @@ -81,7 +82,7 @@ %tmp92 = getelementptr %struct.rtvec_def* %tmp81, i32 0, i32 1, i32 %j.019 ; <%struct..0anon*> [#uses=1] %tmp9394 = bitcast %struct..0anon* %tmp92 to %struct.rtx_def** ; <%struct.rtx_def**> [#uses=1] %tmp95 = load %struct.rtx_def** %tmp9394 ; <%struct.rtx_def*> [#uses=1] - %tmp98 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp95, %struct.rtx_def* %insn ) ; <%struct.rtx_def*> [#uses=1] + %tmp98 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp95, %struct.rtx_def* %insn ) nounwind ; <%struct.rtx_def*> [#uses=1] %tmp101 = getelementptr %struct.rtvec_def* %tmp81, i32 0, i32 1, i32 %j.019, i32 0 ; [#uses=1] %tmp98.c = ptrtoint %struct.rtx_def* %tmp98 to i32 ; [#uses=1] store i32 %tmp98.c, i32* %tmp101 From evan.cheng at apple.com Mon Dec 7 13:42:22 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 19:42:22 -0000 Subject: [llvm-commits] [llvm] r90791 - /llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c Message-ID: <200912071942.nB7JgMsX017152@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 13:42:22 2009 New Revision: 90791 URL: http://llvm.org/viewvc/llvm-project?rev=90791&view=rev Log: Test case for 90787. Added: llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c Added: llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c?rev=90791&view=auto ============================================================================== --- llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c (added) +++ llvm/trunk/test/FrontendC/2009-12-07-BitFieldAlignment.c Mon Dec 7 13:42:22 2009 @@ -0,0 +1,15 @@ +// RUN: %llvmgcc -m32 %s -S -o - | FileCheck %s +// Set alignment on bitfield accesses. + +struct S { + int a, b; + void *c; + unsigned d : 8; + unsigned e : 8; +}; + +void f0(struct S *a) { +// CHECK: %3 = load i32* %2, align 4 +// CHECK: store i32 %4, i32* %2, align 4 + a->e = 0; +} From sabre at nondot.org Mon Dec 7 13:45:30 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Dec 2009 19:45:30 -0000 Subject: [llvm-commits] [llvm] r90792 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912071945.nB7JjUFS017262@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 7 13:45:30 2009 New Revision: 90792 URL: http://llvm.org/viewvc/llvm-project?rev=90792&view=rev Log: add accessor, improve comment. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90792&r1=90791&r2=90792&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Mon Dec 7 13:45:30 2009 @@ -47,6 +47,8 @@ InstInputs.push_back(I); } + Value *getAddr() const { return Addr; } + /// NeedsPHITranslationFromBlock - Return true if moving from the specified /// BasicBlock to its predecessors requires PHI translation. bool NeedsPHITranslationFromBlock(BasicBlock *BB) const { @@ -65,7 +67,7 @@ /// PHITranslateValue - PHI translate the current address up the CFG from /// CurBB to Pred, updating our state the reflect any needed changes. This - /// returns true on failure. + /// returns true on failure and sets Addr to null. bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); /// PHITranslateWithInsertion - PHI translate this value into the specified Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90792&r1=90791&r2=90792&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Mon Dec 7 13:45:30 2009 @@ -195,7 +195,7 @@ /// PHITranslateValue - PHI translate the current address up the CFG from /// CurBB to Pred, updating our state the reflect any needed changes. This -/// returns true on failure. +/// returns true on failure and sets Addr to null. bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) { Addr = PHITranslateSubExpr(Addr, CurBB, PredBB); return Addr == 0; From jyasskin at google.com Mon Dec 7 13:52:10 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 7 Dec 2009 11:52:10 -0800 Subject: [llvm-commits] [PATCH] New external2availableexternally pass (issue166075) In-Reply-To: <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> References: <00163691fbf3bc89a9047a032500@google.com> <4B1B6CEA.9060306@free.fr> <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> Message-ID: Anyone have comments? On Sun, Dec 6, 2009 at 2:32 AM, Jeffrey Yasskin wrote: > On Sun, Dec 6, 2009 at 12:35 AM, Duncan Sands wrote: >> Hi, >> >>> When we have a runtime library, it's useful to expose that library to >>> the optimizers, but it's bad to ask LLVM to actually codegen the >>> library's code a second time. >> >> I didn't look at the code, but it sounds like it gives functions >> available_externally linkage. > > Yes. > >>?Why not have the front-end output >> the functions with available_externally linkage in the first place? > > 1. I knew how to write this pass; modifying clang would have required > learning more. > 2. It seems useful to be able to compile the runtime library to .bc > with external functions, codegen the .o from that for the real runtime > library, and then convert it to the available_externally form for use > by application optimizers and JITs. A front-end flag would require > compiling from C twice. > 3. dgregor endorsed the idea of this patch, although I didn't mention > the possibility of a clang flag. > > But let me know if an extra clang flag would be preferable. I'll > probably wind up writing a standalone tool for Unladen instead of > shaving that yak, but I wouldn't object strongly to dropping this > patch. > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Mon Dec 7 13:52:57 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 07 Dec 2009 19:52:57 -0000 Subject: [llvm-commits] [llvm] r90793 - /llvm/trunk/lib/Analysis/PHITransAddr.cpp Message-ID: <200912071952.nB7JqvMT017582@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 7 13:52:57 2009 New Revision: 90793 URL: http://llvm.org/viewvc/llvm-project?rev=90793&view=rev Log: fix typo Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90793&r1=90792&r2=90793&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Mon Dec 7 13:52:57 2009 @@ -120,7 +120,7 @@ Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); if (GEPOp == 0) return 0; - AnyChanged = GEPOp != GEP->getOperand(i); + AnyChanged |= GEPOp != GEP->getOperand(i); GEPOps.push_back(GEPOp); } From devang.patel at gmail.com Mon Dec 7 13:54:07 2009 From: devang.patel at gmail.com (Devang Patel) Date: Mon, 7 Dec 2009 11:54:07 -0800 Subject: [llvm-commits] [llvm] r90788 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h include/llvm/IntrinsicInst.h include/llvm/Intrinsics.td lib/Analysis/DebugInfo.cpp In-Reply-To: <200912071936.nB7JaZDe016960@zion.cs.uiuc.edu> References: <200912071936.nB7JaZDe016960@zion.cs.uiuc.edu> Message-ID: <352a1fb20912071154j3394cec7j2cff8106201abd2c@mail.gmail.com> Hi Victor, On Mon, Dec 7, 2009 at 11:36 AM, Victor Hernandez wrote: > Author: hernande > Date: Mon Dec ?7 13:36:34 2009 > New Revision: 90788 > > URL: http://llvm.org/viewvc/llvm-project?rev=90788&view=rev > Log: > Introduce the "@llvm.dbg.value" debug intrinsic. > > The semantics of llvm.dbg.value are that starting from where it is executed, an offset into the specified user source variable is specified to get a new value. > > An example: > ?call void @llvm.dbg.value(metadata !{ i32 7 }, i64 0, metadata !2) > Here the user source variable associated with metadata #2 gets the value "i32 7" at offset 0. > > > Modified: > ? ?llvm/trunk/include/llvm/Analysis/DebugInfo.h > ? ?llvm/trunk/include/llvm/IntrinsicInst.h > ? ?llvm/trunk/include/llvm/Intrinsics.td > ? ?llvm/trunk/lib/Analysis/DebugInfo.cpp > > Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90788&r1=90787&r2=90788&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) > +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Dec ?7 13:36:34 2009 > @@ -492,6 +492,7 @@ > > ? ? const Type *EmptyStructPtr; // "{}*". > ? ? Function *DeclareFn; ? ? // llvm.dbg.declare > + ? ?Function *ValueFn; ? ? ? // llvm.dbg.value > > ? ? DIFactory(const DIFactory &); ? ? // DO NOT IMPLEMENT > ? ? void operator=(const DIFactory&); // DO NOT IMPLEMENT > @@ -639,6 +640,13 @@ > ? ? Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Instruction *InsertBefore); > > + ? ?/// InsertValue - Insert a new llvm.dbg.value intrinsic call. > + ? ?Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? DIVariable D, BasicBlock *InsertAtEnd); > + > + ? ?/// InsertValue - Insert a new llvm.dbg.value intrinsic call. > + ? ?Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? DIVariable D, Instruction *InsertBefore); Here Value is overloaded term. Pl. rename this as InsertDbgValueIntrinsic to clarify what this DebugInfo API is doing. Thanks, - Devang From eli.friedman at gmail.com Mon Dec 7 14:15:34 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 7 Dec 2009 12:15:34 -0800 Subject: [llvm-commits] [PATCH] New external2availableexternally pass (issue166075) In-Reply-To: References: <00163691fbf3bc89a9047a032500@google.com> <4B1B6CEA.9060306@free.fr> <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> Message-ID: On Mon, Dec 7, 2009 at 11:52 AM, Jeffrey Yasskin wrote: > Anyone have comments? I don't see any issues with the code. -Eli From baldrick at free.fr Mon Dec 7 14:56:27 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 20:56:27 -0000 Subject: [llvm-commits] [dragonegg] r90802 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912072056.nB7KuRgj020397@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 14:56:27 2009 New Revision: 90802 URL: http://llvm.org/viewvc/llvm-project?rev=90802&view=rev Log: Seperate the thunk handling from alias handling. For the moment just abort when a thunk is seen. Move alias emission closer to where it is used. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90802&r1=90801&r2=90802&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Mon Dec 7 14:56:27 2009 @@ -831,97 +831,6 @@ Array, Name); } -/// emit_alias_to_llvm - Given decl and target emit alias to target. -void emit_alias_to_llvm(tree decl, tree target) { - // Get or create LLVM global for our alias. - GlobalValue *V = cast(DECL_LLVM(decl)); - - GlobalValue *Aliasee; - - if (TREE_CODE(target) == IDENTIFIER_NODE) { - // This is something insane. Probably only LTHUNKs can be here - // Try to grab decl from IDENTIFIER_NODE - - // Query SymTab for aliasee - const char* AliaseeName = IDENTIFIER_POINTER(target); - Aliasee = - dyn_cast_or_null(TheModule-> - getValueSymbolTable().lookup(AliaseeName)); - - // Last resort. Query for name set via __asm__ - if (!Aliasee) { - std::string starred = std::string("\001") + AliaseeName; - Aliasee = - dyn_cast_or_null(TheModule-> - getValueSymbolTable().lookup(starred)); - } - - if (!Aliasee) { - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { - if (GlobalVariable *GV = dyn_cast(V)) - Aliasee = new GlobalVariable(*TheModule, GV->getType(), - GV->isConstant(), - GlobalVariable::ExternalWeakLinkage, - NULL, AliaseeName); - else if (Function *F = dyn_cast(V)) - Aliasee = Function::Create(F->getFunctionType(), - Function::ExternalWeakLinkage, - AliaseeName, TheModule); - else - assert(0 && "Unsuported global value"); - } else { - error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); - return; - } - } - } else { - Aliasee = cast(DECL_LLVM(target)); - } - - GlobalValue::LinkageTypes Linkage; - - // A weak alias has TREE_PUBLIC set but not the other bits. - if (false)//FIXME DECL_LLVM_PRIVATE(decl)) - Linkage = GlobalValue::PrivateLinkage; - else if (false)//FIXME DECL_LLVM_LINKER_PRIVATE(decl)) - Linkage = GlobalValue::LinkerPrivateLinkage; - else if (DECL_WEAK(decl)) - // The user may have explicitly asked for weak linkage - ignore flag_odr. - Linkage = GlobalValue::WeakAnyLinkage; - else if (!TREE_PUBLIC(decl)) - Linkage = GlobalValue::InternalLinkage; - else - Linkage = GlobalValue::ExternalLinkage; - - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", - Aliasee, TheModule); - - handleVisibility(decl, GA); - - if (GA->getType()->canLosslesslyBitCastTo(V->getType())) - V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType())); - else if (!V->use_empty()) { - error ("%J Alias %qD used with invalid type!", decl, decl); - return; - } - - changeLLVMConstant(V, GA); - GA->takeName(V); - if (GlobalVariable *GV = dyn_cast(V)) - GV->eraseFromParent(); - else if (GlobalAlias *GA = dyn_cast(V)) - GA->eraseFromParent(); - else if (Function *F = dyn_cast(V)) - F->eraseFromParent(); - else - assert(0 && "Unsuported global value"); - - // Mark the alias as written so gcc doesn't waste time outputting it. - TREE_ASM_WRITTEN(decl) = 1; - - return; -} - /// ConvertMetadataStringToGV - Convert string to global value. Use existing /// global if possible. Constant* ConvertMetadataStringToGV(const char *str) { @@ -1717,13 +1626,100 @@ pop_cfun (); } -/// emit_same_body_alias - Turn a same-body alias or thunk into LLVM IR. Here -/// alias is a function which has the some body as node. -static void emit_same_body_alias(struct cgraph_node *alias, - struct cgraph_node *node) { - // TODO: The cgraph node contains all kinds of interesting information about - // linkage and visibility - should maybe make use of it? - emit_alias_to_llvm(alias->decl, node->decl); +/// emit_thunk_to_llvm - Turn a thunk into LLVM IR. +void emit_thunk_to_llvm(struct cgraph_node *thunk) { + abort(); + // Mark the thunk as written so gcc doesn't waste time outputting it. + TREE_ASM_WRITTEN(thunk->decl) = 1; +} + +/// emit_alias_to_llvm - Given decl and target emit alias to target. +void emit_alias_to_llvm(tree decl, tree target) { + // Get or create LLVM global for our alias. + GlobalValue *V = cast(DECL_LLVM(decl)); + + GlobalValue *Aliasee; + + if (TREE_CODE(target) == IDENTIFIER_NODE) { + // This is something insane. Probably only LTHUNKs can be here + // Try to grab decl from IDENTIFIER_NODE + + // Query SymTab for aliasee + const char* AliaseeName = IDENTIFIER_POINTER(target); + Aliasee = + dyn_cast_or_null(TheModule-> + getValueSymbolTable().lookup(AliaseeName)); + + // Last resort. Query for name set via __asm__ + if (!Aliasee) { + std::string starred = std::string("\001") + AliaseeName; + Aliasee = + dyn_cast_or_null(TheModule-> + getValueSymbolTable().lookup(starred)); + } + + if (!Aliasee) { + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { + if (GlobalVariable *GV = dyn_cast(V)) + Aliasee = new GlobalVariable(*TheModule, GV->getType(), + GV->isConstant(), + GlobalVariable::ExternalWeakLinkage, + NULL, AliaseeName); + else if (Function *F = dyn_cast(V)) + Aliasee = Function::Create(F->getFunctionType(), + Function::ExternalWeakLinkage, + AliaseeName, TheModule); + else + assert(0 && "Unsuported global value"); + } else { + error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); + return; + } + } + } else { + Aliasee = cast(DECL_LLVM(target)); + } + + GlobalValue::LinkageTypes Linkage; + + // A weak alias has TREE_PUBLIC set but not the other bits. + if (false)//FIXME DECL_LLVM_PRIVATE(decl)) + Linkage = GlobalValue::PrivateLinkage; + else if (false)//FIXME DECL_LLVM_LINKER_PRIVATE(decl)) + Linkage = GlobalValue::LinkerPrivateLinkage; + else if (DECL_WEAK(decl)) + // The user may have explicitly asked for weak linkage - ignore flag_odr. + Linkage = GlobalValue::WeakAnyLinkage; + else if (!TREE_PUBLIC(decl)) + Linkage = GlobalValue::InternalLinkage; + else + Linkage = GlobalValue::ExternalLinkage; + + GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", + Aliasee, TheModule); + + handleVisibility(decl, GA); + + if (GA->getType()->canLosslesslyBitCastTo(V->getType())) + V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType())); + else if (!V->use_empty()) { + error ("%J Alias %qD used with invalid type!", decl, decl); + return; + } + + changeLLVMConstant(V, GA); + GA->takeName(V); + if (GlobalVariable *GV = dyn_cast(V)) + GV->eraseFromParent(); + else if (GlobalAlias *GA = dyn_cast(V)) + GA->eraseFromParent(); + else if (Function *F = dyn_cast(V)) + F->eraseFromParent(); + else + assert(0 && "Unsuported global value"); + + // Mark the alias as written so gcc doesn't waste time outputting it. + TREE_ASM_WRITTEN(decl) = 1; } /// emit_functions - Turn all functions in the compilation unit into LLVM IR. @@ -1741,7 +1737,12 @@ // Output any same-body aliases or thunks. for (struct cgraph_node *alias = node->same_body; alias; alias = alias->next) - emit_same_body_alias(alias, node); + if (alias->thunk.thunk_p) { + emit_thunk_to_llvm(alias); + } else { + assert(alias->thunk.alias == node->decl && "Unexpected alias target!"); + emit_alias_to_llvm(alias->decl, node->decl); + } } } From clattner at apple.com Mon Dec 7 14:59:07 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 7 Dec 2009 12:59:07 -0800 Subject: [llvm-commits] [PATCH] New external2availableexternally pass (issue166075) In-Reply-To: References: <00163691fbf3bc89a9047a032500@google.com> <4B1B6CEA.9060306@free.fr> <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> Message-ID: <6B7FD070-E63E-4612-B088-74DEE2C4AEC6@apple.com> On Dec 7, 2009, at 11:52 AM, Jeffrey Yasskin wrote: > Anyone have comments? Who are the expected clients of this? It seems pretty special purpose to go into mainline. -Chris > On Sun, Dec 6, 2009 at 2:32 AM, Jeffrey Yasskin wrote: >> On Sun, Dec 6, 2009 at 12:35 AM, Duncan Sands wrote: >>> Hi, >>> >>>> When we have a runtime library, it's useful to expose that library to >>>> the optimizers, but it's bad to ask LLVM to actually codegen the >>>> library's code a second time. >>> >>> I didn't look at the code, but it sounds like it gives functions >>> available_externally linkage. >> >> Yes. >> >>> Why not have the front-end output >>> the functions with available_externally linkage in the first place? >> >> 1. I knew how to write this pass; modifying clang would have required >> learning more. >> 2. It seems useful to be able to compile the runtime library to .bc >> with external functions, codegen the .o from that for the real runtime >> library, and then convert it to the available_externally form for use >> by application optimizers and JITs. A front-end flag would require >> compiling from C twice. >> 3. dgregor endorsed the idea of this patch, although I didn't mention >> the possibility of a clang flag. >> >> But let me know if an extra clang flag would be preferable. I'll >> probably wind up writing a standalone tool for Unladen instead of >> shaving that yak, but I wouldn't object strongly to dropping this >> patch. >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From jyasskin at google.com Mon Dec 7 15:06:08 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 7 Dec 2009 13:06:08 -0800 Subject: [llvm-commits] [PATCH] New external2availableexternally pass (issue166075) In-Reply-To: <6B7FD070-E63E-4612-B088-74DEE2C4AEC6@apple.com> References: <00163691fbf3bc89a9047a032500@google.com> <4B1B6CEA.9060306@free.fr> <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> <6B7FD070-E63E-4612-B088-74DEE2C4AEC6@apple.com> Message-ID: On Mon, Dec 7, 2009 at 12:59 PM, Chris Lattner wrote: > > On Dec 7, 2009, at 11:52 AM, Jeffrey Yasskin wrote: > >> Anyone have comments? > > Who are the expected clients of this? ?It seems pretty special purpose to go into mainline. People writing JITs are likely to use it to provide definitions of their runtime library functions. Static compilers could use it too if they ship with a compiled runtime but also want to be able to inline bits of the runtime into their output, without making those bits builtins. From baldrick at free.fr Mon Dec 7 15:16:50 2009 From: baldrick at free.fr (Duncan Sands) Date: Mon, 07 Dec 2009 21:16:50 -0000 Subject: [llvm-commits] [dragonegg] r90803 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912072116.nB7LGoqL021341@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 7 15:16:50 2009 New Revision: 90803 URL: http://llvm.org/viewvc/llvm-project?rev=90803&view=rev Log: Output aliases and thunks in the order they were created, which means the reverse of the order they occur in the list. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90803&r1=90802&r2=90803&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Mon Dec 7 15:16:50 2009 @@ -1734,15 +1734,19 @@ struct cgraph_node *node = csi_node(csi); if (node->analyzed && Visited.insert(node->decl)) emit_function(node); - // Output any same-body aliases or thunks. - for (struct cgraph_node *alias = node->same_body; alias; - alias = alias->next) + + // Output any same-body aliases or thunks in the order they were created. + struct cgraph_node *alias, *next; + for (alias = node->same_body; alias && alias->next; alias = alias->next); + for (; alias; alias = next) { + next = alias->previous; if (alias->thunk.thunk_p) { emit_thunk_to_llvm(alias); } else { assert(alias->thunk.alias == node->decl && "Unexpected alias target!"); emit_alias_to_llvm(alias->decl, node->decl); } + } } } From evan.cheng at apple.com Mon Dec 7 15:19:33 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 21:19:33 -0000 Subject: [llvm-commits] [llvm] r90804 - /llvm/trunk/lib/CodeGen/TailDuplication.cpp Message-ID: <200912072119.nB7LJXLf021518@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 15:19:33 2009 New Revision: 90804 URL: http://llvm.org/viewvc/llvm-project?rev=90804&view=rev Log: Delete code accidentally left behind. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=90804&r1=90803&r2=90804&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Mon Dec 7 15:19:33 2009 @@ -244,16 +244,6 @@ if (UseMI->getParent() == DefBB) continue; SSAUpdate.RewriteUse(UseMO); - while (!NewPHIs.empty()) { - MachineInstr *NewPHI = NewPHIs.back(); - NewPHIs.pop_back(); - unsigned PHIDef = NewPHI->getOperand(0).getReg(); - for (unsigned j = 1, ee = NewPHI->getNumOperands(); j != ee; - j += 2) { - if (NewPHI->getOperand(j).getReg() == VReg) - NewPHI->getOperand(j).setReg(PHIDef); - } - } } } From jyasskin at google.com Mon Dec 7 15:34:29 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 7 Dec 2009 13:34:29 -0800 Subject: [llvm-commits] Change indirect-globals to use a dedicated allocIndirectGV (issue157145) In-Reply-To: <0016e68dec164ab6f9047922f14f@google.com> References: <0016e68dec164ab6f9047922f14f@google.com> Message-ID: Hi Evan, any word on this? On Tue, Nov 24, 2009 at 11:28 AM, wrote: > Reviewers: evan.cheng_apple.com, > > Message: > Hi Evan, could you take a look? > http://codereview.appspot.com/download/issue157145_7.diff > I think this is an ok change for arm (and it passes tests on nlewycky's > box) because even though the indirect global is generated as part of a > call stub, it's not actually executed. > > Description: > This lets us remove start/finishGVStub and the BufferState helper class > from the MachineCodeEmitter interface. ?It has the side-effect of not > setting the indirect global writable and then executable on ARM, but > that shouldn't be necessary. > > Please review this at http://codereview.appspot.com/157145 > > Affected files: > ? M ? ? include/llvm/CodeGen/JITCodeEmitter.h > ? M ? ? include/llvm/CodeGen/MachineCodeEmitter.h > ? M ? ? lib/ExecutionEngine/JIT/JITEmitter.cpp > ? M ? ? lib/Target/ARM/ARMJITInfo.cpp > ? M ? ? lib/Target/Alpha/AlphaJITInfo.cpp > ? M ? ? lib/Target/PowerPC/PPCJITInfo.cpp > ? M ? ? lib/Target/X86/X86JITInfo.cpp > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From dpatel at apple.com Mon Dec 7 15:41:32 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 07 Dec 2009 21:41:32 -0000 Subject: [llvm-commits] [llvm] r90805 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h Message-ID: <200912072141.nB7LfXeY022455@zion.cs.uiuc.edu> Author: dpatel Date: Mon Dec 7 15:41:32 2009 New Revision: 90805 URL: http://llvm.org/viewvc/llvm-project?rev=90805&view=rev Log: Add support to emit debug info for c++ style namespaces. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90805&r1=90804&r2=90805&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Dec 7 15:41:32 2009 @@ -99,6 +99,7 @@ bool isGlobalVariable() const; bool isScope() const; bool isCompileUnit() const; + bool isNameSpace() const; bool isLexicalBlock() const; bool isSubrange() const; bool isEnumerator() const; @@ -218,7 +219,7 @@ virtual ~DIType() {} DIDescriptor getContext() const { return getDescriptorField(1); } - StringRef getName() const { return getStringField(2); } + StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ return getFieldAs(3); } unsigned getLineNumber() const { return getUnsignedField(4); } uint64_t getSizeInBits() const { return getUInt64Field(5); } @@ -470,6 +471,22 @@ StringRef getFilename() const { return getContext().getFilename(); } }; + /// DINameSpace - A wrapper for a C++ style name space. + class DINameSpace : public DIScope { + public: + explicit DINameSpace(MDNode *N = 0) : DIScope(N) { + if (DbgNode && !isNameSpace()) + DbgNode = 0; + } + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + StringRef getDirectory() const { return getContext().getDirectory(); } + StringRef getFilename() const { return getContext().getFilename(); } + DICompileUnit getCompileUnit() const { return getFieldAs(3); } + unsigned getLineNumber() const { return getUnsignedField(4); } + }; + /// DILocation - This object holds location information. This object /// is not associated with any DWARF tag. class DILocation : public DIDescriptor { @@ -624,6 +641,11 @@ /// with the specified parent context. DILexicalBlock CreateLexicalBlock(DIDescriptor Context); + /// CreateNameSpace - This creates new descriptor for a namespace + /// with the specified parent context. + DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name, + DICompileUnit CU, unsigned LineNo); + /// CreateLocation - Creates a debug info location. DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc); Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=90805&r1=90804&r2=90805&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Dec 7 15:41:32 2009 @@ -227,6 +227,7 @@ case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_lexical_block: case dwarf::DW_TAG_subprogram: + case dwarf::DW_TAG_namespace: return true; default: break; @@ -242,6 +243,14 @@ return Tag == dwarf::DW_TAG_compile_unit; } +/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. +bool DIDescriptor::isNameSpace() const { + assert (!isNull() && "Invalid descriptor!"); + unsigned Tag = getTag(); + + return Tag == dwarf::DW_TAG_namespace; +} + /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { assert (!isNull() && "Invalid descriptor!"); @@ -438,6 +447,8 @@ return DISubprogram(DbgNode).getFilename(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getFilename(); + else if (isNameSpace()) + return DINameSpace(DbgNode).getFilename(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -450,6 +461,8 @@ return DISubprogram(DbgNode).getDirectory(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getDirectory(); + else if (isNameSpace()) + return DINameSpace(DbgNode).getDirectory(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -996,6 +1009,21 @@ return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); } +/// CreateNameSpace - This creates new descriptor for a namespace +/// with the specified parent context. +DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNo) { + Value *Elts[] = { + GetTagConstant(dwarf::DW_TAG_namespace), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) + }; + return DINameSpace(MDNode::get(VMContext, &Elts[0], 5)); +} + /// CreateLocation - Creates a debug info location. DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc) { Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90805&r1=90804&r2=90805&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Dec 7 15:41:32 2009 @@ -446,6 +446,23 @@ addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); } +/// addSourceLine - Add location information to specified debug information +/// entry. +void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) { + // If there is no compile unit specified, don't add a line #. + if (NS->getCompileUnit().isNull()) + return; + + unsigned Line = NS->getLineNumber(); + StringRef FN = NS->getFilename(); + StringRef Dir = NS->getDirectory(); + + unsigned FileID = GetOrCreateSourceID(Dir, FN); + assert(FileID && "Invalid file id"); + addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); + addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); +} + /* Byref variables, in Blocks, are declared by the programmer as "SomeType VarName;", but the compiler creates a __Block_byref_x_VarName struct, and gives the variable VarName @@ -771,9 +788,13 @@ // Add debug information entry to entity and appropriate context. DIE *Die = NULL; DIDescriptor Context = Ty.getContext(); - if (!Context.isNull()) - Die = DW_Unit->getDIE(Context.getNode()); - + if (!Context.isNull()) { + if (Context.isNameSpace()) { + DINameSpace NS(Context.getNode()); + Die = getOrCreateNameSpace(NS); + } else + Die = DW_Unit->getDIE(Context.getNode()); + } if (Die) Die->addChild(Buffer); else @@ -1643,6 +1664,29 @@ return SrcId; } +/// getOrCreateNameSpace - Create a DIE for DINameSpace. +DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace &NS) { + DIE *NDie = ModuleCU->getDIE(NS.getNode()); + if (NDie) + return NDie; + + NDie = new DIE(dwarf::DW_TAG_namespace); + ModuleCU->insertDIE(NS.getNode(), NDie); + if (!NS.getName().empty()) + addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName()); + addSourceLine(NDie, &NS); + DIDescriptor NSContext = NS.getContext(); + DIE *Context = NULL; + if (NSContext.isNameSpace()) { + DINameSpace NS2(NSContext.getNode()); + Context = getOrCreateNameSpace(NS2); + } + else + Context = ModuleCU->getCUDie(); + Context->addChild(NDie); + return NDie; +} + void DwarfDebug::constructCompileUnit(MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); @@ -1734,10 +1778,17 @@ ModuleCU->insertDIE(N, SubprogramDie); // Add to context owner. - if (SP.getContext().getNode() == SP.getCompileUnit().getNode()) + DIDescriptor SPContext = SP.getContext(); + if (SPContext.isCompileUnit() + && SPContext.getNode() == SP.getCompileUnit().getNode()) { if (TopLevelDIEs.insert(SubprogramDie)) TopLevelDIEsVector.push_back(SubprogramDie); - + } else if (SPContext.isNameSpace()) { + DINameSpace NS(SPContext.getNode()); + DIE *NDie = getOrCreateNameSpace(NS); + NDie->addChild(SubprogramDie); + } + // Expose as global. ModuleCU->addGlobal(SP.getName(), SubprogramDie); @@ -1780,10 +1831,18 @@ for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), E = DbgFinder.global_variable_end(); I != E; ++I) { DIGlobalVariable GV(*I); - if (GV.getContext().getNode() != GV.getCompileUnit().getNode()) - ScopedGVs.push_back(*I); - else + DIDescriptor GVContext = GV.getContext(); + if (GVContext.isCompileUnit() + && GVContext.getNode() == GV.getCompileUnit().getNode()) constructGlobalVariableDIE(*I); + else if (GVContext.isNameSpace()) { + DIE *GVDie = createGlobalVariableDIE(ModuleCU, GV); + DINameSpace NS(GVContext.getNode()); + DIE *NDie = getOrCreateNameSpace(NS); + NDie->addChild(GVDie); + } + else + ScopedGVs.push_back(*I); } // Create DIEs for each subprogram. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=90805&r1=90804&r2=90805&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Dec 7 15:41:32 2009 @@ -289,6 +289,7 @@ void addSourceLine(DIE *Die, const DIGlobal *G); void addSourceLine(DIE *Die, const DISubprogram *SP); void addSourceLine(DIE *Die, const DIType *Ty); + void addSourceLine(DIE *Die, const DINameSpace *NS); /// addAddress - Add an address attribute to a die based on the location /// provided. @@ -340,6 +341,9 @@ /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy); + /// getOrCreateNameSpace - Create a DIE for DINameSpace. + DIE *getOrCreateNameSpace(DINameSpace &NS); + /// createGlobalVariableDIE - Create new DIE using GV. DIE *createGlobalVariableDIE(CompileUnit *DW_Unit, const DIGlobalVariable &GV); From dpatel at apple.com Mon Dec 7 15:49:53 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 07 Dec 2009 21:49:53 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r90806 - in /llvm-gcc-4.2/trunk/gcc: llvm-debug.cpp llvm-debug.h Message-ID: <200912072149.nB7LnrlP022775@zion.cs.uiuc.edu> Author: dpatel Date: Mon Dec 7 15:49:53 2009 New Revision: 90806 URL: http://llvm.org/viewvc/llvm-project?rev=90806&view=rev Log: Emit debug info for C++ namespaces. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=90806&r1=90805&r2=90806&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Mon Dec 7 15:49:53 2009 @@ -282,7 +282,23 @@ RegionMap[FnDecl] = WeakVH(SP.getNode()); } - /// findRegion - Find tree_node N's region. +/// getOrCreateNameSpace - Get name space descriptor for the tree node. +DINameSpace DebugInfo::getOrCreateNameSpace(tree Node, DIDescriptor Context) { + std::map::iterator I = + NameSpaceCache.find(Node); + if (I != NameSpaceCache.end()) + return DINameSpace(cast(I->second)); + + expanded_location Loc = GetNodeLocation(Node, false); + DINameSpace DNS = + DebugFactory.CreateNameSpace(Context, GetNodeName(Node), + getOrCreateCompileUnit(Loc.file), Loc.line); + + NameSpaceCache[Node] = WeakVH(DNS.getNode()); + return DNS; +} + +/// findRegion - Find tree_node N's region. DIDescriptor DebugInfo::findRegion(tree Node) { if (Node == NULL_TREE) return getOrCreateCompileUnit(main_input_filename); @@ -293,8 +309,9 @@ return DIDescriptor(R); if (TYPE_P (Node)) { - if (TYPE_CONTEXT (Node)) + if (TYPE_CONTEXT (Node)) { return findRegion (TYPE_CONTEXT(Node)); + } } else if (DECL_P (Node)) { tree decl = Node; tree context = NULL_TREE; @@ -304,10 +321,19 @@ context = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); - if (context != NULL_TREE) - return findRegion(context); + if (context != NULL_TREE) { + if (TREE_CODE(Node) == NAMESPACE_DECL) { + DIDescriptor Context = findRegion(context); + return getOrCreateNameSpace(Node, Context); + } else + return findRegion(context); + } } - + + if (TREE_CODE(Node) == NAMESPACE_DECL) + return getOrCreateNameSpace(Node, + getOrCreateCompileUnit(main_input_filename)); + // Otherwise main compile unit covers everything. return getOrCreateCompileUnit(main_input_filename); } Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=90806&r1=90805&r2=90806&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Mon Dec 7 15:49:53 2009 @@ -68,6 +68,9 @@ std::map SPCache; // Cache of previously constructed // Subprograms. + std::map NameSpaceCache; + // Cache of previously constructed name + // spaces. SmallVector RegionStack; // Stack to track declarative scopes. @@ -136,6 +139,9 @@ /// findRegion - Find tree_node N's region. DIDescriptor findRegion(tree_node *n); + + /// getOrCreateNameSpace - Get name space descriptor for the tree node. + DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context); }; } // end namespace llvm From vhernandez at apple.com Mon Dec 7 15:54:43 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 07 Dec 2009 21:54:43 -0000 Subject: [llvm-commits] [llvm] r90807 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp Message-ID: <200912072154.nB7Lsh0b022942@zion.cs.uiuc.edu> Author: hernande Date: Mon Dec 7 15:54:43 2009 New Revision: 90807 URL: http://llvm.org/viewvc/llvm-project?rev=90807&view=rev Log: Rename DIFactory::InsertValue() as DIFactory::InsertDbgValueIntrinsic() Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90807&r1=90806&r2=90807&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Dec 7 15:54:43 2009 @@ -662,13 +662,13 @@ Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, Instruction *InsertBefore); - /// InsertValue - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, - DIVariable D, BasicBlock *InsertAtEnd); - - /// InsertValue - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset, - DIVariable D, Instruction *InsertBefore); + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, BasicBlock *InsertAtEnd); + + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); }; Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=90807&r1=90806&r2=90807&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Dec 7 15:54:43 2009 @@ -1078,9 +1078,10 @@ return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); } -/// InsertValue - Insert a new llvm.dbg.value intrinsic call. -Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D, - Instruction *InsertBefore) { +/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. +Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, + DIVariable D, + Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && "offset must be i64"); @@ -1093,9 +1094,10 @@ return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore); } -/// InsertValue - Insert a new llvm.dbg.value intrinsic call. -Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D, - BasicBlock *InsertAtEnd) { +/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. +Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, + DIVariable D, + BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && "offset must be i64"); From evan.cheng at apple.com Mon Dec 7 16:23:52 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 7 Dec 2009 14:23:52 -0800 Subject: [llvm-commits] Change indirect-globals to use a dedicated allocIndirectGV (issue157145) In-Reply-To: References: <0016e68dec164ab6f9047922f14f@google.com> Message-ID: Sorry, completely missed it. + // Size == alignment on ARM. + void *PtrAddr = JCE.allocIndirectGV( + GV, Buffer, sizeof(Buffer), sizeof(Buffer)); The comment is somewhat misleading. The alignment and size of the buffer happen to be both 4 in this case. Your code makes it seem like they have to be the same. Apart from that, it seems fine. Eric, could you test it on x86 and x86_64 Darwin? Thanks, Evan On Dec 7, 2009, at 1:34 PM, Jeffrey Yasskin wrote: > Hi Evan, any word on this? > > On Tue, Nov 24, 2009 at 11:28 AM, wrote: >> Reviewers: evan.cheng_apple.com, >> >> Message: >> Hi Evan, could you take a look? >> http://codereview.appspot.com/download/issue157145_7.diff >> I think this is an ok change for arm (and it passes tests on nlewycky's >> box) because even though the indirect global is generated as part of a >> call stub, it's not actually executed. >> >> Description: >> This lets us remove start/finishGVStub and the BufferState helper class >> from the MachineCodeEmitter interface. It has the side-effect of not >> setting the indirect global writable and then executable on ARM, but >> that shouldn't be necessary. >> >> Please review this at http://codereview.appspot.com/157145 >> >> Affected files: >> M include/llvm/CodeGen/JITCodeEmitter.h >> M include/llvm/CodeGen/MachineCodeEmitter.h >> M lib/ExecutionEngine/JIT/JITEmitter.cpp >> M lib/Target/ARM/ARMJITInfo.cpp >> M lib/Target/Alpha/AlphaJITInfo.cpp >> M lib/Target/PowerPC/PPCJITInfo.cpp >> M lib/Target/X86/X86JITInfo.cpp >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091207/b03b7639/attachment.html From jyasskin at google.com Mon Dec 7 16:32:38 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 07 Dec 2009 22:32:38 -0000 Subject: [llvm-commits] [llvm] r90813 - /llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Message-ID: <200912072232.nB7MWcmA024287@zion.cs.uiuc.edu> Author: jyasskin Date: Mon Dec 7 16:32:38 2009 New Revision: 90813 URL: http://llvm.org/viewvc/llvm-project?rev=90813&view=rev Log: Fix the OProfileJITEventListener for StringRef being returned from debug info. Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=90813&r1=90812&r2=90813&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Mon Dec 7 16:32:38 2009 @@ -69,24 +69,18 @@ } class FilenameCache { - // Holds the filename of each Scope, so that we can pass the - // pointer into oprofile. These char*s are freed in the destructor. - DenseMap Filenames; + // Holds the filename of each Scope, so that we can pass a null-terminated + // string into oprofile. + DenseMap Filenames; public: const char *getFilename(MDNode *Scope) { - char *&Filename = Filenames[Scope]; + std::string &Filename = Filenames[Scope]; if (Filename == NULL) { DIScope S(Scope); - Filename = strdup(S.getFilename()); - } - return Filename; - } - ~FilenameCache() { - for (DenseMap::iterator - I = Filenames.begin(), E = Filenames.end(); I != E; ++I) { - free(I->second); + Filename = S.getFilename(); } + return Filename.c_str(); } }; From jyasskin at google.com Mon Dec 7 16:59:39 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 7 Dec 2009 14:59:39 -0800 Subject: [llvm-commits] Change indirect-globals to use a dedicated allocIndirectGV (issue157145) In-Reply-To: References: <0016e68dec164ab6f9047922f14f@google.com> Message-ID: On Mon, Dec 7, 2009 at 2:23 PM, Evan Cheng wrote: > Sorry, completely missed it. > > + // Size == alignment on ARM. > + void *PtrAddr = JCE.allocIndirectGV( > + GV, Buffer, sizeof(Buffer), sizeof(Buffer)); > > The comment is somewhat misleading. The alignment and size of the buffer > happen to be both 4 in this case. Your code makes it seem like they have to > be the same. Good point. I've removed that comment and specified the alignment explicitly on both ARM and X86. http://codereview.appspot.com/download/issue157145_2003.diff > Apart from that, it seems fine. Eric, could you test it on x86 and x86_64 > Darwin? I'll wait for Eric's ok to check this in. > Thanks, > Evan > On Dec 7, 2009, at 1:34 PM, Jeffrey Yasskin wrote: > > Hi Evan, any word on this? > > On Tue, Nov 24, 2009 at 11:28 AM, ? wrote: > > Reviewers: evan.cheng_apple.com, > > Message: > > Hi Evan, could you take a look? > > http://codereview.appspot.com/download/issue157145_7.diff > > I think this is an ok change for arm (and it passes tests on nlewycky's > > box) because even though the indirect global is generated as part of a > > call stub, it's not actually executed. > > Description: > > This lets us remove start/finishGVStub and the BufferState helper class > > from the MachineCodeEmitter interface. ?It has the side-effect of not > > setting the indirect global writable and then executable on ARM, but > > that shouldn't be necessary. > > Please review this at http://codereview.appspot.com/157145 > > Affected files: > > ? M ? ? include/llvm/CodeGen/JITCodeEmitter.h > > ? M ? ? include/llvm/CodeGen/MachineCodeEmitter.h > > ? M ? ? lib/ExecutionEngine/JIT/JITEmitter.cpp > > ? M ? ? lib/Target/ARM/ARMJITInfo.cpp > > ? M ? ? lib/Target/Alpha/AlphaJITInfo.cpp > > ? M ? ? lib/Target/PowerPC/PPCJITInfo.cpp > > ? M ? ? lib/Target/X86/X86JITInfo.cpp > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > From jyasskin at gmail.com Mon Dec 7 17:06:02 2009 From: jyasskin at gmail.com (jyasskin at gmail.com) Date: Mon, 07 Dec 2009 23:06:02 +0000 Subject: [llvm-commits] [PATCH] Make Path use StringRef instead of std::string where possible (issue161054) Message-ID: <0016e6d2849355ce81047a2b80d2@google.com> Reviewers: , Message: This depends on the patch I just sent to cfe-commits. I wanted to run it by the list in case there are objections to the interface change (that, for example, Path.getSuffix().c_str() no longer works). Please review this at http://codereview.appspot.com/161054 Affected files: M include/llvm/System/Path.h M lib/CompilerDriver/CompilationGraph.cpp M lib/System/Path.cpp M lib/System/Unix/Path.inc M lib/System/Win32/Path.inc From evan.cheng at apple.com Mon Dec 7 17:10:34 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 23:10:34 -0000 Subject: [llvm-commits] [llvm] r90815 - /llvm/trunk/lib/CodeGen/MachineInstr.cpp Message-ID: <200912072310.nB7NAZix025498@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 17:10:34 2009 New Revision: 90815 URL: http://llvm.org/viewvc/llvm-project?rev=90815&view=rev Log: Follow up to 90488. Turn a check into an assertion. Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=90815&r1=90814&r2=90815&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Dec 7 17:10:34 2009 @@ -1064,8 +1064,8 @@ unsigned MachineInstr::isConstantValuePHI() const { if (getOpcode() != TargetInstrInfo::PHI) return 0; - if (getNumOperands() <= 1) - return 0; + assert(getNumOperands() >= 3 && + "It's illegal to have a PHI without source operands"); unsigned Reg = getOperand(1).getReg(); for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) From evan.cheng at apple.com Mon Dec 7 17:11:03 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 07 Dec 2009 23:11:03 -0000 Subject: [llvm-commits] [llvm] r90816 - /llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp Message-ID: <200912072311.nB7NB3SZ025524@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 7 17:11:03 2009 New Revision: 90816 URL: http://llvm.org/viewvc/llvm-project?rev=90816&view=rev Log: Watch out for duplicated PHI instructions. Modified: llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp Modified: llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp?rev=90816&r1=90815&r2=90816&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSSAUpdater.cpp Mon Dec 7 17:11:03 2009 @@ -85,6 +85,36 @@ return GetValueAtEndOfBlockInternal(BB); } +static +unsigned LookForIdenticalPHI(MachineBasicBlock *BB, + SmallVector, 8> &PredValues) { + if (BB->empty()) + return 0; + + MachineBasicBlock::iterator I = BB->front(); + if (I->getOpcode() != TargetInstrInfo::PHI) + return 0; + + AvailableValsTy AVals; + for (unsigned i = 0, e = PredValues.size(); i != e; ++i) + AVals[PredValues[i].first] = PredValues[i].second; + while (I != BB->end() && I->getOpcode() == TargetInstrInfo::PHI) { + bool Same = true; + for (unsigned i = 1, e = I->getNumOperands(); i != e; i += 2) { + unsigned SrcReg = I->getOperand(i).getReg(); + MachineBasicBlock *SrcBB = I->getOperand(i+1).getMBB(); + if (AVals[SrcBB] != SrcReg) { + Same = false; + break; + } + } + if (Same) + return I->getOperand(0).getReg(); + ++I; + } + return 0; +} + /// InsertNewDef - Insert an empty PHI or IMPLICIT_DEF instruction which define /// a value of the given register class at the start of the specified basic /// block. It returns the virtual register defined by the instruction. @@ -97,7 +127,6 @@ return BuildMI(*BB, I, DebugLoc::getUnknownLoc(), TII->get(Opcode), NewVR); } - /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that /// is live in the middle of the specified block. /// @@ -121,7 +150,7 @@ // If there is no definition of the renamed variable in this block, just use // GetValueAtEndOfBlock to do our work. if (!getAvailableVals(AV).count(BB)) - return GetValueAtEndOfBlock(BB); + return GetValueAtEndOfBlockInternal(BB); // If there are no predecessors, just return undef. if (BB->pred_empty()) { @@ -156,6 +185,11 @@ if (SingularValue != 0) return SingularValue; + // If an identical PHI is already in BB, just reuse it. + unsigned DupPHI = LookForIdenticalPHI(BB, PredValues); + if (DupPHI) + return DupPHI; + // Otherwise, we do need a PHI: insert one now. MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front(); MachineInstr *InsertedPHI = InsertNewDef(TargetInstrInfo::PHI, BB, @@ -199,7 +233,7 @@ unsigned NewVR = 0; if (UseMI->getOpcode() == TargetInstrInfo::PHI) { MachineBasicBlock *SourceBB = findCorrespondingPred(UseMI, &U); - NewVR = GetValueAtEndOfBlock(SourceBB); + NewVR = GetValueAtEndOfBlockInternal(SourceBB); } else { NewVR = GetValueInMiddleOfBlock(UseMI->getParent()); } From devang.patel at gmail.com Mon Dec 7 17:24:12 2009 From: devang.patel at gmail.com (Devang Patel) Date: Mon, 7 Dec 2009 15:24:12 -0800 Subject: [llvm-commits] [llvm] r90813 - /llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp In-Reply-To: <200912072232.nB7MWcmA024287@zion.cs.uiuc.edu> References: <200912072232.nB7MWcmA024287@zion.cs.uiuc.edu> Message-ID: <352a1fb20912071524w7f4c2a06hd71845ac1d6c4c5e@mail.gmail.com> Hi Jeffrey, On Mon, Dec 7, 2009 at 2:32 PM, Jeffrey Yasskin wrote: > Author: jyasskin > Date: Mon Dec ?7 16:32:38 2009 > New Revision: 90813 > > URL: http://llvm.org/viewvc/llvm-project?rev=90813&view=rev > Log: > Fix the OProfileJITEventListener for StringRef being returned from debug info. > > > Modified: > ? ?llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=90813&r1=90812&r2=90813&view=diff > > ============================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Mon Dec ?7 16:32:38 2009 > @@ -69,24 +69,18 @@ > ?} > > ?class FilenameCache { > - ?// Holds the filename of each Scope, so that we can pass the > - ?// pointer into oprofile. ?These char*s are freed in the destructor. > - ?DenseMap Filenames; > + ?// Holds the filename of each Scope, so that we can pass a null-terminated > + ?// string into oprofile. > + ?DenseMap Filenames; > While you're here, it is a good idea to change this map to use ValueMap :) - Devang From jyasskin at google.com Mon Dec 7 18:14:27 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 7 Dec 2009 16:14:27 -0800 Subject: [llvm-commits] [PATCH] New external2availableexternally pass (issue166075) In-Reply-To: References: <00163691fbf3bc89a9047a032500@google.com> <4B1B6CEA.9060306@free.fr> <5d44f72f0912060232k217b3cej98aeb29280bf0bc4@mail.gmail.com> <6B7FD070-E63E-4612-B088-74DEE2C4AEC6@apple.com> Message-ID: On Mon, Dec 7, 2009 at 1:06 PM, Jeffrey Yasskin wrote: > On Mon, Dec 7, 2009 at 12:59 PM, Chris Lattner wrote: >> >> On Dec 7, 2009, at 11:52 AM, Jeffrey Yasskin wrote: >> >>> Anyone have comments? >> >> Who are the expected clients of this? ?It seems pretty special purpose to go into mainline. > > People writing JITs are likely to use it to provide definitions of > their runtime library functions. Static compilers could use it too if > they ship with a compiled runtime but also want to be able to inline > bits of the runtime into their output, without making those bits > builtins. That is, take the author of a new language. 1. They write a compiler, taking their language to IR. 2. They write a standard library, which they'll ship with their compiler. To make compilation fast, they generate native code from the library and install it with their compiler. 3. They notice that calls into their standard library could benefit from inlining. There are two things they could do here: a. Don't install native code; instead install .bc files. Load those into the module of each translation unit. This means that for stdlib calls that aren't inlined, every compilation needs to generate code. That's especially problematic for a JIT, but also wastes time for a static compiler. b. Generate a .bc file with the library functions defined, but marked available_externally. This lets the optimizers inline the definitions, but non-inlined definitions just call out to the pre-compiled native code. 3b is the tactic this pass is designed for. The language author uses it like: 1. Write the compiler. 2. Write the standard library. 3. Compile it to bitcode. 4. Generate a .o or .so from the bitcode, and install that with the compiler. This gets linked with every output binary. 5. Run external2availableexternally over the bitcode file, to produce a stdlib.bc. This gets loaded into the Module of every translation unit to facilitate inlining. Jeffrey From asl at math.spbu.ru Mon Dec 7 19:03:04 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 08 Dec 2009 01:03:04 -0000 Subject: [llvm-commits] [llvm] r90819 - in /llvm/trunk: lib/Target/MSP430/MSP430InstrInfo.td test/CodeGen/MSP430/bit.ll Message-ID: <200912080103.nB8134s2030147@zion.cs.uiuc.edu> Author: asl Date: Mon Dec 7 19:03:04 2009 New Revision: 90819 URL: http://llvm.org/viewvc/llvm-project?rev=90819&view=rev Log: Reduce (cmp 0, and_su (foo, bar)) into (bit foo, bar). This saves extra instruction. Patch inspired by Brian Lucas! Added: llvm/trunk/test/CodeGen/MSP430/bit.ll Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=90819&r1=90818&r2=90819&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Mon Dec 7 19:03:04 2009 @@ -92,7 +92,9 @@ // Pattern Fragments def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>; - +def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ + return N->hasOneUse(); +}]>; //===----------------------------------------------------------------------===// // Instruction list.. @@ -826,6 +828,65 @@ "cmp.w\t{$src1, $src2}", [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>; + +// BIT TESTS, just sets condition codes +// Note that the C condition is set differently than when using CMP. +let isCommutable = 1 in { +def BIT8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR8:$src1, GR8:$src2)), + (implicit SRW)]>; +def BIT16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR16:$src1, GR16:$src2)), + (implicit SRW)]>; +} +def BIT8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR8:$src1, imm:$src2)), + (implicit SRW)]>; +def BIT16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR16:$src1, imm:$src2)), + (implicit SRW)]>; + +def BIT8rm : Pseudo<(outs), (ins GR8:$src1, memdst:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR8:$src1, (load addr:$src2))), + (implicit SRW)]>; +def BIT16rm : Pseudo<(outs), (ins GR16:$src1, memdst:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su GR16:$src1, (load addr:$src2))), + (implicit SRW)]>; + +def BIT8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (load addr:$src1), GR8:$src2)), + (implicit SRW)]>; +def BIT16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (load addr:$src1), GR16:$src2)), + (implicit SRW)]>; + +def BIT8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (load addr:$src1), (i8 imm:$src2))), + (implicit SRW)]>; +def BIT16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (load addr:$src1), (i16 imm:$src2))), + (implicit SRW)]>; + +def BIT8mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2), + "bit.b\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (i8 (load addr:$src1)), + (load addr:$src2))), + (implicit SRW)]>; +def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2), + "bit.w\t{$src2, $src1}", + [(MSP430cmp 0, (and_su (i16 (load addr:$src1)), + (load addr:$src2))), + (implicit SRW)]>; } // Defs = [SRW] //===----------------------------------------------------------------------===// @@ -908,3 +969,6 @@ // peephole patterns def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>; +def : Pat<(MSP430cmp 0, (trunc (and_su GR16:$src1, GR16:$src2))), + (BIT8rr (EXTRACT_SUBREG GR16:$src1, subreg_8bit), + (EXTRACT_SUBREG GR16:$src2, subreg_8bit))>; Added: llvm/trunk/test/CodeGen/MSP430/bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/bit.ll?rev=90819&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/MSP430/bit.ll (added) +++ llvm/trunk/test/CodeGen/MSP430/bit.ll Mon Dec 7 19:03:04 2009 @@ -0,0 +1,166 @@ +; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s +target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:32" +target triple = "msp430-generic-generic" + + at foo8 = external global i8; + at bar8 = external global i8; + +define i8 @bitbrr(i8 %a, i8 %b) nounwind { + %t1 = and i8 %a, %b + %t2 = icmp ne i8 %t1, 0 + %t3 = zext i1 %t2 to i8 + ret i8 %t3 +} +; CHECK: bitbrr: +; CHECK: bit.b r14, r15 + +define i8 @bitbri(i8 %a) nounwind { + %t1 = and i8 %a, 15 + %t2 = icmp ne i8 %t1, 0 + %t3 = zext i1 %t2 to i8 + ret i8 %t3 +} +; CHECK: bitbri: +; CHECK: bit.b #15, r15 + +define i8 @bitbir(i8 %a) nounwind { + %t1 = and i8 15, %a + %t2 = icmp ne i8 %t1, 0 + %t3 = zext i1 %t2 to i8 + ret i8 %t3 +} +; CHECK: bitbir: +; CHECK: bit.b #15, r15 + +define i8 @bitbmi() nounwind { + %t1 = load i8* @foo8 + %t2 = and i8 %t1, 15 + %t3 = icmp ne i8 %t2, 0 + %t4 = zext i1 %t3 to i8 + ret i8 %t4 +} +; CHECK: bitbmi: +; CHECK: bit.b #15, &foo8 + +define i8 @bitbim() nounwind { + %t1 = load i8* @foo8 + %t2 = and i8 15, %t1 + %t3 = icmp ne i8 %t2, 0 + %t4 = zext i1 %t3 to i8 + ret i8 %t4 +} +; CHECK: bitbim: +; CHECK: bit.b #15, &foo8 + +define i8 @bitbrm(i8 %a) nounwind { + %t1 = load i8* @foo8 + %t2 = and i8 %a, %t1 + %t3 = icmp ne i8 %t2, 0 + %t4 = zext i1 %t3 to i8 + ret i8 %t4 +} +; CHECK: bitbrm: +; CHECK: bit.b &foo8, r15 + +define i8 @bitbmr(i8 %a) nounwind { + %t1 = load i8* @foo8 + %t2 = and i8 %t1, %a + %t3 = icmp ne i8 %t2, 0 + %t4 = zext i1 %t3 to i8 + ret i8 %t4 +} +; CHECK: bitbmr: +; CHECK: bit.b r15, &foo8 + +define i8 @bitbmm() nounwind { + %t1 = load i8* @foo8 + %t2 = load i8* @bar8 + %t3 = and i8 %t1, %t2 + %t4 = icmp ne i8 %t3, 0 + %t5 = zext i1 %t4 to i8 + ret i8 %t5 +} +; CHECK: bitbmm: +; CHECK: bit.b &bar8, &foo8 + + at foo16 = external global i16; + at bar16 = external global i16; + +define i16 @bitwrr(i16 %a, i16 %b) nounwind { + %t1 = and i16 %a, %b + %t2 = icmp ne i16 %t1, 0 + %t3 = zext i1 %t2 to i16 + ret i16 %t3 +} +; CHECK: bitwrr: +; CHECK: bit.w r14, r15 + +define i16 @bitwri(i16 %a) nounwind { + %t1 = and i16 %a, 4080 + %t2 = icmp ne i16 %t1, 0 + %t3 = zext i1 %t2 to i16 + ret i16 %t3 +} +; CHECK: bitwri: +; CHECK: bit.w #4080, r15 + +define i16 @bitwir(i16 %a) nounwind { + %t1 = and i16 4080, %a + %t2 = icmp ne i16 %t1, 0 + %t3 = zext i1 %t2 to i16 + ret i16 %t3 +} +; CHECK: bitwir: +; CHECK: bit.w #4080, r15 + +define i16 @bitwmi() nounwind { + %t1 = load i16* @foo16 + %t2 = and i16 %t1, 4080 + %t3 = icmp ne i16 %t2, 0 + %t4 = zext i1 %t3 to i16 + ret i16 %t4 +} +; CHECK: bitwmi: +; CHECK: bit.w #4080, &foo16 + +define i16 @bitwim() nounwind { + %t1 = load i16* @foo16 + %t2 = and i16 4080, %t1 + %t3 = icmp ne i16 %t2, 0 + %t4 = zext i1 %t3 to i16 + ret i16 %t4 +} +; CHECK: bitwim: +; CHECK: bit.w #4080, &foo16 + +define i16 @bitwrm(i16 %a) nounwind { + %t1 = load i16* @foo16 + %t2 = and i16 %a, %t1 + %t3 = icmp ne i16 %t2, 0 + %t4 = zext i1 %t3 to i16 + ret i16 %t4 +} +; CHECK: bitwrm: +; CHECK: bit.w &foo16, r15 + +define i16 @bitwmr(i16 %a) nounwind { + %t1 = load i16* @foo16 + %t2 = and i16 %t1, %a + %t3 = icmp ne i16 %t2, 0 + %t4 = zext i1 %t3 to i16 + ret i16 %t4 +} +; CHECK: bitwmr: +; CHECK: bit.w r15, &foo16 + +define i16 @bitwmm() nounwind { + %t1 = load i16* @foo16 + %t2 = load i16* @bar16 + %t3 = and i16 %t1, %t2 + %t4 = icmp ne i16 %t3, 0 + %t5 = zext i1 %t4 to i16 + ret i16 %t5 +} +; CHECK: bitwmm: +; CHECK: bit.w &bar16, &foo16 + From echristo at apple.com Mon Dec 7 19:29:26 2009 From: echristo at apple.com (Eric Christopher) Date: Mon, 7 Dec 2009 17:29:26 -0800 Subject: [llvm-commits] Change indirect-globals to use a dedicated allocIndirectGV (issue157145) In-Reply-To: References: <0016e68dec164ab6f9047922f14f@google.com> Message-ID: <0C1DBF68-04C1-4606-AF1A-08E02C4B1C56@apple.com> > >> Apart from that, it seems fine. Eric, could you test it on x86 and x86_64 >> Darwin? > > I'll wait for Eric's ok to check this in. Testing now. -eric From echristo at apple.com Mon Dec 7 20:22:56 2009 From: echristo at apple.com (Eric Christopher) Date: Mon, 7 Dec 2009 18:22:56 -0800 Subject: [llvm-commits] Change indirect-globals to use a dedicated allocIndirectGV (issue157145) In-Reply-To: <0C1DBF68-04C1-4606-AF1A-08E02C4B1C56@apple.com> References: <0016e68dec164ab6f9047922f14f@google.com> <0C1DBF68-04C1-4606-AF1A-08E02C4B1C56@apple.com> Message-ID: On Dec 7, 2009, at 5:29 PM, Eric Christopher wrote: >> >>> Apart from that, it seems fine. Eric, could you test it on x86 and x86_64 >>> Darwin? >> >> I'll wait for Eric's ok to check this in. > > Testing now. The resultant llvm-gcc failed to bootstrap on 32-bit leopard (Died with an UNREACHABLE). I haven't debugged it more and it could be transient on ToT. -eric From ofv at wanadoo.es Mon Dec 7 20:40:09 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 08 Dec 2009 02:40:09 -0000 Subject: [llvm-commits] [llvm] r90828 - /llvm/trunk/include/llvm/System/DataTypes.h.cmake Message-ID: <200912080240.nB82e9Dw001079@zion.cs.uiuc.edu> Author: ofv Date: Mon Dec 7 20:40:09 2009 New Revision: 90828 URL: http://llvm.org/viewvc/llvm-project?rev=90828&view=rev Log: For VC++, define the ?INT*_C macros only it they are not yet defined. Some compatibility updates like the Boost TR1 compatibility headers define them. Patch contributed by OvermindDL1! Modified: llvm/trunk/include/llvm/System/DataTypes.h.cmake Modified: llvm/trunk/include/llvm/System/DataTypes.h.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/System/DataTypes.h.cmake?rev=90828&r1=90827&r2=90828&view=diff ============================================================================== --- llvm/trunk/include/llvm/System/DataTypes.h.cmake (original) +++ llvm/trunk/include/llvm/System/DataTypes.h.cmake Mon Dec 7 20:40:09 2009 @@ -118,14 +118,33 @@ #define INT32_MAX 2147483647 #define INT32_MIN -2147483648 #define UINT32_MAX 4294967295U -#define INT8_C(C) C -#define UINT8_C(C) C -#define INT16_C(C) C -#define UINT16_C(C) C -#define INT32_C(C) C -#define UINT32_C(C) C ## U -#define INT64_C(C) ((int64_t) C ## LL) -#define UINT64_C(C) ((uint64_t) C ## ULL) +/* Certain compatibility updates to VC++ introduce the `cstdint' + * header, which defines the INT*_C macros. On default installs they + * are absent. */ +#ifndef INT8_C +# define INT8_C(C) C +#endif +#ifndef UINT8_C +# define UINT8_C(C) C +#endif +#ifndef INT16_C +# define INT16_C(C) C +#endif +#ifndef UINT16_C +# define UINT16_C(C) C +#endif +#ifndef INT32_C +# define INT32_C(C) C +#endif +#ifndef UINT32_C +# define UINT32_C(C) C ## U +#endif +#ifndef INT64_C +# define INT64_C(C) ((int64_t) C ## LL) +#endif +#ifndef UINT64_C +# define UINT64_C(C) ((uint64_t) C ## ULL) +#endif #endif /* _MSC_VER */ /* Set defaults for constants which we cannot find. */ From ofv at wanadoo.es Mon Dec 7 20:49:55 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 08 Dec 2009 02:49:55 -0000 Subject: [llvm-commits] [llvm] r90829 - /llvm/trunk/include/llvm/System/DataTypes.h.in Message-ID: <200912080249.nB82nt3o001412@zion.cs.uiuc.edu> Author: ofv Date: Mon Dec 7 20:49:54 2009 New Revision: 90829 URL: http://llvm.org/viewvc/llvm-project?rev=90829&view=rev Log: Removed VC++ compatibility code from DataTypes.h.in. This header file is not used on VC++ builds. Modified: llvm/trunk/include/llvm/System/DataTypes.h.in Modified: llvm/trunk/include/llvm/System/DataTypes.h.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/System/DataTypes.h.in?rev=90829&r1=90828&r2=90829&view=diff ============================================================================== --- llvm/trunk/include/llvm/System/DataTypes.h.in (original) +++ llvm/trunk/include/llvm/System/DataTypes.h.in Mon Dec 7 20:49:54 2009 @@ -36,8 +36,6 @@ #include #endif -#ifndef _MSC_VER - /* Note that this header's correct operation depends on __STDC_LIMIT_MACROS being defined. We would define it here, but in order to prevent Bad Things happening when system headers or C++ STL headers include stdint.h before we @@ -89,40 +87,6 @@ #define UINT32_MAX 4294967295U #endif -#else /* _MSC_VER */ -/* Visual C++ doesn't provide standard integer headers, but it does provide - built-in data types. */ -#include -#include -#include -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed int ssize_t; -#define INT8_MAX 127 -#define INT8_MIN -128 -#define UINT8_MAX 255 -#define INT16_MAX 32767 -#define INT16_MIN -32768 -#define UINT16_MAX 65535 -#define INT32_MAX 2147483647 -#define INT32_MIN -2147483648 -#define UINT32_MAX 4294967295U -#define INT8_C(C) C -#define UINT8_C(C) C -#define INT16_C(C) C -#define UINT16_C(C) C -#define INT32_C(C) C -#define UINT32_C(C) C ## U -#define INT64_C(C) ((int64_t) C ## LL) -#define UINT64_C(C) ((uint64_t) C ## ULL) -#endif /* _MSC_VER */ - /* Set defaults for constants which we cannot find. */ #if !defined(INT64_MAX) # define INT64_MAX 9223372036854775807LL From sabre at nondot.org Mon Dec 7 23:31:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Dec 2009 05:31:46 -0000 Subject: [llvm-commits] [llvm] r90834 - /llvm/trunk/lib/VMCore/Constants.cpp Message-ID: <200912080531.nB85VkiT006433@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 7 23:31:46 2009 New Revision: 90834 URL: http://llvm.org/viewvc/llvm-project?rev=90834&view=rev Log: whitespace cleanup Modified: llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=90834&r1=90833&r2=90834&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Mon Dec 7 23:31:46 2009 @@ -1560,7 +1560,7 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, Constant *C, - Value* const *Idxs, + Value *const *Idxs, unsigned NumIdx) { assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx) == From nicholas at mxc.ca Mon Dec 7 23:45:42 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 08 Dec 2009 05:45:42 -0000 Subject: [llvm-commits] [llvm] r90836 - in /llvm/trunk/lib/Transforms: Scalar/CodeGenPrepare.cpp Scalar/SCCVN.cpp Utils/BasicBlockUtils.cpp Message-ID: <200912080545.nB85jgW8006950@zion.cs.uiuc.edu> Author: nicholas Date: Mon Dec 7 23:45:41 2009 New Revision: 90836 URL: http://llvm.org/viewvc/llvm-project?rev=90836&view=rev Log: Remove unnecessary #include "llvm/LLVMContext.h". Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=90836&r1=90835&r2=90836&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Dec 7 23:45:41 2009 @@ -21,7 +21,6 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" -#include "llvm/LLVMContext.h" #include "llvm/Pass.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" Modified: llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp?rev=90836&r1=90835&r2=90836&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Mon Dec 7 23:45:41 2009 @@ -19,7 +19,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" -#include "llvm/LLVMContext.h" #include "llvm/Operator.h" #include "llvm/Value.h" #include "llvm/ADT/DenseMap.h" Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=90836&r1=90835&r2=90836&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Mon Dec 7 23:45:41 2009 @@ -16,7 +16,6 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" -#include "llvm/LLVMContext.h" #include "llvm/Constant.h" #include "llvm/Type.h" #include "llvm/Analysis/AliasAnalysis.h" From sabre at nondot.org Tue Dec 8 00:06:26 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Dec 2009 06:06:26 -0000 Subject: [llvm-commits] [llvm] r90837 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912080606.nB866QDW007592@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 00:06:26 2009 New Revision: 90837 URL: http://llvm.org/viewvc/llvm-project?rev=90837&view=rev Log: fix a typo (and -> add) and fix GetAvailablePHITranslatedSubExpr to not side-effect the current object. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90837&r1=90836&r2=90837&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Tue Dec 8 00:06:26 2009 @@ -88,7 +88,7 @@ /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. Value *GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB, - const DominatorTree &DT); + const DominatorTree &DT) const; /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90837&r1=90836&r2=90837&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 00:06:26 2009 @@ -22,7 +22,7 @@ isa(Inst)) return true; - if (Inst->getOpcode() == Instruction::And && + if (Inst->getOpcode() == Instruction::Add && isa(Inst->getOperand(1))) return true; @@ -205,9 +205,12 @@ /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. Value *PHITransAddr:: GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB, - const DominatorTree &DT) { + const DominatorTree &DT) const { + PHITransAddr Tmp(V, TD); + Tmp.PHITranslateValue(CurBB, PredBB); + // See if PHI translation succeeds. - V = PHITranslateSubExpr(V, CurBB, PredBB); + V = Tmp.getAddr(); // Make sure the value is live in the predecessor. if (Instruction *Inst = dyn_cast_or_null(V)) From baldrick at free.fr Tue Dec 8 00:39:48 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 06:39:48 -0000 Subject: [llvm-commits] [dragonegg] r90839 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912080639.nB86dm9x008705@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 00:39:48 2009 New Revision: 90839 URL: http://llvm.org/viewvc/llvm-project?rev=90839&view=rev Log: Look up the ultimate transparent alias when handling weakrefs. Not clear if this is really needed, but it matches do_assemble_alias better. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90839&r1=90838&r2=90839&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 00:39:48 2009 @@ -1639,6 +1639,10 @@ GlobalValue *V = cast(DECL_LLVM(decl)); GlobalValue *Aliasee; + bool weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)); + if (weakref) + while (IDENTIFIER_TRANSPARENT_ALIAS(target)) + target = TREE_CHAIN (target); if (TREE_CODE(target) == IDENTIFIER_NODE) { // This is something insane. Probably only LTHUNKs can be here @@ -1659,7 +1663,7 @@ } if (!Aliasee) { - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { + if (weakref) { if (GlobalVariable *GV = dyn_cast(V)) Aliasee = new GlobalVariable(*TheModule, GV->getType(), GV->isConstant(), From baldrick at free.fr Tue Dec 8 02:22:43 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 08:22:43 -0000 Subject: [llvm-commits] [dragonegg] r90844 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912080822.nB88Mh4s012510@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 02:22:43 2009 New Revision: 90844 URL: http://llvm.org/viewvc/llvm-project?rev=90844&view=rev Log: Reintroduce emit_same_body_alias, since this seems more logical and I am still fighting with getting their linkage right. Tidy the linkage logic in emit_alias_to_llvm. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90844&r1=90843&r2=90844&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 02:22:43 2009 @@ -1686,16 +1686,11 @@ GlobalValue::LinkageTypes Linkage; - // A weak alias has TREE_PUBLIC set but not the other bits. - if (false)//FIXME DECL_LLVM_PRIVATE(decl)) - Linkage = GlobalValue::PrivateLinkage; - else if (false)//FIXME DECL_LLVM_LINKER_PRIVATE(decl)) - Linkage = GlobalValue::LinkerPrivateLinkage; + if (!TREE_PUBLIC(decl)) + Linkage = GlobalValue::InternalLinkage; else if (DECL_WEAK(decl)) // The user may have explicitly asked for weak linkage - ignore flag_odr. Linkage = GlobalValue::WeakAnyLinkage; - else if (!TREE_PUBLIC(decl)) - Linkage = GlobalValue::InternalLinkage; else Linkage = GlobalValue::ExternalLinkage; @@ -1726,6 +1721,13 @@ TREE_ASM_WRITTEN(decl) = 1; } +/// emit_same_body_alias - Turn a same-body alias into LLVM IR. +static void emit_same_body_alias(struct cgraph_node *alias, + struct cgraph_node *target) { + assert(alias->thunk.alias == target->decl && "Unexpected alias target!"); + emit_alias_to_llvm(alias->decl, target->decl); +} + /// emit_functions - Turn all functions in the compilation unit into LLVM IR. static void emit_functions(cgraph_node_set set) { LazilyInitializeModule(); @@ -1744,12 +1746,10 @@ for (alias = node->same_body; alias && alias->next; alias = alias->next); for (; alias; alias = next) { next = alias->previous; - if (alias->thunk.thunk_p) { + if (alias->thunk.thunk_p) emit_thunk_to_llvm(alias); - } else { - assert(alias->thunk.alias == node->decl && "Unexpected alias target!"); - emit_alias_to_llvm(alias->decl, node->decl); - } + else + emit_same_body_alias(alias, node); } } } From baldrick at free.fr Tue Dec 8 02:24:13 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 08:24:13 -0000 Subject: [llvm-commits] [dragonegg] r90845 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912080824.nB88ODP6012573@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 02:24:13 2009 New Revision: 90845 URL: http://llvm.org/viewvc/llvm-project?rev=90845&view=rev Log: Remove unused function. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90845&r1=90844&r2=90845&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 02:24:13 2009 @@ -1452,11 +1452,6 @@ (isCtor ? &StaticCtors:&StaticDtors)->push_back(std::make_pair(Fn, InitPrio)); } -void llvm_emit_typedef(tree decl) { - // Need hooks for debug info? - return; -} - /// llvm_emit_file_scope_asm - Emit the specified string as a file-scope inline /// asm block. void llvm_emit_file_scope_asm(const char *string) { From baldrick at free.fr Tue Dec 8 02:34:57 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 08:34:57 -0000 Subject: [llvm-commits] [dragonegg] r90846 - in /dragonegg/trunk: bits_and_bobs.h llvm-backend.cpp llvm-convert.cpp Message-ID: <200912080834.nB88Yvat013154@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 02:34:56 2009 New Revision: 90846 URL: http://llvm.org/viewvc/llvm-project?rev=90846&view=rev Log: Drop "_to_llvm" from the names of a bunch of routines. This makes the emit naming scheme more uniform. Modified: dragonegg/trunk/bits_and_bobs.h dragonegg/trunk/llvm-backend.cpp dragonegg/trunk/llvm-convert.cpp Modified: dragonegg/trunk/bits_and_bobs.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/bits_and_bobs.h?rev=90846&r1=90845&r2=90846&view=diff ============================================================================== --- dragonegg/trunk/bits_and_bobs.h (original) +++ dragonegg/trunk/bits_and_bobs.h Tue Dec 8 02:34:56 2009 @@ -4,10 +4,9 @@ union tree_node; -// emit_global_to_llvm - Emit the specified VAR_DECL to LLVM as a global -// variable. +// emit_global - Emit the specified VAR_DECL to LLVM as a global variable. // FIXME: Should not be here -void emit_global_to_llvm(union tree_node*); +void emit_global(union tree_node*); extern bool flag_odr; Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90846&r1=90845&r2=90846&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 02:34:56 2009 @@ -943,7 +943,7 @@ // Visibility may also have changed. handleVisibility(decl, GV); - // Temporary to avoid infinite recursion (see comments emit_global_to_llvm) + // Temporary to avoid infinite recursion (see comments emit_global) GV->setInitializer(UndefValue::get(GV->getType()->getElementType())); // Convert the initializer over. @@ -975,10 +975,9 @@ GV->setInitializer(Init); } -/// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to -/// LLVM as a global variable. This function implements the end of -/// assemble_variable. -void emit_global_to_llvm(tree decl) { +/// emit_global - Emit the specified VAR_DECL or aggregate CONST_DECL to LLVM as +/// a global variable. This function implements the end of assemble_variable. +void emit_global(tree decl) { // FIXME: Support alignment on globals: DECL_ALIGN. // FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'. @@ -1014,10 +1013,9 @@ // Temporarily set an initializer for the global, so we don't infinitely // recurse. If we don't do this, we can hit cases where we see "oh a global - // with an initializer hasn't been initialized yet, call emit_global_to_llvm - // on it". When constructing the initializer it might refer to itself. - // this can happen for things like void *G = &G; - // + // with an initializer hasn't been initialized yet, call emit_global on it". + // When constructing the initializer it might refer to itself. + // This can happen for things like void *G = &G; GV->setInitializer(UndefValue::get(GV->getType()->getElementType())); Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); } @@ -1621,15 +1619,15 @@ pop_cfun (); } -/// emit_thunk_to_llvm - Turn a thunk into LLVM IR. -void emit_thunk_to_llvm(struct cgraph_node *thunk) { +/// emit_thunk - Turn a thunk into LLVM IR. +void emit_thunk(struct cgraph_node *thunk) { abort(); // Mark the thunk as written so gcc doesn't waste time outputting it. TREE_ASM_WRITTEN(thunk->decl) = 1; } -/// emit_alias_to_llvm - Given decl and target emit alias to target. -void emit_alias_to_llvm(tree decl, tree target) { +/// emit_alias - Given decl and target emit alias to target. +void emit_alias(tree decl, tree target) { // Get or create LLVM global for our alias. GlobalValue *V = cast(DECL_LLVM(decl)); @@ -1720,7 +1718,7 @@ static void emit_same_body_alias(struct cgraph_node *alias, struct cgraph_node *target) { assert(alias->thunk.alias == target->decl && "Unexpected alias target!"); - emit_alias_to_llvm(alias->decl, target->decl); + emit_alias(alias->decl, target->decl); } /// emit_functions - Turn all functions in the compilation unit into LLVM IR. @@ -1742,7 +1740,7 @@ for (; alias; alias = next) { next = alias->previous; if (alias->thunk.thunk_p) - emit_thunk_to_llvm(alias); + emit_thunk(alias); else emit_same_body_alias(alias, node); } @@ -1787,13 +1785,13 @@ FOR_EACH_STATIC_VARIABLE (vnode) { tree var = vnode->decl; if (TREE_CODE(var) == VAR_DECL && TREE_PUBLIC(var)) - emit_global_to_llvm(var); + emit_global(var); } // Emit any aliases. alias_pair *p; for (unsigned i = 0; VEC_iterate(alias_pair, alias_pairs, i, p); i++) - emit_alias_to_llvm(p->decl, p->target); + emit_alias(p->decl, p->target); } /// pass_emit_variables - IPA pass that turns GCC variables into LLVM IR. Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=90846&r1=90845&r2=90846&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Tue Dec 8 02:34:56 2009 @@ -6279,7 +6279,7 @@ if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) && GV->isDeclaration() && !BOGUS_CTOR(exp)) { - emit_global_to_llvm(exp); + emit_global(exp); Decl = DECL_LOCAL(exp); // Decl could have change if it changed type. } } else { @@ -7982,7 +7982,7 @@ if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) && Val->isDeclaration() && !BOGUS_CTOR(exp)) { - emit_global_to_llvm(exp); + emit_global(exp); // Decl could have change if it changed type. Val = cast(DECL_LLVM(exp)); } From baldrick at free.fr Tue Dec 8 04:10:21 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 10:10:21 -0000 Subject: [llvm-commits] [llvm] r90850 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll Message-ID: <200912081010.nB8AALGF031035@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 04:10:20 2009 New Revision: 90850 URL: http://llvm.org/viewvc/llvm-project?rev=90850&view=rev Log: Teach GlobalOpt to delete aliases with internal linkage (after forwarding any uses). GlobalDCE can also do this, but is only run at -O3. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=90850&r1=90849&r2=90850&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Tue Dec 8 04:10:20 2009 @@ -2493,29 +2493,28 @@ Changed = true; } - // If the aliasee has internal linkage, give it the name and linkage - // of the alias, and delete the alias. This turns: - // define internal ... @f(...) - // @a = alias ... @f - // into: - // define ... @a(...) - if (!Target->hasLocalLinkage()) - continue; - - // The transform is only useful if the alias does not have internal linkage. - if (J->hasLocalLinkage()) - continue; - - // Do not perform the transform if multiple aliases potentially target the - // aliasee. This check also ensures that it is safe to replace the section - // and other attributes of the aliasee with those of the alias. - if (!hasOneUse) - continue; - - // Give the aliasee the name, linkage and other attributes of the alias. - Target->takeName(J); - Target->setLinkage(J->getLinkage()); - Target->GlobalValue::copyAttributesFrom(J); + // If the alias is externally visible, we may still be able to simplify it. + if (!J->hasLocalLinkage()) { + // If the aliasee has internal linkage, give it the name and linkage + // of the alias, and delete the alias. This turns: + // define internal ... @f(...) + // @a = alias ... @f + // into: + // define ... @a(...) + if (!Target->hasLocalLinkage()) + continue; + + // Do not perform the transform if multiple aliases potentially target the + // aliasee. This check also ensures that it is safe to replace the section + // and other attributes of the aliasee with those of the alias. + if (!hasOneUse) + continue; + + // Give the aliasee the name, linkage and other attributes of the alias. + Target->takeName(J); + Target->setLinkage(J->getLinkage()); + Target->GlobalValue::copyAttributesFrom(J); + } // Delete the alias. M.getAliasList().erase(J); Modified: llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll?rev=90850&r1=90849&r2=90850&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll Tue Dec 8 04:10:20 2009 @@ -1,6 +1,8 @@ -; RUN: opt < %s -globalopt -S | grep {define void @a} +; RUN: opt < %s -globalopt -S | FileCheck %s define internal void @f() { +; CHECK-NOT: @f +; CHECK: define void @a ret void } @@ -10,3 +12,13 @@ call void()* @a() ret void } + + at b = alias internal void ()* @g +; CHECK-NOT: @b + +define void @h() { + call void()* @b() +; CHECK: call void @g + ret void +} + From benny.kra at googlemail.com Tue Dec 8 07:07:39 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 08 Dec 2009 13:07:39 -0000 Subject: [llvm-commits] [llvm] r90855 - /llvm/trunk/lib/VMCore/PassManager.cpp Message-ID: <200912081307.nB8D7dsR004973@zion.cs.uiuc.edu> Author: d0k Date: Tue Dec 8 07:07:38 2009 New Revision: 90855 URL: http://llvm.org/viewvc/llvm-project?rev=90855&view=rev Log: Remove useless calls to c_str(). Modified: llvm/trunk/lib/VMCore/PassManager.cpp Modified: llvm/trunk/lib/VMCore/PassManager.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassManager.cpp?rev=90855&r1=90854&r2=90855&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/PassManager.cpp (original) +++ llvm/trunk/lib/VMCore/PassManager.cpp Tue Dec 8 07:07:38 2009 @@ -1397,8 +1397,7 @@ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); - dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, - M.getModuleIdentifier().c_str()); + dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); dumpRequiredSet(MP); initializeAnalysisImpl(MP); @@ -1412,13 +1411,13 @@ if (Changed) dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, - M.getModuleIdentifier().c_str()); + M.getModuleIdentifier()); dumpPreservedSet(MP); verifyPreservedAnalysis(MP); removeNotPreservedAnalysis(MP); recordAvailableAnalysis(MP); - removeDeadPasses(MP, M.getModuleIdentifier().c_str(), ON_MODULE_MSG); + removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); } // Finalize on-the-fly passes From dpatel at apple.com Tue Dec 8 09:01:36 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 08 Dec 2009 15:01:36 -0000 Subject: [llvm-commits] [llvm] r90857 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/DebugInfo/2009-12-08-DeadGV.ll Message-ID: <200912081501.nB8F1aUL009096@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 8 09:01:35 2009 New Revision: 90857 URL: http://llvm.org/viewvc/llvm-project?rev=90857&view=rev Log: Do not try to push dead variable's debug info into namespace info. Added: llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90857&r1=90856&r2=90857&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Dec 8 09:01:35 2009 @@ -1837,9 +1837,11 @@ constructGlobalVariableDIE(*I); else if (GVContext.isNameSpace()) { DIE *GVDie = createGlobalVariableDIE(ModuleCU, GV); - DINameSpace NS(GVContext.getNode()); - DIE *NDie = getOrCreateNameSpace(NS); - NDie->addChild(GVDie); + if (GVDie) { + DINameSpace NS(GVContext.getNode()); + DIE *NDie = getOrCreateNameSpace(NS); + NDie->addChild(GVDie); + } } else ScopedGVs.push_back(*I); Added: llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll?rev=90857&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll (added) +++ llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll Tue Dec 8 09:01:35 2009 @@ -0,0 +1,18 @@ +; RUN: llc %s -o /dev/null +; PR 5713 + +define i32 @_Z3foov() nounwind readnone ssp { +entry: + ret i32 0, !dbg !4 +} + +!llvm.dbg.gv = !{!0} + +!0 = metadata !{i32 458804, i32 0, metadata !1, metadata !"X", metadata !"X", metadata !"_ZN1A1XE", metadata !2, i32 3, metadata !3, i1 false, i1 true, null}; [DW_TAG_variable ] +!1 = metadata !{i32 458809, metadata !2, metadata !"A", metadata !2, i32 2}; [DW_TAG_namespace ] +!2 = metadata !{i32 458769, i32 0, i32 4, metadata !"ng.cc", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5653) (LLVM build)", i1 true, i1 true, metadata !"", i32 0}; [DW_TAG_compile_unit ] +!3 = metadata !{i32 458788, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ] +!4 = metadata !{i32 7, i32 0, metadata !5, null} +!5 = metadata !{i32 458798, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3foov", metadata !2, i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null}; [DW_TAG_subprogram ] +!6 = metadata !{i32 458773, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0}; [DW_TAG_subroutine_type ] +!7 = metadata !{metadata !3} From dpatel at apple.com Tue Dec 8 09:31:32 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 08 Dec 2009 15:31:32 -0000 Subject: [llvm-commits] [llvm] r90858 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200912081531.nB8FVWII010188@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 8 09:31:31 2009 New Revision: 90858 URL: http://llvm.org/viewvc/llvm-project?rev=90858&view=rev Log: Cleanup. There is no need to supply ModuleCU to addType() as a parameter. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90858&r1=90857&r2=90858&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Dec 8 09:31:31 2009 @@ -756,12 +756,12 @@ } /// addType - Add a new type attribute to the specified entity. -void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { +void DwarfDebug::addType(DIE *Entity, DIType Ty) { if (Ty.isNull()) return; // Check for pre-existence. - DIEEntry *Entry = DW_Unit->getDIEEntry(Ty.getNode()); + DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode()); // If it exists then use the existing value. if (Entry) { @@ -771,18 +771,18 @@ // Set up proxy. Entry = createDIEEntry(); - DW_Unit->insertDIEEntry(Ty.getNode(), Entry); + ModuleCU->insertDIEEntry(Ty.getNode(), Entry); // Construct type. DIE *Buffer = new DIE(dwarf::DW_TAG_base_type); ModuleCU->insertDIE(Ty.getNode(), Buffer); if (Ty.isBasicType()) - constructTypeDIE(DW_Unit, *Buffer, DIBasicType(Ty.getNode())); + constructTypeDIE(*Buffer, DIBasicType(Ty.getNode())); else if (Ty.isCompositeType()) - constructTypeDIE(DW_Unit, *Buffer, DICompositeType(Ty.getNode())); + constructTypeDIE(*Buffer, DICompositeType(Ty.getNode())); else { assert(Ty.isDerivedType() && "Unknown kind of DIType"); - constructTypeDIE(DW_Unit, *Buffer, DIDerivedType(Ty.getNode())); + constructTypeDIE(*Buffer, DIDerivedType(Ty.getNode())); } // Add debug information entry to entity and appropriate context. @@ -793,19 +793,18 @@ DINameSpace NS(Context.getNode()); Die = getOrCreateNameSpace(NS); } else - Die = DW_Unit->getDIE(Context.getNode()); + Die = ModuleCU->getDIE(Context.getNode()); } if (Die) Die->addChild(Buffer); else - DW_Unit->addDie(Buffer); + ModuleCU->addDie(Buffer); Entry->setEntry(Buffer); Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); } /// constructTypeDIE - Construct basic type die from DIBasicType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DIBasicType BTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { // Get core information. StringRef Name = BTy.getName(); Buffer.setTag(dwarf::DW_TAG_base_type); @@ -820,8 +819,7 @@ } /// constructTypeDIE - Construct derived type die from DIDerivedType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DIDerivedType DTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { // Get core information. StringRef Name = DTy.getName(); uint64_t Size = DTy.getSizeInBits() >> 3; @@ -834,7 +832,7 @@ // Map to main type, void will not have a type. DIType FromTy = DTy.getTypeDerivedFrom(); - addType(DW_Unit, &Buffer, FromTy); + addType(&Buffer, FromTy); // Add name if not anonymous or intermediate type. if (!Name.empty()) @@ -850,8 +848,7 @@ } /// constructTypeDIE - Construct type DIE from DICompositeType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DICompositeType CTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { // Get core information. StringRef Name = CTy.getName(); @@ -862,7 +859,7 @@ switch (Tag) { case dwarf::DW_TAG_vector_type: case dwarf::DW_TAG_array_type: - constructArrayTypeDIE(DW_Unit, Buffer, &CTy); + constructArrayTypeDIE(Buffer, &CTy); break; case dwarf::DW_TAG_enumeration_type: { DIArray Elements = CTy.getTypeArray(); @@ -872,7 +869,7 @@ DIE *ElemDie = NULL; DIEnumerator Enum(Elements.getElement(i).getNode()); if (!Enum.isNull()) { - ElemDie = constructEnumTypeDIE(DW_Unit, &Enum); + ElemDie = constructEnumTypeDIE(&Enum); Buffer.addChild(ElemDie); } } @@ -882,7 +879,7 @@ // Add return type. DIArray Elements = CTy.getTypeArray(); DIDescriptor RTy = Elements.getElement(0); - addType(DW_Unit, &Buffer, DIType(RTy.getNode())); + addType(&Buffer, DIType(RTy.getNode())); // Add prototype flag. addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); @@ -891,7 +888,7 @@ for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); DIDescriptor Ty = Elements.getElement(i); - addType(DW_Unit, Arg, DIType(Ty.getNode())); + addType(Arg, DIType(Ty.getNode())); Buffer.addChild(Arg); } } @@ -913,11 +910,9 @@ continue; DIE *ElemDie = NULL; if (Element.getTag() == dwarf::DW_TAG_subprogram) - ElemDie = createMemberSubprogramDIE(DW_Unit, - DISubprogram(Element.getNode())); + ElemDie = createMemberSubprogramDIE(DISubprogram(Element.getNode())); else - ElemDie = createMemberDIE(DW_Unit, - DIDerivedType(Element.getNode())); + ElemDie = createMemberDIE(DIDerivedType(Element.getNode())); Buffer.addChild(ElemDie); } @@ -972,26 +967,26 @@ } /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. -void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, +void DwarfDebug::constructArrayTypeDIE(DIE &Buffer, DICompositeType *CTy) { Buffer.setTag(dwarf::DW_TAG_array_type); if (CTy->getTag() == dwarf::DW_TAG_vector_type) addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); // Emit derived type. - addType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom()); + addType(&Buffer, CTy->getTypeDerivedFrom()); DIArray Elements = CTy->getTypeArray(); // Get an anonymous type for index type. - DIE *IdxTy = DW_Unit->getIndexTyDie(); + DIE *IdxTy = ModuleCU->getIndexTyDie(); if (!IdxTy) { // Construct an anonymous type for index type. IdxTy = new DIE(dwarf::DW_TAG_base_type); addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, dwarf::DW_ATE_signed); - DW_Unit->addDie(IdxTy); - DW_Unit->setIndexTyDie(IdxTy); + ModuleCU->addDie(IdxTy); + ModuleCU->setIndexTyDie(IdxTy); } // Add subranges to array type. @@ -1003,7 +998,7 @@ } /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. -DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) { +DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) { DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); StringRef Name = ETy->getName(); addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); @@ -1013,8 +1008,7 @@ } /// createGlobalVariableDIE - Create new DIE using GV. -DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit, - const DIGlobalVariable &GV) { +DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) { // If the global variable was optmized out then no need to create debug info // entry. if (!GV.getGlobal()) return NULL; @@ -1035,7 +1029,7 @@ addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, LinkageName); } - addType(DW_Unit, GVDie, GV.getType()); + addType(GVDie, GV.getType()); if (!GV.isLocalToUnit()) addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); addSourceLine(GVDie, &GV); @@ -1051,13 +1045,13 @@ } /// createMemberDIE - Create new member DIE. -DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){ +DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) { DIE *MemberDie = new DIE(DT.getTag()); StringRef Name = DT.getName(); if (!Name.empty()) addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - addType(DW_Unit, MemberDie, DT.getTypeDerivedFrom()); + addType(MemberDie, DT.getTypeDerivedFrom()); addSourceLine(MemberDie, &DT); @@ -1111,8 +1105,7 @@ /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. -DIE *DwarfDebug::createRawSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createRawSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram); addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); @@ -1141,9 +1134,9 @@ unsigned SPTag = SPTy.getTag(); if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type) - addType(DW_Unit, SPDie, SPTy); + addType(SPDie, SPTy); else - addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode())); + addType(SPDie, DIType(Args.getElement(0).getNode())); unsigned VK = SP.getVirtuality(); if (VK) { @@ -1160,11 +1153,10 @@ /// createMemberSubprogramDIE - Create new member DIE using SP. This routine /// always returns a die with DW_AT_declaration attribute. -DIE *DwarfDebug::createMemberSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createMemberSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (!SPDie) - SPDie = createSubprogramDIE(DW_Unit, SP); + SPDie = createSubprogramDIE(SP); // If SPDie has DW_AT_declaration then reuse it. if (!SP.isDefinition()) @@ -1175,7 +1167,7 @@ if (TopLevelDIEs.insert(SPDie)) TopLevelDIEsVector.push_back(SPDie); - SPDie = createRawSubprogramDIE(DW_Unit, SP); + SPDie = createRawSubprogramDIE(SP); // Add arguments. DICompositeType SPTy = SP.getType(); @@ -1184,7 +1176,7 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); + addType(Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } @@ -1194,13 +1186,12 @@ } /// createSubprogramDIE - Create new DIE using SP. -DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (SPDie) return SPDie; - SPDie = createRawSubprogramDIE(DW_Unit, SP); + SPDie = createRawSubprogramDIE(SP); if (!SP.isDefinition()) { addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); @@ -1214,14 +1205,14 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); + addType(Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } } // DW_TAG_inlined_subroutine may refer to this DIE. - DW_Unit->insertDIE(SP.getNode(), SPDie); + ModuleCU->insertDIE(SP.getNode(), SPDie); return SPDie; } @@ -1234,64 +1225,6 @@ return *I->second; } -/// createDbgScopeVariable - Create a new scope variable. -/// -DIE *DwarfDebug::createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { - // Get the descriptor. - const DIVariable &VD = DV->getVariable(); - StringRef Name = VD.getName(); - if (Name.empty()) - return NULL; - - // Translate tag to proper Dwarf tag. The result variable is dropped for - // now. - unsigned Tag; - switch (VD.getTag()) { - case dwarf::DW_TAG_return_variable: - return NULL; - case dwarf::DW_TAG_arg_variable: - Tag = dwarf::DW_TAG_formal_parameter; - break; - case dwarf::DW_TAG_auto_variable: // fall thru - default: - Tag = dwarf::DW_TAG_variable; - break; - } - - // Define variable debug information entry. - DIE *VariableDie = new DIE(Tag); - addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - - // Add source line info if available. - addSourceLine(VariableDie, &VD); - - // Add variable type. - // FIXME: isBlockByrefVariable should be reformulated in terms of complex - // addresses instead. - if (VD.isBlockByrefVariable()) - addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); - else - addType(Unit, VariableDie, VD.getType()); - - // Add variable address. - // Variables for abstract instances of inlined functions don't get a - // location. - MachineLocation Location; - unsigned FrameReg; - int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); - Location.set(FrameReg, Offset); - - - if (VD.hasComplexAddress()) - addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else if (VD.isBlockByrefVariable()) - addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else - addAddress(VariableDie, dwarf::DW_AT_location, Location); - - return VariableDie; -} - /// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. /// Initialize scope and update scope hierarchy. DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, @@ -1397,7 +1330,7 @@ if (!N) continue; DIGlobalVariable GV(N); if (GV.getContext().getNode() == SPNode) { - DIE *ScopedGVDie = createGlobalVariableDIE(ModuleCU, GV); + DIE *ScopedGVDie = createGlobalVariableDIE(GV); if (ScopedGVDie) SPDie->addChild(ScopedGVDie); } @@ -1486,8 +1419,7 @@ /// constructVariableDIE - Construct a DIE for the given DbgVariable. -DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, - DbgScope *Scope, CompileUnit *Unit) { +DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { // Get the descriptor. const DIVariable &VD = DV->getVariable(); StringRef Name = VD.getName(); @@ -1536,9 +1468,9 @@ // FIXME: isBlockByrefVariable should be reformulated in terms of complex // addresses instead. if (VD.isBlockByrefVariable()) - addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); + addType(VariableDie, getBlockByrefType(VD.getType(), Name)); else - addType(Unit, VariableDie, VD.getType()); + addType(VariableDie, VD.getType()); } // Add variable address. @@ -1607,7 +1539,7 @@ // Add variables to scope. SmallVector &Variables = Scope->getVariables(); for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDIE = constructVariableDIE(Variables[i], Scope, ModuleCU); + DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); if (VariableDIE) ScopeDIE->addChild(VariableDIE); } @@ -1739,7 +1671,7 @@ if (ModuleCU->getDIE(DI_GV.getNode())) return; - DIE *VariableDie = createGlobalVariableDIE(ModuleCU, DI_GV); + DIE *VariableDie = createGlobalVariableDIE(DI_GV); // Add to map. ModuleCU->insertDIE(N, VariableDie); @@ -1772,7 +1704,7 @@ // class type. return; - DIE *SubprogramDie = createSubprogramDIE(ModuleCU, SP); + DIE *SubprogramDie = createSubprogramDIE(SP); // Add to map. ModuleCU->insertDIE(N, SubprogramDie); @@ -1836,7 +1768,7 @@ && GVContext.getNode() == GV.getCompileUnit().getNode()) constructGlobalVariableDIE(*I); else if (GVContext.isNameSpace()) { - DIE *GVDie = createGlobalVariableDIE(ModuleCU, GV); + DIE *GVDie = createGlobalVariableDIE(GV); if (GVDie) { DINameSpace NS(GVContext.getNode()); DIE *NDie = getOrCreateNameSpace(NS); @@ -2480,13 +2412,16 @@ } } -/// emitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. +/// emitDebugInfo - Emit the debug info section. /// -void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) { - DIE *Die = Unit->getCUDie(); +void DwarfDebug::emitDebugInfo() { + // Start debug info section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfInfoSection()); + DIE *Die = ModuleCU->getCUDie(); // Emit the compile units header. - EmitLabel("info_begin", Unit->getID()); + EmitLabel("info_begin", ModuleCU->getID()); // Emit size of content not including length itself unsigned ContentSize = Die->getSize() + @@ -2507,17 +2442,10 @@ Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - EmitLabel("info_end", Unit->getID()); + EmitLabel("info_end", ModuleCU->getID()); Asm->EOL(); -} - -void DwarfDebug::emitDebugInfo() { - // Start debug info section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfInfoSection()); - emitDebugInfoPerCU(ModuleCU); } /// emitAbbreviations - Emit the abbreviation section. @@ -2815,24 +2743,30 @@ Asm->EOL(); } -void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) { - EmitDifference("pubnames_end", Unit->getID(), - "pubnames_begin", Unit->getID(), true); +/// emitDebugPubNames - Emit visible names into a debug pubnames section. +/// +void DwarfDebug::emitDebugPubNames() { + // Start the dwarf pubnames section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfPubNamesSection()); + + EmitDifference("pubnames_end", ModuleCU->getID(), + "pubnames_begin", ModuleCU->getID(), true); Asm->EOL("Length of Public Names Info"); - EmitLabel("pubnames_begin", Unit->getID()); + EmitLabel("pubnames_begin", ModuleCU->getID()); Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); EmitSectionOffset("info_begin", "section_info", - Unit->getID(), 0, true, false); + ModuleCU->getID(), 0, true, false); Asm->EOL("Offset of Compilation Unit Info"); - EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(), + EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), true); Asm->EOL("Compilation Unit Length"); - const StringMap &Globals = Unit->getGlobals(); + const StringMap &Globals = ModuleCU->getGlobals(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); @@ -2843,21 +2777,11 @@ } Asm->EmitInt32(0); Asm->EOL("End Mark"); - EmitLabel("pubnames_end", Unit->getID()); + EmitLabel("pubnames_end", ModuleCU->getID()); Asm->EOL(); } -/// emitDebugPubNames - Emit visible names into a debug pubnames section. -/// -void DwarfDebug::emitDebugPubNames() { - // Start the dwarf pubnames section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfPubNamesSection()); - - emitDebugPubNamesPerCU(ModuleCU); -} - void DwarfDebug::emitDebugPubTypes() { // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection( Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=90858&r1=90857&r2=90858&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Dec 8 09:31:31 2009 @@ -315,63 +315,58 @@ const MachineLocation &Location); /// addType - Add a new type attribute to the specified entity. - void addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty); + void addType(DIE *Entity, DIType Ty); void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DIBasicType BTy); /// constructTypeDIE - Construct derived type die from DIDerivedType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DIDerivedType DTy); /// constructTypeDIE - Construct type DIE from DICompositeType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DICompositeType CTy); /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy); /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. - void constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructArrayTypeDIE(DIE &Buffer, DICompositeType *CTy); /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. - DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy); + DIE *constructEnumTypeDIE(DIEnumerator *ETy); /// getOrCreateNameSpace - Create a DIE for DINameSpace. DIE *getOrCreateNameSpace(DINameSpace &NS); /// createGlobalVariableDIE - Create new DIE using GV. - DIE *createGlobalVariableDIE(CompileUnit *DW_Unit, - const DIGlobalVariable &GV); + DIE *createGlobalVariableDIE(const DIGlobalVariable &GV); /// createMemberDIE - Create new member DIE. - DIE *createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT); + DIE *createMemberDIE(const DIDerivedType &DT); /// createSubprogramDIE - Create new DIE using SP. - DIE *createSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createSubprogramDIE(const DISubprogram &SP); /// createMemberSubprogramDIE - Create new member DIE using SP. This /// routine always returns a die with DW_AT_declaration attribute. - DIE *createMemberSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createMemberSubprogramDIE(const DISubprogram &SP); /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. - DIE *createRawSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createRawSubprogramDIE(const DISubprogram &SP); /// findCompileUnit - Get the compile unit for the given descriptor. /// CompileUnit &findCompileUnit(DICompileUnit Unit) const; - /// createDbgScopeVariable - Create a new scope variable. - /// - DIE *createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit); - /// getUpdatedDbgScope - Find or create DbgScope assicated with /// the instruction. Initialize scope and update scope hierarchy. DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); @@ -401,7 +396,7 @@ DIE *constructInlinedScopeDIE(DbgScope *Scope); /// constructVariableDIE - Construct a DIE for the given DbgVariable. - DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit); + DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S); /// constructScopeDIE - Construct a DIE for this scope. DIE *constructScopeDIE(DbgScope *Scope); @@ -422,10 +417,8 @@ /// void computeSizeAndOffsets(); - /// EmitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. + /// EmitDebugInfo - Emit the debug info section. /// - void emitDebugInfoPerCU(CompileUnit *Unit); - void emitDebugInfo(); /// emitAbbreviations - Emit the abbreviation section. @@ -449,8 +442,6 @@ /// section. void emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo); - void emitDebugPubNamesPerCU(CompileUnit *Unit); - /// emitDebugPubNames - Emit visible names into a debug pubnames section. /// void emitDebugPubNames(); From baldrick at free.fr Tue Dec 8 11:28:32 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 17:28:32 -0000 Subject: [llvm-commits] [dragonegg] r90862 - /dragonegg/trunk/gcc-patches/lto_flags.diff Message-ID: <200912081728.nB8HSWU5014183@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 11:28:31 2009 New Revision: 90862 URL: http://llvm.org/viewvc/llvm-project?rev=90862&view=rev Log: Need to note the new #include in Makefile.in, as pointed out by Rafael. Modified: dragonegg/trunk/gcc-patches/lto_flags.diff Modified: dragonegg/trunk/gcc-patches/lto_flags.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/lto_flags.diff?rev=90862&r1=90861&r2=90862&view=diff ============================================================================== --- dragonegg/trunk/gcc-patches/lto_flags.diff (original) +++ dragonegg/trunk/gcc-patches/lto_flags.diff Tue Dec 8 11:28:31 2009 @@ -1,7 +1,7 @@ Index: mainline/gcc/cgraphunit.c =================================================================== ---- mainline.orig/gcc/cgraphunit.c 2009-12-05 13:39:51.034414478 +0100 -+++ mainline/gcc/cgraphunit.c 2009-12-05 13:44:22.576904063 +0100 +--- mainline.orig/gcc/cgraphunit.c 2009-12-08 17:31:41.004321857 +0100 ++++ mainline/gcc/cgraphunit.c 2009-12-08 17:36:47.211914685 +0100 @@ -358,8 +358,7 @@ && !DECL_DECLARED_INLINE_P (decl) && !node->origin)) @@ -14,8 +14,8 @@ Index: mainline/gcc/ipa-cp.c =================================================================== ---- mainline.orig/gcc/ipa-cp.c 2009-12-05 13:39:51.074413887 +0100 -+++ mainline/gcc/ipa-cp.c 2009-12-05 13:44:22.576904063 +0100 +--- mainline.orig/gcc/ipa-cp.c 2009-12-08 17:31:41.024330339 +0100 ++++ mainline/gcc/ipa-cp.c 2009-12-08 17:36:47.221953358 +0100 @@ -628,7 +628,7 @@ { /* We do not need to bother analyzing calls to unknown @@ -27,8 +27,8 @@ if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) Index: mainline/gcc/ipa.c =================================================================== ---- mainline.orig/gcc/ipa.c 2009-12-05 13:39:51.094413696 +0100 -+++ mainline/gcc/ipa.c 2009-12-05 13:44:22.576904063 +0100 +--- mainline.orig/gcc/ipa.c 2009-12-08 17:31:41.034318098 +0100 ++++ mainline/gcc/ipa.c 2009-12-08 17:36:47.231861147 +0100 @@ -27,6 +27,7 @@ #include "timevar.h" #include "gimple.h" @@ -48,8 +48,8 @@ struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility = Index: mainline/gcc/varpool.c =================================================================== ---- mainline.orig/gcc/varpool.c 2009-12-05 13:39:51.044386864 +0100 -+++ mainline/gcc/varpool.c 2009-12-05 13:44:22.576904063 +0100 +--- mainline.orig/gcc/varpool.c 2009-12-08 17:31:41.004321857 +0100 ++++ mainline/gcc/varpool.c 2009-12-08 17:36:47.241964425 +0100 @@ -244,8 +244,7 @@ COMDAT variables that must be output only when they are needed. */ if (TREE_PUBLIC (decl) @@ -62,8 +62,8 @@ return true; Index: mainline/gcc/fortran/options.c =================================================================== ---- mainline.orig/gcc/fortran/options.c 2009-12-05 13:39:51.064386464 +0100 -+++ mainline/gcc/fortran/options.c 2009-12-05 13:44:22.576904063 +0100 +--- mainline.orig/gcc/fortran/options.c 2009-12-08 17:31:41.014317857 +0100 ++++ mainline/gcc/fortran/options.c 2009-12-08 17:36:47.241964425 +0100 @@ -243,7 +243,7 @@ gfc_option.flag_whole_file = 1; @@ -73,3 +73,16 @@ gfc_option.flag_whole_file = 1; /* -fbounds-check is equivalent to -fcheck=bounds */ +Index: mainline/gcc/Makefile.in +=================================================================== +--- mainline.orig/gcc/Makefile.in 2009-12-08 17:31:41.024330339 +0100 ++++ mainline/gcc/Makefile.in 2009-12-08 17:36:47.251874518 +0100 +@@ -2876,7 +2876,7 @@ + $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \ + $(TREE_FLOW_H) gt-varpool.h + ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ +- $(TREE_PASS_H) $(TIMEVAR_H) $(GIMPLE_H) $(GGC_H) ++ $(TREE_PASS_H) $(TIMEVAR_H) $(GIMPLE_H) $(GGC_H) $(FLAGS_H) + ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ + $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ From bob.wilson at apple.com Tue Dec 8 12:22:04 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 08 Dec 2009 18:22:04 -0000 Subject: [llvm-commits] [llvm] r90864 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200912081822.nB8IM4VM016373@zion.cs.uiuc.edu> Author: bwilson Date: Tue Dec 8 12:22:03 2009 New Revision: 90864 URL: http://llvm.org/viewvc/llvm-project?rev=90864&view=rev Log: Clean up dead operands left around after SROA replaces a mem intrinsic. I'm not aware that this does anything significant on its own, but it's needed for another patch that I'm working on. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=90864&r1=90863&r2=90864&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Dec 8 12:22:03 2009 @@ -769,6 +769,10 @@ OtherPtr = MTI->getRawDest(); } } + + // Keep track of the other intrinsic argument, so it can be removed if it + // is dead when the intrinsic is replaced. + Value *PossiblyDead = OtherPtr; // If there is an other pointer, we want to convert it to the same pointer // type as AI has, so we can GEP through it safely. @@ -922,6 +926,8 @@ } } MI->eraseFromParent(); + if (PossiblyDead) + RecursivelyDeleteTriviallyDeadInstructions(PossiblyDead); } /// RewriteStoreUserOfWholeAlloca - We found a store of an integer that From bob.wilson at apple.com Tue Dec 8 12:27:03 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 08 Dec 2009 18:27:03 -0000 Subject: [llvm-commits] [llvm] r90866 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200912081827.nB8IR4w0016583@zion.cs.uiuc.edu> Author: bwilson Date: Tue Dec 8 12:27:03 2009 New Revision: 90866 URL: http://llvm.org/viewvc/llvm-project?rev=90866&view=rev Log: Some superficial cleanups. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=90866&r1=90865&r2=90866&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Dec 8 12:27:03 2009 @@ -105,7 +105,7 @@ void isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, AllocaInfo &Info); void isSafeElementUse(Value *Ptr, bool isFirstElt, AllocaInst *AI, - AllocaInfo &Info); + AllocaInfo &Info); void isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocaInst *AI, unsigned OpNo, AllocaInfo &Info); void isSafeUseOfBitCastedAllocation(BitCastInst *User, AllocaInst *AI, @@ -362,7 +362,6 @@ // Now that we have created the alloca instructions that we want to use, // expand the getelementptr instructions to use them. - // while (!AI->use_empty()) { Instruction *User = cast(AI->use_back()); if (BitCastInst *BCInst = dyn_cast(User)) { @@ -540,7 +539,7 @@ return true; } -/// isSafeUseOfAllocation - Check to see if this user is an allowed use for an +/// isSafeUseOfAllocation - Check if this user is an allowed use for an /// aggregate allocation. void SROA::isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, AllocaInfo &Info) { @@ -1216,7 +1215,7 @@ return Info.needsCleanup ? 1 : 3; } -/// CleanupGEP - GEP is used by an Alloca, which can be prompted after the GEP +/// CleanupGEP - GEP is used by an Alloca, which can be promoted after the GEP /// is canonicalized here. void SROA::CleanupGEP(GetElementPtrInst *GEPI) { gep_type_iterator I = gep_type_begin(GEPI); From evan.cheng at apple.com Tue Dec 8 13:34:53 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 08 Dec 2009 19:34:53 -0000 Subject: [llvm-commits] [llvm] r90868 - /llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Message-ID: <200912081934.nB8JYrgB018924@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 13:34:53 2009 New Revision: 90868 URL: http://llvm.org/viewvc/llvm-project?rev=90868&view=rev Log: Revert 90789 for now. It caused massive compile time regression. Post-ra scheduler slowed down dramatically with this. Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=90868&r1=90867&r2=90868&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Tue Dec 8 13:34:53 2009 @@ -300,7 +300,7 @@ /// considered to be a 'virtual' register, which is part of the SSA /// namespace. This must be the same for all targets, which means that each /// target is limited to this fixed number of registers. - FirstVirtualRegister = 16384 + FirstVirtualRegister = 1024 }; /// isPhysicalRegister - Return true if the specified register number is in From daniel at zuster.org Tue Dec 8 13:47:36 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 08 Dec 2009 19:47:36 -0000 Subject: [llvm-commits] [llvm] r90869 - in /llvm/trunk/test: CMakeLists.txt Unit/lit.cfg lit.cfg Message-ID: <200912081947.nB8JlbmR019319@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Dec 8 13:47:36 2009 New Revision: 90869 URL: http://llvm.org/viewvc/llvm-project?rev=90869&view=rev Log: CMake/lit: Add llvm_{unit_,}site_config parameters, and always pass them when running tests from the project files. Modified: llvm/trunk/test/CMakeLists.txt llvm/trunk/test/Unit/lit.cfg llvm/trunk/test/lit.cfg Modified: llvm/trunk/test/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=90869&r1=90868&r2=90869&view=diff ============================================================================== --- llvm/trunk/test/CMakeLists.txt (original) +++ llvm/trunk/test/CMakeLists.txt Tue Dec 8 13:47:36 2009 @@ -31,6 +31,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg COMMAND ${PYTHON_EXECUTABLE} ${LLVM_SOURCE_DIR}/utils/lit/lit.py + --param llvm_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + --param llvm_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg -sv ${CMAKE_CURRENT_BINARY_DIR} DEPENDS Modified: llvm/trunk/test/Unit/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Unit/lit.cfg?rev=90869&r1=90868&r2=90869&view=diff ============================================================================== --- llvm/trunk/test/Unit/lit.cfg (original) +++ llvm/trunk/test/Unit/lit.cfg Tue Dec 8 13:47:36 2009 @@ -32,6 +32,12 @@ # configuration hasn't been created by the build system, or we are in an # out-of-tree build situation). + # Check for 'llvm_unit_site_config' user parameter, and use that if available. + site_cfg = lit.params.get('llvm_unit_site_config', None) + if site_cfg and os.path.exists(site_cfg): + lit.load_config(config, site_cfg) + raise SystemExit + # Try to detect the situation where we are using an out-of-tree build by # looking for 'llvm-config'. # Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=90869&r1=90868&r2=90869&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Tue Dec 8 13:47:36 2009 @@ -58,6 +58,12 @@ # configuration hasn't been created by the build system, or we are in an # out-of-tree build situation). + # Check for 'llvm_site_config' user parameter, and use that if available. + site_cfg = lit.params.get('llvm_site_config', None) + if site_cfg and os.path.exists(site_cfg): + lit.load_config(config, site_cfg) + raise SystemExit + # Try to detect the situation where we are using an out-of-tree build by # looking for 'llvm-config'. # From daniel at zuster.org Tue Dec 8 13:48:01 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 08 Dec 2009 19:48:01 -0000 Subject: [llvm-commits] [llvm] r90870 - /llvm/trunk/tools/ Message-ID: <200912081948.nB8Jm1CA019341@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Dec 8 13:48:01 2009 New Revision: 90870 URL: http://llvm.org/viewvc/llvm-project?rev=90870&view=rev Log: Set svn:ignore on tools/clang. Modified: llvm/trunk/tools/ (props changed) Propchange: llvm/trunk/tools/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Dec 8 13:48:01 2009 @@ -0,0 +1 @@ +clang From daniel at zuster.org Tue Dec 8 13:49:30 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 08 Dec 2009 19:49:30 -0000 Subject: [llvm-commits] [llvm] r90871 - /llvm/trunk/utils/lit/lit.py Message-ID: <200912081949.nB8JnU59019393@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Dec 8 13:49:30 2009 New Revision: 90871 URL: http://llvm.org/viewvc/llvm-project?rev=90871&view=rev Log: lit: Prevent crash-on-invalid (when run on directory which has no test suite). Modified: llvm/trunk/utils/lit/lit.py Modified: llvm/trunk/utils/lit/lit.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit.py?rev=90871&r1=90870&r2=90871&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit.py (original) +++ llvm/trunk/utils/lit/lit.py Tue Dec 8 13:49:30 2009 @@ -230,7 +230,7 @@ ts,path_in_suite = getTestSuite(path, litConfig, testSuiteCache) if ts is None: litConfig.warning('unable to find test suite for %r' % path) - return () + return (),() if litConfig.debug: litConfig.note('resolved input %r to %r::%r' % (path, ts.name, From baldrick at free.fr Tue Dec 8 15:17:07 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 21:17:07 -0000 Subject: [llvm-commits] [dragonegg] r90877 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912082117.nB8LH7Tg022689@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 15:17:07 2009 New Revision: 90877 URL: http://llvm.org/viewvc/llvm-project?rev=90877&view=rev Log: After some experimentation, these linkage settings for aliases seem both fairly logical and result in much the same output as with gcc. (Now that there are also same-body aliases, which are basically multiple names for the same C++ ctor/dtor, the alias zoo became larger and harder to get right, or close to right). Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90877&r1=90876&r2=90877&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 15:17:07 2009 @@ -1677,38 +1677,41 @@ Aliasee = cast(DECL_LLVM(target)); } - GlobalValue::LinkageTypes Linkage; + GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage; - if (!TREE_PUBLIC(decl)) + if (DECL_COMDAT(decl)) + // Need not be put out unless needed in this translation unit. Linkage = GlobalValue::InternalLinkage; + else if (DECL_ONE_ONLY(decl)) + // Copies of this DECL in multiple translation units should be merged. + Linkage = GlobalValue::WeakODRLinkage; else if (DECL_WEAK(decl)) // The user may have explicitly asked for weak linkage - ignore flag_odr. Linkage = GlobalValue::WeakAnyLinkage; - else - Linkage = GlobalValue::ExternalLinkage; - - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", - Aliasee, TheModule); + else if (!TREE_PUBLIC(decl)) + // Not accessible from outside this translation unit. + Linkage = GlobalValue::InternalLinkage; + else if (DECL_EXTERNAL(decl)) + // Do not allocate storage, and refer to a definition elsewhere. + Linkage = GlobalValue::InternalLinkage; - handleVisibility(decl, GA); + if (Linkage != GlobalValue::InternalLinkage) { + // Create the LLVM alias. + GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", + Aliasee, TheModule); + handleVisibility(decl, GA); - if (GA->getType()->canLosslesslyBitCastTo(V->getType())) + // Associate it with decl instead of V. V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType())); - else if (!V->use_empty()) { - error ("%J Alias %qD used with invalid type!", decl, decl); - return; + changeLLVMConstant(V, GA); + GA->takeName(V); + } else { + // Make all users of the alias directly use the aliasee instead. + V->replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee, V->getType())); + changeLLVMConstant(V, Aliasee); } - changeLLVMConstant(V, GA); - GA->takeName(V); - if (GlobalVariable *GV = dyn_cast(V)) - GV->eraseFromParent(); - else if (GlobalAlias *GA = dyn_cast(V)) - GA->eraseFromParent(); - else if (Function *F = dyn_cast(V)) - F->eraseFromParent(); - else - assert(0 && "Unsuported global value"); + V->eraseFromParent(); // Mark the alias as written so gcc doesn't waste time outputting it. TREE_ASM_WRITTEN(decl) = 1; From baldrick at free.fr Tue Dec 8 15:18:28 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 08 Dec 2009 21:18:28 -0000 Subject: [llvm-commits] [dragonegg] r90878 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912082118.nB8LIS8i022741@zion.cs.uiuc.edu> Author: baldrick Date: Tue Dec 8 15:18:28 2009 New Revision: 90878 URL: http://llvm.org/viewvc/llvm-project?rev=90878&view=rev Log: Thunks are not yet supported - say so rather than dieing obscurely. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=90878&r1=90877&r2=90878&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue Dec 8 15:18:28 2009 @@ -1621,7 +1621,7 @@ /// emit_thunk - Turn a thunk into LLVM IR. void emit_thunk(struct cgraph_node *thunk) { - abort(); + assert(false && "Thunks not yet implemented - come back next week!"); // Mark the thunk as written so gcc doesn't waste time outputting it. TREE_ASM_WRITTEN(thunk->decl) = 1; } From stoklund at 2pi.dk Tue Dec 8 16:19:43 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 08 Dec 2009 22:19:43 -0000 Subject: [llvm-commits] [test-suite] r90888 - /test-suite/trunk/TEST.llc.report Message-ID: <200912082219.nB8MJhHK025313@zion.cs.uiuc.edu> Author: stoklund Date: Tue Dec 8 16:19:43 2009 New Revision: 90888 URL: http://llvm.org/viewvc/llvm-project?rev=90888&view=rev Log: Change timings in llc Modified: test-suite/trunk/TEST.llc.report Modified: test-suite/trunk/TEST.llc.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.llc.report?rev=90888&r1=90887&r2=90888&view=diff ============================================================================== --- test-suite/trunk/TEST.llc.report (original) +++ test-suite/trunk/TEST.llc.report Tue Dec 8 16:19:43 2009 @@ -16,6 +16,7 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times + ["InstrCr", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Instruction Creation'], ["LiveVar", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Live Variable'], ["LiveInt", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Live Interval'], ["RASetup", sub { return AddColumns(@_,-1,-2); }], From stoklund at 2pi.dk Tue Dec 8 16:29:30 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 08 Dec 2009 22:29:30 -0000 Subject: [llvm-commits] [test-suite] r90891 - /test-suite/trunk/TEST.llc.report Message-ID: <200912082229.nB8MTUm8025786@zion.cs.uiuc.edu> Author: stoklund Date: Tue Dec 8 16:29:30 2009 New Revision: 90891 URL: http://llvm.org/viewvc/llvm-project?rev=90891&view=rev Log: Undo mistaken commit. Modified: test-suite/trunk/TEST.llc.report Modified: test-suite/trunk/TEST.llc.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.llc.report?rev=90891&r1=90890&r2=90891&view=diff ============================================================================== --- test-suite/trunk/TEST.llc.report (original) +++ test-suite/trunk/TEST.llc.report Tue Dec 8 16:29:30 2009 @@ -16,7 +16,6 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Times - ["InstrCr", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Instruction Creation'], ["LiveVar", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Live Variable'], ["LiveInt", '([0-9.]+) \([^)]+\)[ 0-9A-Za-z]+Live Interval'], ["RASetup", sub { return AddColumns(@_,-1,-2); }], From stoklund at 2pi.dk Tue Dec 8 16:29:34 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 08 Dec 2009 22:29:34 -0000 Subject: [llvm-commits] [test-suite] r90892 - /test-suite/trunk/TEST.beta-compare.report Message-ID: <200912082229.nB8MTYLJ025799@zion.cs.uiuc.edu> Author: stoklund Date: Tue Dec 8 16:29:34 2009 New Revision: 90892 URL: http://llvm.org/viewvc/llvm-project?rev=90892&view=rev Log: Fix regexp for beta-compare report. Modified: test-suite/trunk/TEST.beta-compare.report Modified: test-suite/trunk/TEST.beta-compare.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.beta-compare.report?rev=90892&r1=90891&r2=90892&view=diff ============================================================================== --- test-suite/trunk/TEST.beta-compare.report (original) +++ test-suite/trunk/TEST.beta-compare.report Tue Dec 8 16:29:34 2009 @@ -25,8 +25,8 @@ ["Name:" , '\'([^\']+)\' Program'], [], # Code Size - ["#Insts", 'LLC: ([0-9]+).*Number of machine instrs printed'], - ["Beta", 'LLCBETA: ([0-9]+).*Number of machine instrs printed'], + ["#Insts", 'LLC: *([0-9]+).*Number of machine instrs printed'], + ["Beta", 'LLCBETA: *([0-9]+).*Number of machine instrs printed'], ["LLC/BETA" , \&SizeRatio], [] ); From evan.cheng at apple.com Tue Dec 8 17:06:23 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 08 Dec 2009 23:06:23 -0000 Subject: [llvm-commits] [llvm] r90894 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/inlineasm3.ll Message-ID: <200912082306.nB8N6NZg027038@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 17:06:22 2009 New Revision: 90894 URL: http://llvm.org/viewvc/llvm-project?rev=90894&view=rev Log: - Support inline asm 'w' constraint for 128-bit vector types. - Also support the 'q' NEON registers asm code. Added: llvm/trunk/test/CodeGen/ARM/inlineasm3.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=90894&r1=90893&r2=90894&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Dec 8 17:06:22 2009 @@ -4021,6 +4021,8 @@ return std::make_pair(0U, ARM::SPRRegisterClass); if (VT == MVT::f64) return std::make_pair(0U, ARM::DPRRegisterClass); + if (VT.getSizeInBits() == 128) + return std::make_pair(0U, ARM::QPRRegisterClass); break; } } @@ -4059,6 +4061,9 @@ ARM::D4, ARM::D5, ARM::D6, ARM::D7, ARM::D8, ARM::D9, ARM::D10,ARM::D11, ARM::D12,ARM::D13,ARM::D14,ARM::D15, 0); + if (VT.getSizeInBits() == 128) + return make_vector(ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, + ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, 0); break; } Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=90894&r1=90893&r2=90894&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Tue Dec 8 17:06:22 2009 @@ -1045,6 +1045,7 @@ printNoHashImmediate(MI, OpNum); return false; case 'P': // Print a VFP double precision register. + case 'q': // Print a NEON quad precision register. printOperand(MI, OpNum); return false; case 'Q': Added: llvm/trunk/test/CodeGen/ARM/inlineasm3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/inlineasm3.ll?rev=90894&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/inlineasm3.ll (added) +++ llvm/trunk/test/CodeGen/ARM/inlineasm3.ll Tue Dec 8 17:06:22 2009 @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s + +%struct.int32x4_t = type { <4 x i32> } + +define arm_apcscc void @t() nounwind { +entry: +; CHECK: vmov.I64 q15, #0 +; CHECK: vmov.32 d30[0], r0 +; CHECK: vmov q0, q15 + %tmp = alloca %struct.int32x4_t, align 16 + call void asm sideeffect "vmov.I64 q15, #0\0Avmov.32 d30[0], $1\0Avmov ${0:q}, q15\0A", "=*w,r,~{d31},~{d30}"(%struct.int32x4_t* %tmp, i32 8192) nounwind + ret void +} From dpatel at apple.com Tue Dec 8 17:21:45 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 08 Dec 2009 23:21:45 -0000 Subject: [llvm-commits] [llvm] r90898 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h test/DebugInfo/2009-12-08-DeadGV.ll Message-ID: <200912082321.nB8NLj6H027736@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 8 17:21:45 2009 New Revision: 90898 URL: http://llvm.org/viewvc/llvm-project?rev=90898&view=rev Log: Revert 90858 90875 and 90805 for now. Removed: llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90898&r1=90897&r2=90898&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Dec 8 17:21:45 2009 @@ -99,7 +99,6 @@ bool isGlobalVariable() const; bool isScope() const; bool isCompileUnit() const; - bool isNameSpace() const; bool isLexicalBlock() const; bool isSubrange() const; bool isEnumerator() const; @@ -219,7 +218,7 @@ virtual ~DIType() {} DIDescriptor getContext() const { return getDescriptorField(1); } - StringRef getName() const { return getStringField(2); } + StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ return getFieldAs(3); } unsigned getLineNumber() const { return getUnsignedField(4); } uint64_t getSizeInBits() const { return getUInt64Field(5); } @@ -471,22 +470,6 @@ StringRef getFilename() const { return getContext().getFilename(); } }; - /// DINameSpace - A wrapper for a C++ style name space. - class DINameSpace : public DIScope { - public: - explicit DINameSpace(MDNode *N = 0) : DIScope(N) { - if (DbgNode && !isNameSpace()) - DbgNode = 0; - } - - DIScope getContext() const { return getFieldAs(1); } - StringRef getName() const { return getStringField(2); } - StringRef getDirectory() const { return getContext().getDirectory(); } - StringRef getFilename() const { return getContext().getFilename(); } - DICompileUnit getCompileUnit() const { return getFieldAs(3); } - unsigned getLineNumber() const { return getUnsignedField(4); } - }; - /// DILocation - This object holds location information. This object /// is not associated with any DWARF tag. class DILocation : public DIDescriptor { @@ -641,11 +624,6 @@ /// with the specified parent context. DILexicalBlock CreateLexicalBlock(DIDescriptor Context); - /// CreateNameSpace - This creates new descriptor for a namespace - /// with the specified parent context. - DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name, - DICompileUnit CU, unsigned LineNo); - /// CreateLocation - Creates a debug info location. DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc); Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=90898&r1=90897&r2=90898&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Dec 8 17:21:45 2009 @@ -227,7 +227,6 @@ case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_lexical_block: case dwarf::DW_TAG_subprogram: - case dwarf::DW_TAG_namespace: return true; default: break; @@ -243,14 +242,6 @@ return Tag == dwarf::DW_TAG_compile_unit; } -/// isNameSpace - Return true if the specified tag is DW_TAG_namespace. -bool DIDescriptor::isNameSpace() const { - assert (!isNull() && "Invalid descriptor!"); - unsigned Tag = getTag(); - - return Tag == dwarf::DW_TAG_namespace; -} - /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { assert (!isNull() && "Invalid descriptor!"); @@ -447,8 +438,6 @@ return DISubprogram(DbgNode).getFilename(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getFilename(); - else if (isNameSpace()) - return DINameSpace(DbgNode).getFilename(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -461,8 +450,6 @@ return DISubprogram(DbgNode).getDirectory(); else if (isCompileUnit()) return DICompileUnit(DbgNode).getDirectory(); - else if (isNameSpace()) - return DINameSpace(DbgNode).getDirectory(); else assert (0 && "Invalid DIScope!"); return StringRef(); @@ -1009,21 +996,6 @@ return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); } -/// CreateNameSpace - This creates new descriptor for a namespace -/// with the specified parent context. -DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name, - DICompileUnit CompileUnit, - unsigned LineNo) { - Value *Elts[] = { - GetTagConstant(dwarf::DW_TAG_namespace), - Context.getNode(), - MDString::get(VMContext, Name), - CompileUnit.getNode(), - ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) - }; - return DINameSpace(MDNode::get(VMContext, &Elts[0], 5)); -} - /// CreateLocation - Creates a debug info location. DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, DIScope S, DILocation OrigLoc) { Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90898&r1=90897&r2=90898&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Dec 8 17:21:45 2009 @@ -446,23 +446,6 @@ addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); } -/// addSourceLine - Add location information to specified debug information -/// entry. -void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) { - // If there is no compile unit specified, don't add a line #. - if (NS->getCompileUnit().isNull()) - return; - - unsigned Line = NS->getLineNumber(); - StringRef FN = NS->getFilename(); - StringRef Dir = NS->getDirectory(); - - unsigned FileID = GetOrCreateSourceID(Dir, FN); - assert(FileID && "Invalid file id"); - addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); - addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); -} - /* Byref variables, in Blocks, are declared by the programmer as "SomeType VarName;", but the compiler creates a __Block_byref_x_VarName struct, and gives the variable VarName @@ -756,12 +739,12 @@ } /// addType - Add a new type attribute to the specified entity. -void DwarfDebug::addType(DIE *Entity, DIType Ty) { +void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { if (Ty.isNull()) return; // Check for pre-existence. - DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode()); + DIEEntry *Entry = DW_Unit->getDIEEntry(Ty.getNode()); // If it exists then use the existing value. if (Entry) { @@ -771,40 +754,37 @@ // Set up proxy. Entry = createDIEEntry(); - ModuleCU->insertDIEEntry(Ty.getNode(), Entry); + DW_Unit->insertDIEEntry(Ty.getNode(), Entry); // Construct type. DIE *Buffer = new DIE(dwarf::DW_TAG_base_type); ModuleCU->insertDIE(Ty.getNode(), Buffer); if (Ty.isBasicType()) - constructTypeDIE(*Buffer, DIBasicType(Ty.getNode())); + constructTypeDIE(DW_Unit, *Buffer, DIBasicType(Ty.getNode())); else if (Ty.isCompositeType()) - constructTypeDIE(*Buffer, DICompositeType(Ty.getNode())); + constructTypeDIE(DW_Unit, *Buffer, DICompositeType(Ty.getNode())); else { assert(Ty.isDerivedType() && "Unknown kind of DIType"); - constructTypeDIE(*Buffer, DIDerivedType(Ty.getNode())); + constructTypeDIE(DW_Unit, *Buffer, DIDerivedType(Ty.getNode())); } // Add debug information entry to entity and appropriate context. DIE *Die = NULL; DIDescriptor Context = Ty.getContext(); - if (!Context.isNull()) { - if (Context.isNameSpace()) { - DINameSpace NS(Context.getNode()); - Die = getOrCreateNameSpace(NS); - } else - Die = ModuleCU->getDIE(Context.getNode()); - } + if (!Context.isNull()) + Die = DW_Unit->getDIE(Context.getNode()); + if (Die) Die->addChild(Buffer); else - ModuleCU->addDie(Buffer); + DW_Unit->addDie(Buffer); Entry->setEntry(Buffer); Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); } /// constructTypeDIE - Construct basic type die from DIBasicType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { +void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + DIBasicType BTy) { // Get core information. StringRef Name = BTy.getName(); Buffer.setTag(dwarf::DW_TAG_base_type); @@ -819,7 +799,8 @@ } /// constructTypeDIE - Construct derived type die from DIDerivedType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { +void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + DIDerivedType DTy) { // Get core information. StringRef Name = DTy.getName(); uint64_t Size = DTy.getSizeInBits() >> 3; @@ -832,7 +813,7 @@ // Map to main type, void will not have a type. DIType FromTy = DTy.getTypeDerivedFrom(); - addType(&Buffer, FromTy); + addType(DW_Unit, &Buffer, FromTy); // Add name if not anonymous or intermediate type. if (!Name.empty()) @@ -848,7 +829,8 @@ } /// constructTypeDIE - Construct type DIE from DICompositeType. -void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { +void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + DICompositeType CTy) { // Get core information. StringRef Name = CTy.getName(); @@ -859,7 +841,7 @@ switch (Tag) { case dwarf::DW_TAG_vector_type: case dwarf::DW_TAG_array_type: - constructArrayTypeDIE(Buffer, &CTy); + constructArrayTypeDIE(DW_Unit, Buffer, &CTy); break; case dwarf::DW_TAG_enumeration_type: { DIArray Elements = CTy.getTypeArray(); @@ -869,7 +851,7 @@ DIE *ElemDie = NULL; DIEnumerator Enum(Elements.getElement(i).getNode()); if (!Enum.isNull()) { - ElemDie = constructEnumTypeDIE(&Enum); + ElemDie = constructEnumTypeDIE(DW_Unit, &Enum); Buffer.addChild(ElemDie); } } @@ -879,7 +861,7 @@ // Add return type. DIArray Elements = CTy.getTypeArray(); DIDescriptor RTy = Elements.getElement(0); - addType(&Buffer, DIType(RTy.getNode())); + addType(DW_Unit, &Buffer, DIType(RTy.getNode())); // Add prototype flag. addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); @@ -888,7 +870,7 @@ for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); DIDescriptor Ty = Elements.getElement(i); - addType(Arg, DIType(Ty.getNode())); + addType(DW_Unit, Arg, DIType(Ty.getNode())); Buffer.addChild(Arg); } } @@ -910,9 +892,11 @@ continue; DIE *ElemDie = NULL; if (Element.getTag() == dwarf::DW_TAG_subprogram) - ElemDie = createMemberSubprogramDIE(DISubprogram(Element.getNode())); + ElemDie = createMemberSubprogramDIE(DW_Unit, + DISubprogram(Element.getNode())); else - ElemDie = createMemberDIE(DIDerivedType(Element.getNode())); + ElemDie = createMemberDIE(DW_Unit, + DIDerivedType(Element.getNode())); Buffer.addChild(ElemDie); } @@ -967,26 +951,26 @@ } /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. -void DwarfDebug::constructArrayTypeDIE(DIE &Buffer, +void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, DICompositeType *CTy) { Buffer.setTag(dwarf::DW_TAG_array_type); if (CTy->getTag() == dwarf::DW_TAG_vector_type) addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); // Emit derived type. - addType(&Buffer, CTy->getTypeDerivedFrom()); + addType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom()); DIArray Elements = CTy->getTypeArray(); // Get an anonymous type for index type. - DIE *IdxTy = ModuleCU->getIndexTyDie(); + DIE *IdxTy = DW_Unit->getIndexTyDie(); if (!IdxTy) { // Construct an anonymous type for index type. IdxTy = new DIE(dwarf::DW_TAG_base_type); addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, dwarf::DW_ATE_signed); - ModuleCU->addDie(IdxTy); - ModuleCU->setIndexTyDie(IdxTy); + DW_Unit->addDie(IdxTy); + DW_Unit->setIndexTyDie(IdxTy); } // Add subranges to array type. @@ -998,7 +982,7 @@ } /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. -DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) { +DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) { DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); StringRef Name = ETy->getName(); addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); @@ -1008,7 +992,8 @@ } /// createGlobalVariableDIE - Create new DIE using GV. -DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) { +DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit, + const DIGlobalVariable &GV) { // If the global variable was optmized out then no need to create debug info // entry. if (!GV.getGlobal()) return NULL; @@ -1029,7 +1014,7 @@ addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, LinkageName); } - addType(GVDie, GV.getType()); + addType(DW_Unit, GVDie, GV.getType()); if (!GV.isLocalToUnit()) addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); addSourceLine(GVDie, &GV); @@ -1045,13 +1030,13 @@ } /// createMemberDIE - Create new member DIE. -DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) { +DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){ DIE *MemberDie = new DIE(DT.getTag()); StringRef Name = DT.getName(); if (!Name.empty()) addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - addType(MemberDie, DT.getTypeDerivedFrom()); + addType(DW_Unit, MemberDie, DT.getTypeDerivedFrom()); addSourceLine(MemberDie, &DT); @@ -1105,7 +1090,8 @@ /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. -DIE *DwarfDebug::createRawSubprogramDIE(const DISubprogram &SP) { +DIE *DwarfDebug::createRawSubprogramDIE(CompileUnit *DW_Unit, + const DISubprogram &SP) { DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram); addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); @@ -1134,9 +1120,9 @@ unsigned SPTag = SPTy.getTag(); if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type) - addType(SPDie, SPTy); + addType(DW_Unit, SPDie, SPTy); else - addType(SPDie, DIType(Args.getElement(0).getNode())); + addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode())); unsigned VK = SP.getVirtuality(); if (VK) { @@ -1153,10 +1139,11 @@ /// createMemberSubprogramDIE - Create new member DIE using SP. This routine /// always returns a die with DW_AT_declaration attribute. -DIE *DwarfDebug::createMemberSubprogramDIE(const DISubprogram &SP) { +DIE *DwarfDebug::createMemberSubprogramDIE(CompileUnit *DW_Unit, + const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (!SPDie) - SPDie = createSubprogramDIE(SP); + SPDie = createSubprogramDIE(DW_Unit, SP); // If SPDie has DW_AT_declaration then reuse it. if (!SP.isDefinition()) @@ -1167,7 +1154,7 @@ if (TopLevelDIEs.insert(SPDie)) TopLevelDIEsVector.push_back(SPDie); - SPDie = createRawSubprogramDIE(SP); + SPDie = createRawSubprogramDIE(DW_Unit, SP); // Add arguments. DICompositeType SPTy = SP.getType(); @@ -1176,7 +1163,7 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(Arg, DIType(Args.getElement(i).getNode())); + addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } @@ -1186,12 +1173,13 @@ } /// createSubprogramDIE - Create new DIE using SP. -DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP) { +DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit, + const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (SPDie) return SPDie; - SPDie = createRawSubprogramDIE(SP); + SPDie = createRawSubprogramDIE(DW_Unit, SP); if (!SP.isDefinition()) { addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); @@ -1205,14 +1193,14 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(Arg, DIType(Args.getElement(i).getNode())); + addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } } // DW_TAG_inlined_subroutine may refer to this DIE. - ModuleCU->insertDIE(SP.getNode(), SPDie); + DW_Unit->insertDIE(SP.getNode(), SPDie); return SPDie; } @@ -1225,6 +1213,64 @@ return *I->second; } +/// createDbgScopeVariable - Create a new scope variable. +/// +DIE *DwarfDebug::createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { + // Get the descriptor. + const DIVariable &VD = DV->getVariable(); + StringRef Name = VD.getName(); + if (Name.empty()) + return NULL; + + // Translate tag to proper Dwarf tag. The result variable is dropped for + // now. + unsigned Tag; + switch (VD.getTag()) { + case dwarf::DW_TAG_return_variable: + return NULL; + case dwarf::DW_TAG_arg_variable: + Tag = dwarf::DW_TAG_formal_parameter; + break; + case dwarf::DW_TAG_auto_variable: // fall thru + default: + Tag = dwarf::DW_TAG_variable; + break; + } + + // Define variable debug information entry. + DIE *VariableDie = new DIE(Tag); + addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); + + // Add source line info if available. + addSourceLine(VariableDie, &VD); + + // Add variable type. + // FIXME: isBlockByrefVariable should be reformulated in terms of complex + // addresses instead. + if (VD.isBlockByrefVariable()) + addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); + else + addType(Unit, VariableDie, VD.getType()); + + // Add variable address. + // Variables for abstract instances of inlined functions don't get a + // location. + MachineLocation Location; + unsigned FrameReg; + int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); + Location.set(FrameReg, Offset); + + + if (VD.hasComplexAddress()) + addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) + addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else + addAddress(VariableDie, dwarf::DW_AT_location, Location); + + return VariableDie; +} + /// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. /// Initialize scope and update scope hierarchy. DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, @@ -1330,7 +1376,7 @@ if (!N) continue; DIGlobalVariable GV(N); if (GV.getContext().getNode() == SPNode) { - DIE *ScopedGVDie = createGlobalVariableDIE(GV); + DIE *ScopedGVDie = createGlobalVariableDIE(ModuleCU, GV); if (ScopedGVDie) SPDie->addChild(ScopedGVDie); } @@ -1419,7 +1465,8 @@ /// constructVariableDIE - Construct a DIE for the given DbgVariable. -DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { +DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, + DbgScope *Scope, CompileUnit *Unit) { // Get the descriptor. const DIVariable &VD = DV->getVariable(); StringRef Name = VD.getName(); @@ -1468,9 +1515,9 @@ // FIXME: isBlockByrefVariable should be reformulated in terms of complex // addresses instead. if (VD.isBlockByrefVariable()) - addType(VariableDie, getBlockByrefType(VD.getType(), Name)); + addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); else - addType(VariableDie, VD.getType()); + addType(Unit, VariableDie, VD.getType()); } // Add variable address. @@ -1539,7 +1586,7 @@ // Add variables to scope. SmallVector &Variables = Scope->getVariables(); for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); + DIE *VariableDIE = constructVariableDIE(Variables[i], Scope, ModuleCU); if (VariableDIE) ScopeDIE->addChild(VariableDIE); } @@ -1596,29 +1643,6 @@ return SrcId; } -/// getOrCreateNameSpace - Create a DIE for DINameSpace. -DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace &NS) { - DIE *NDie = ModuleCU->getDIE(NS.getNode()); - if (NDie) - return NDie; - - NDie = new DIE(dwarf::DW_TAG_namespace); - ModuleCU->insertDIE(NS.getNode(), NDie); - if (!NS.getName().empty()) - addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName()); - addSourceLine(NDie, &NS); - DIDescriptor NSContext = NS.getContext(); - DIE *Context = NULL; - if (NSContext.isNameSpace()) { - DINameSpace NS2(NSContext.getNode()); - Context = getOrCreateNameSpace(NS2); - } - else - Context = ModuleCU->getCUDie(); - Context->addChild(NDie); - return NDie; -} - void DwarfDebug::constructCompileUnit(MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); @@ -1671,7 +1695,7 @@ if (ModuleCU->getDIE(DI_GV.getNode())) return; - DIE *VariableDie = createGlobalVariableDIE(DI_GV); + DIE *VariableDie = createGlobalVariableDIE(ModuleCU, DI_GV); // Add to map. ModuleCU->insertDIE(N, VariableDie); @@ -1704,23 +1728,16 @@ // class type. return; - DIE *SubprogramDie = createSubprogramDIE(SP); + DIE *SubprogramDie = createSubprogramDIE(ModuleCU, SP); // Add to map. ModuleCU->insertDIE(N, SubprogramDie); // Add to context owner. - DIDescriptor SPContext = SP.getContext(); - if (SPContext.isCompileUnit() - && SPContext.getNode() == SP.getCompileUnit().getNode()) { + if (SP.getContext().getNode() == SP.getCompileUnit().getNode()) if (TopLevelDIEs.insert(SubprogramDie)) TopLevelDIEsVector.push_back(SubprogramDie); - } else if (SPContext.isNameSpace()) { - DINameSpace NS(SPContext.getNode()); - DIE *NDie = getOrCreateNameSpace(NS); - NDie->addChild(SubprogramDie); - } - + // Expose as global. ModuleCU->addGlobal(SP.getName(), SubprogramDie); @@ -1763,20 +1780,10 @@ for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), E = DbgFinder.global_variable_end(); I != E; ++I) { DIGlobalVariable GV(*I); - DIDescriptor GVContext = GV.getContext(); - if (GVContext.isCompileUnit() - && GVContext.getNode() == GV.getCompileUnit().getNode()) - constructGlobalVariableDIE(*I); - else if (GVContext.isNameSpace()) { - DIE *GVDie = createGlobalVariableDIE(GV); - if (GVDie) { - DINameSpace NS(GVContext.getNode()); - DIE *NDie = getOrCreateNameSpace(NS); - NDie->addChild(GVDie); - } - } - else + if (GV.getContext().getNode() != GV.getCompileUnit().getNode()) ScopedGVs.push_back(*I); + else + constructGlobalVariableDIE(*I); } // Create DIEs for each subprogram. @@ -2412,16 +2419,13 @@ } } -/// emitDebugInfo - Emit the debug info section. +/// emitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. /// -void DwarfDebug::emitDebugInfo() { - // Start debug info section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfInfoSection()); - DIE *Die = ModuleCU->getCUDie(); +void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) { + DIE *Die = Unit->getCUDie(); // Emit the compile units header. - EmitLabel("info_begin", ModuleCU->getID()); + EmitLabel("info_begin", Unit->getID()); // Emit size of content not including length itself unsigned ContentSize = Die->getSize() + @@ -2442,10 +2446,17 @@ Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - EmitLabel("info_end", ModuleCU->getID()); + EmitLabel("info_end", Unit->getID()); Asm->EOL(); +} +void DwarfDebug::emitDebugInfo() { + // Start debug info section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfInfoSection()); + + emitDebugInfoPerCU(ModuleCU); } /// emitAbbreviations - Emit the abbreviation section. @@ -2743,30 +2754,24 @@ Asm->EOL(); } -/// emitDebugPubNames - Emit visible names into a debug pubnames section. -/// -void DwarfDebug::emitDebugPubNames() { - // Start the dwarf pubnames section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfPubNamesSection()); - - EmitDifference("pubnames_end", ModuleCU->getID(), - "pubnames_begin", ModuleCU->getID(), true); +void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) { + EmitDifference("pubnames_end", Unit->getID(), + "pubnames_begin", Unit->getID(), true); Asm->EOL("Length of Public Names Info"); - EmitLabel("pubnames_begin", ModuleCU->getID()); + EmitLabel("pubnames_begin", Unit->getID()); Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); EmitSectionOffset("info_begin", "section_info", - ModuleCU->getID(), 0, true, false); + Unit->getID(), 0, true, false); Asm->EOL("Offset of Compilation Unit Info"); - EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), + EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(), true); Asm->EOL("Compilation Unit Length"); - const StringMap &Globals = ModuleCU->getGlobals(); + const StringMap &Globals = Unit->getGlobals(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); @@ -2777,11 +2782,21 @@ } Asm->EmitInt32(0); Asm->EOL("End Mark"); - EmitLabel("pubnames_end", ModuleCU->getID()); + EmitLabel("pubnames_end", Unit->getID()); Asm->EOL(); } +/// emitDebugPubNames - Emit visible names into a debug pubnames section. +/// +void DwarfDebug::emitDebugPubNames() { + // Start the dwarf pubnames section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfPubNamesSection()); + + emitDebugPubNamesPerCU(ModuleCU); +} + void DwarfDebug::emitDebugPubTypes() { // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection( Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=90898&r1=90897&r2=90898&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Dec 8 17:21:45 2009 @@ -289,7 +289,6 @@ void addSourceLine(DIE *Die, const DIGlobal *G); void addSourceLine(DIE *Die, const DISubprogram *SP); void addSourceLine(DIE *Die, const DIType *Ty); - void addSourceLine(DIE *Die, const DINameSpace *NS); /// addAddress - Add an address attribute to a die based on the location /// provided. @@ -315,58 +314,60 @@ const MachineLocation &Location); /// addType - Add a new type attribute to the specified entity. - void addType(DIE *Entity, DIType Ty); + void addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty); void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType. - void constructTypeDIE(DIE &Buffer, + void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, DIBasicType BTy); /// constructTypeDIE - Construct derived type die from DIDerivedType. - void constructTypeDIE(DIE &Buffer, + void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, DIDerivedType DTy); /// constructTypeDIE - Construct type DIE from DICompositeType. - void constructTypeDIE(DIE &Buffer, + void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, DICompositeType CTy); /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy); /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. - void constructArrayTypeDIE(DIE &Buffer, + void constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, DICompositeType *CTy); /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. - DIE *constructEnumTypeDIE(DIEnumerator *ETy); - - /// getOrCreateNameSpace - Create a DIE for DINameSpace. - DIE *getOrCreateNameSpace(DINameSpace &NS); + DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy); /// createGlobalVariableDIE - Create new DIE using GV. - DIE *createGlobalVariableDIE(const DIGlobalVariable &GV); + DIE *createGlobalVariableDIE(CompileUnit *DW_Unit, + const DIGlobalVariable &GV); /// createMemberDIE - Create new member DIE. - DIE *createMemberDIE(const DIDerivedType &DT); + DIE *createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT); /// createSubprogramDIE - Create new DIE using SP. - DIE *createSubprogramDIE(const DISubprogram &SP); + DIE *createSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); /// createMemberSubprogramDIE - Create new member DIE using SP. This /// routine always returns a die with DW_AT_declaration attribute. - DIE *createMemberSubprogramDIE(const DISubprogram &SP); + DIE *createMemberSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. - DIE *createRawSubprogramDIE(const DISubprogram &SP); + DIE *createRawSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); /// findCompileUnit - Get the compile unit for the given descriptor. /// CompileUnit &findCompileUnit(DICompileUnit Unit) const; + /// createDbgScopeVariable - Create a new scope variable. + /// + DIE *createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit); + /// getUpdatedDbgScope - Find or create DbgScope assicated with /// the instruction. Initialize scope and update scope hierarchy. DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); @@ -396,7 +397,7 @@ DIE *constructInlinedScopeDIE(DbgScope *Scope); /// constructVariableDIE - Construct a DIE for the given DbgVariable. - DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S); + DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit); /// constructScopeDIE - Construct a DIE for this scope. DIE *constructScopeDIE(DbgScope *Scope); @@ -417,8 +418,10 @@ /// void computeSizeAndOffsets(); - /// EmitDebugInfo - Emit the debug info section. + /// EmitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. /// + void emitDebugInfoPerCU(CompileUnit *Unit); + void emitDebugInfo(); /// emitAbbreviations - Emit the abbreviation section. @@ -442,6 +445,8 @@ /// section. void emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo); + void emitDebugPubNamesPerCU(CompileUnit *Unit); + /// emitDebugPubNames - Emit visible names into a debug pubnames section. /// void emitDebugPubNames(); Removed: llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll?rev=90897&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll (original) +++ llvm/trunk/test/DebugInfo/2009-12-08-DeadGV.ll (removed) @@ -1,18 +0,0 @@ -; RUN: llc %s -o /dev/null -; PR 5713 - -define i32 @_Z3foov() nounwind readnone ssp { -entry: - ret i32 0, !dbg !4 -} - -!llvm.dbg.gv = !{!0} - -!0 = metadata !{i32 458804, i32 0, metadata !1, metadata !"X", metadata !"X", metadata !"_ZN1A1XE", metadata !2, i32 3, metadata !3, i1 false, i1 true, null}; [DW_TAG_variable ] -!1 = metadata !{i32 458809, metadata !2, metadata !"A", metadata !2, i32 2}; [DW_TAG_namespace ] -!2 = metadata !{i32 458769, i32 0, i32 4, metadata !"ng.cc", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5653) (LLVM build)", i1 true, i1 true, metadata !"", i32 0}; [DW_TAG_compile_unit ] -!3 = metadata !{i32 458788, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ] -!4 = metadata !{i32 7, i32 0, metadata !5, null} -!5 = metadata !{i32 458798, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3foov", metadata !2, i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null}; [DW_TAG_subprogram ] -!6 = metadata !{i32 458773, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0}; [DW_TAG_subroutine_type ] -!7 = metadata !{metadata !3} From dpatel at apple.com Tue Dec 8 17:22:51 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 08 Dec 2009 23:22:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r90899 - in /llvm-gcc-4.2/trunk/gcc: llvm-debug.cpp llvm-debug.h Message-ID: <200912082322.nB8NMpgk027786@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 8 17:22:51 2009 New Revision: 90899 URL: http://llvm.org/viewvc/llvm-project?rev=90899&view=rev Log: Revert 90806 for now. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=90899&r1=90898&r2=90899&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue Dec 8 17:22:51 2009 @@ -282,23 +282,7 @@ RegionMap[FnDecl] = WeakVH(SP.getNode()); } -/// getOrCreateNameSpace - Get name space descriptor for the tree node. -DINameSpace DebugInfo::getOrCreateNameSpace(tree Node, DIDescriptor Context) { - std::map::iterator I = - NameSpaceCache.find(Node); - if (I != NameSpaceCache.end()) - return DINameSpace(cast(I->second)); - - expanded_location Loc = GetNodeLocation(Node, false); - DINameSpace DNS = - DebugFactory.CreateNameSpace(Context, GetNodeName(Node), - getOrCreateCompileUnit(Loc.file), Loc.line); - - NameSpaceCache[Node] = WeakVH(DNS.getNode()); - return DNS; -} - -/// findRegion - Find tree_node N's region. + /// findRegion - Find tree_node N's region. DIDescriptor DebugInfo::findRegion(tree Node) { if (Node == NULL_TREE) return getOrCreateCompileUnit(main_input_filename); @@ -309,9 +293,8 @@ return DIDescriptor(R); if (TYPE_P (Node)) { - if (TYPE_CONTEXT (Node)) { + if (TYPE_CONTEXT (Node)) return findRegion (TYPE_CONTEXT(Node)); - } } else if (DECL_P (Node)) { tree decl = Node; tree context = NULL_TREE; @@ -321,19 +304,10 @@ context = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); - if (context != NULL_TREE) { - if (TREE_CODE(Node) == NAMESPACE_DECL) { - DIDescriptor Context = findRegion(context); - return getOrCreateNameSpace(Node, Context); - } else - return findRegion(context); - } + if (context != NULL_TREE) + return findRegion(context); } - - if (TREE_CODE(Node) == NAMESPACE_DECL) - return getOrCreateNameSpace(Node, - getOrCreateCompileUnit(main_input_filename)); - + // Otherwise main compile unit covers everything. return getOrCreateCompileUnit(main_input_filename); } Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=90899&r1=90898&r2=90899&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Tue Dec 8 17:22:51 2009 @@ -68,9 +68,6 @@ std::map SPCache; // Cache of previously constructed // Subprograms. - std::map NameSpaceCache; - // Cache of previously constructed name - // spaces. SmallVector RegionStack; // Stack to track declarative scopes. @@ -139,9 +136,6 @@ /// findRegion - Find tree_node N's region. DIDescriptor findRegion(tree_node *n); - - /// getOrCreateNameSpace - Get name space descriptor for the tree node. - DINameSpace getOrCreateNameSpace(tree_node *Node, DIDescriptor Context); }; } // end namespace llvm From sabre at nondot.org Tue Dec 8 17:42:52 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 08 Dec 2009 23:42:52 -0000 Subject: [llvm-commits] [llvm] r90901 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912082342.nB8Ngq6e028607@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 17:42:51 2009 New Revision: 90901 URL: http://llvm.org/viewvc/llvm-project?rev=90901&view=rev Log: make sure that PHITransAddr keeps its 'InstInputs' list up to date when instsimplify kicks in. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90901&r1=90900&r2=90901&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Tue Dec 8 17:42:51 2009 @@ -98,6 +98,11 @@ Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl &NewInsts); + + /// ReplaceInstWithValue - Remove any instruction inputs in the InstInputs + /// array that are due to the specified instruction that is about to be + /// removed from the address, and add any corresponding to V. This returns V. + Value *ReplaceInstWithValue(Instruction *I, Value *V); }; } // end namespace llvm Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90901&r1=90900&r2=90901&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 17:42:51 2009 @@ -43,6 +43,44 @@ } +static void RemoveInstInputs(Instruction *I, + SmallVectorImpl &InstInputs) { + // If the instruction is in the InstInputs list, remove it. + SmallVectorImpl::iterator Entry = + std::find(InstInputs.begin(), InstInputs.end(), I); + if (Entry != InstInputs.end()) { + InstInputs.erase(Entry); + return; + } + + // Otherwise, it must have instruction inputs itself. Zap them recursively. + bool HadInstInputs = false; + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + if (Instruction *Op = dyn_cast(I->getOperand(i))) { + RemoveInstInputs(Op, InstInputs); + HadInstInputs = true; + } + } + + // This instruction had to have operands in the instinputs list or it should + // have been in the list itself. If not, the list is broken. + assert(HadInstInputs && "InstInputs list inconsistent!"); +} + +/// ReplaceInstWithValue - Remove any instruction inputs in the InstInputs +/// array that are due to the specified instruction that is about to be +/// removed from the address, and add any corresponding to V. This returns V. +Value *PHITransAddr::ReplaceInstWithValue(Instruction *I, Value *V) { + // Remove the old instruction from InstInputs. + RemoveInstInputs(I, InstInputs); + + // If V is an instruction, it is now an input. + if (Instruction *VI = dyn_cast(V)) + InstInputs.push_back(VI); + return V; +} + + Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB) { // If this is a non-instruction value, it can't require PHI translation. @@ -98,7 +136,8 @@ // Constants are trivial to find. if (Constant *C = dyn_cast(PHIIn)) - return ConstantExpr::getBitCast(C, BC->getType()); + return ReplaceInstWithValue(BC, ConstantExpr::getBitCast(C, + BC->getType())); // Otherwise we have to see if a bitcasted version of the incoming pointer // is available. If so, we can use it, otherwise we have to fail. @@ -129,7 +168,7 @@ // Simplify the GEP to handle 'gep x, 0' -> x etc. if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) - return V; + return ReplaceInstWithValue(GEP, V); // Scan to see if we have this GEP available. Value *APHIOp = GEPOps[0]; @@ -174,7 +213,7 @@ // See if the add simplifies away. if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) - return Res; + return ReplaceInstWithValue(Inst, Res); // Otherwise, see if we have this add available somewhere. for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); From gohman at apple.com Tue Dec 8 17:59:13 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 08 Dec 2009 23:59:13 -0000 Subject: [llvm-commits] [llvm] r90905 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp Message-ID: <200912082359.nB8NxD9L029630@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 8 17:59:12 2009 New Revision: 90905 URL: http://llvm.org/viewvc/llvm-project?rev=90905&view=rev Log: Put a threshold on the number of users PointerMayBeCaptured examines; fall back to a conservative answer if there are more. This works around some several compile time problems resulting from BasicAliasAnalysis calling PointerMayBeCaptured. The value has been chosen arbitrarily. This fixes rdar://7438917 and may partially address PR5708. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=90905&r1=90904&r2=90905&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Tue Dec 8 17:59:12 2009 @@ -25,6 +25,16 @@ #include "llvm/Support/CallSite.h" using namespace llvm; +/// As its comment mentions, PointerMayBeCaptured can be expensive. +/// However, it's not easy for BasicAA to cache the result, because +/// it's an ImmutablePass. To work around this, bound queries at a +/// fixed number of uses. +/// +/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep +/// a cache. Then we can move the code from BasicAliasAnalysis into +/// that path, and remove this threshold. +static int const Threshold = 20; + /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can /// be expensive, so consider caching the results. The boolean ReturnCaptures @@ -37,12 +47,18 @@ assert(isa(V->getType()) && "Capture is for pointers only!"); SmallVector Worklist; SmallSet Visited; + int Count = 0; for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; ++UI) { Use *U = &UI.getUse(); Visited.insert(U); Worklist.push_back(U); + + // If there are lots of uses, conservativelty say that the value + // is captured to avoid taking too much compile time. + if (Count++ >= Threshold) + return true; } while (!Worklist.empty()) { From sabre at nondot.org Tue Dec 8 18:01:00 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 00:01:00 -0000 Subject: [llvm-commits] [llvm] r90906 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912090001.nB9011vu029720@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 18:01:00 2009 New Revision: 90906 URL: http://llvm.org/viewvc/llvm-project?rev=90906&view=rev Log: add dumping and sanity checking support. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90906&r1=90905&r2=90906&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Tue Dec 8 18:01:00 2009 @@ -80,6 +80,13 @@ Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl &NewInsts); + + void dump() const; + + /// Verify - Check internal consistency of this data structure. Though it + /// claims to return a bool, it actually aborts on error and always returns + /// true. + bool Verify() const; private: Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); @@ -103,6 +110,7 @@ /// array that are due to the specified instruction that is about to be /// removed from the address, and add any corresponding to V. This returns V. Value *ReplaceInstWithValue(Instruction *I, Value *V); + }; } // end namespace llvm Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90906&r1=90905&r2=90906&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 18:01:00 2009 @@ -14,6 +14,7 @@ #include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; static bool CanPHITrans(Instruction *Inst) { @@ -32,6 +33,72 @@ return false; } +void PHITransAddr::dump() const { + if (Addr == 0) { + errs() << "PHITransAddr: null\n"; + return; + } + errs() << "PHITransAddr: " << *Addr << "\n"; + for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) + errs() << " Input #" << i << " is " << *InstInputs[i] << "\n"; +} + + +static bool VerifySubExpr(Value *Expr, + SmallVectorImpl &InstInputs) { + // If this is a non-instruction value, there is nothing to do. + Instruction *I = dyn_cast(Expr); + if (I == 0) return true; + + // If it's an instruction, it is either in Tmp or its operands recursively + // are. + SmallVectorImpl::iterator Entry = + std::find(InstInputs.begin(), InstInputs.end(), I); + if (Entry != InstInputs.end()) { + InstInputs.erase(Entry); + return true; + } + + // If it isn't in the InstInputs list it is a subexpr incorporated into the + // address. Sanity check that it is phi translatable. + if (!CanPHITrans(I)) { + errs() << "Non phi translatable instruction found in PHITransAddr, either " + "something is missing from InstInputs or CanPHITrans is wrong:\n"; + errs() << *I << '\n'; + return false; + } + + // Validate the operands of the instruction. + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (!VerifySubExpr(I->getOperand(i), InstInputs)) + return false; + + return true; +} + +/// Verify - Check internal consistency of this data structure. If the +/// structure is valid, it returns true. If invalid, it prints errors and +/// returns false. +bool PHITransAddr::Verify() const { + if (Addr == 0) return true; + + SmallVector Tmp(InstInputs.begin(), InstInputs.end()); + + if (!VerifySubExpr(Addr, Tmp)) + return false; + + if (!Tmp.empty()) { + errs() << "PHITransAddr inconsistent, contains extra instructions:\n"; + for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) + errs() << " InstInput #" << i << " is " << *InstInputs[i] << "\n"; + return false; + } + + // a-ok. + return true; +} + + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true /// if we have some hope of doing it. This should be used as a filter to /// avoid calling PHITranslateValue in hopeless situations. @@ -236,7 +303,9 @@ /// CurBB to Pred, updating our state the reflect any needed changes. This /// returns true on failure and sets Addr to null. bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) { + assert(Verify() && "Invalid PHITransAddr!"); Addr = PHITranslateSubExpr(Addr, CurBB, PredBB); + assert(Verify() && "Invalid PHITransAddr!"); return Addr == 0; } From clattner at apple.com Tue Dec 8 18:04:52 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 8 Dec 2009 16:04:52 -0800 Subject: [llvm-commits] [llvm] r90905 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp In-Reply-To: <200912082359.nB8NxD9L029630@zion.cs.uiuc.edu> References: <200912082359.nB8NxD9L029630@zion.cs.uiuc.edu> Message-ID: Ok, typo 'conservativelty' though. You might as well bump up the 'small' datastructures to 32 so that they are "really" unlikely to have to resize as well. -Chris On Dec 8, 2009, at 3:59 PM, Dan Gohman wrote: > Author: djg > Date: Tue Dec 8 17:59:12 2009 > New Revision: 90905 > > URL: http://llvm.org/viewvc/llvm-project?rev=90905&view=rev > Log: > Put a threshold on the number of users PointerMayBeCaptured > examines; fall back to a conservative answer if there are > more. This works around some several compile time problems > resulting from BasicAliasAnalysis calling PointerMayBeCaptured. > > The value has been chosen arbitrarily. > > This fixes rdar://7438917 and may partially address PR5708. > > Modified: > llvm/trunk/lib/Analysis/CaptureTracking.cpp > > Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=90905&r1=90904&r2=90905&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) > +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Tue Dec 8 17:59:12 > 2009 > @@ -25,6 +25,16 @@ > #include "llvm/Support/CallSite.h" > using namespace llvm; > > +/// As its comment mentions, PointerMayBeCaptured can be expensive. > +/// However, it's not easy for BasicAA to cache the result, because > +/// it's an ImmutablePass. To work around this, bound queries at a > +/// fixed number of uses. > +/// > +/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep > +/// a cache. Then we can move the code from BasicAliasAnalysis into > +/// that path, and remove this threshold. > +static int const Threshold = 20; > + > /// PointerMayBeCaptured - Return true if this pointer value may be > captured > /// by the enclosing function (which is required to exist). This > routine can > /// be expensive, so consider caching the results. The boolean > ReturnCaptures > @@ -37,12 +47,18 @@ > assert(isa(V->getType()) && "Capture is for pointers > only!"); > SmallVector Worklist; > SmallSet Visited; > + int Count = 0; > > for (Value::use_const_iterator UI = V->use_begin(), UE = V- > >use_end(); > UI != UE; ++UI) { > Use *U = &UI.getUse(); > Visited.insert(U); > Worklist.push_back(U); > + > + // If there are lots of uses, conservativelty say that the value > + // is captured to avoid taking too much compile time. > + if (Count++ >= Threshold) > + return true; > } > > while (!Worklist.empty()) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Dec 8 18:10:56 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 00:10:56 -0000 Subject: [llvm-commits] [llvm] r90908 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912090010.nB90AuJS030210@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 18:10:55 2009 New Revision: 90908 URL: http://llvm.org/viewvc/llvm-project?rev=90908&view=rev Log: instructions defined in CurBB may be intermediate nodes of the computation. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90908&r1=90907&r2=90908&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Tue Dec 8 18:10:55 2009 @@ -83,9 +83,9 @@ void dump() const; - /// Verify - Check internal consistency of this data structure. Though it - /// claims to return a bool, it actually aborts on error and always returns - /// true. + /// Verify - Check internal consistency of this data structure. If the + /// structure is valid, it returns true. If invalid, it prints errors and + /// returns false. bool Verify() const; private: Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90908&r1=90907&r2=90908&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 18:10:55 2009 @@ -154,12 +154,20 @@ Instruction *Inst = dyn_cast(V); if (Inst == 0) return V; - // If 'Inst' is defined in this block, it must be an input that needs to be - // phi translated or an intermediate expression that needs to be incorporated - // into the expression. - if (Inst->getParent() == CurBB) { - assert(std::count(InstInputs.begin(), InstInputs.end(), Inst) && - "Not an input?"); + // Determine whether 'Inst' is an input to our PHI translatable expression. + bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); + + // Handle inputs instructions if needed. + if (isInput) { + if (Inst->getParent() != CurBB) { + // If it is an input defined in a different block, then it remains an + // input. + return Inst; + } + + // If 'Inst' is defined in this block, it must be an input that needs to be + // phi translated or an intermediate expression that needs to be incorporated + // into the expression. // If this is a PHI, go ahead and translate it. if (PHINode *PN = dyn_cast(Inst)) @@ -179,14 +187,6 @@ for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) if (Instruction *Op = dyn_cast(Inst->getOperand(i))) InstInputs.push_back(Op); - - } else { - // Determine whether 'Inst' is an input to our PHI translatable expression. - bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); - - // If it is an input defined in a different block, then it remains an input. - if (isInput) - return Inst; } // Ok, it must be an intermediate result (either because it started that way From sabre at nondot.org Tue Dec 8 18:18:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 00:18:13 -0000 Subject: [llvm-commits] [llvm] r90909 - /llvm/trunk/lib/Analysis/PHITransAddr.cpp Message-ID: <200912090018.nB90IDbc030444@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 18:18:13 2009 New Revision: 90909 URL: http://llvm.org/viewvc/llvm-project?rev=90909&view=rev Log: fix PHI translation to take the PHI out of the instinputs set and add the translated value back to it if an instruction. Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90909&r1=90908&r2=90909&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 18:18:13 2009 @@ -164,22 +164,20 @@ // input. return Inst; } - - // If 'Inst' is defined in this block, it must be an input that needs to be - // phi translated or an intermediate expression that needs to be incorporated - // into the expression. - + + // If 'Inst' is defined in this block and is an input that needs to be phi + // translated, we need to incorporate the value into the expression or fail. + // If this is a PHI, go ahead and translate it. if (PHINode *PN = dyn_cast(Inst)) - return PN->getIncomingValueForBlock(PredBB); - + return ReplaceInstWithValue(PN, PN->getIncomingValueForBlock(PredBB)); // If this is a non-phi value, and it is analyzable, we can incorporate it // into the expression by making all instruction operands be inputs. if (!CanPHITrans(Inst)) return 0; - - // Okay, we can incorporate it, this instruction is no longer an input. + + // The instruction itself isn't an input any longer. InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst)); // All instruction operands are now inputs (and of course, they may also be From gohman at apple.com Tue Dec 8 18:28:44 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 09 Dec 2009 00:28:44 -0000 Subject: [llvm-commits] [llvm] r90910 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp Message-ID: <200912090028.nB90Sinv030745@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 8 18:28:42 2009 New Revision: 90910 URL: http://llvm.org/viewvc/llvm-project?rev=90910&view=rev Log: Fix a typo in a comment, and adjust SmallSet and SmallVector sizes, that Chris noticed. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=90910&r1=90909&r2=90910&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Tue Dec 8 18:28:42 2009 @@ -45,20 +45,20 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures) { assert(isa(V->getType()) && "Capture is for pointers only!"); - SmallVector Worklist; - SmallSet Visited; + SmallVector Worklist; + SmallSet Visited; int Count = 0; for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; ++UI) { - Use *U = &UI.getUse(); - Visited.insert(U); - Worklist.push_back(U); - - // If there are lots of uses, conservativelty say that the value + // If there are lots of uses, conservatively say that the value // is captured to avoid taking too much compile time. if (Count++ >= Threshold) return true; + + Use *U = &UI.getUse(); + Visited.insert(U); + Worklist.push_back(U); } while (!Worklist.empty()) { From sabre at nondot.org Tue Dec 8 18:41:28 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 00:41:28 -0000 Subject: [llvm-commits] [llvm] r90912 - /llvm/trunk/tools/opt/opt.cpp Message-ID: <200912090041.nB90fTcG031237@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 18:41:28 2009 New Revision: 90912 URL: http://llvm.org/viewvc/llvm-project?rev=90912&view=rev Log: when opt crashes, print its command line arguments as a pretty stack trace. Somehow opt was missed when this was added. Modified: llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=90912&r1=90911&r2=90912&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Tue Dec 8 18:41:28 2009 @@ -30,6 +30,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PluginLoader.h" +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/StandardPasses.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/raw_ostream.h" @@ -340,12 +341,14 @@ // main for opt // int main(int argc, char **argv) { - llvm_shutdown_obj X; // Call llvm_shutdown() on exit. + sys::PrintStackTraceOnErrorSignal(); + llvm::PrettyStackTraceProgram X(argc, argv); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); - sys::PrintStackTraceOnErrorSignal(); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. From stuart at apple.com Tue Dec 8 18:55:57 2009 From: stuart at apple.com (Stuart Hastings) Date: Wed, 09 Dec 2009 00:55:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r90914 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200912090055.nB90tvrY031749@zion.cs.uiuc.edu> Author: stuart Date: Tue Dec 8 18:55:56 2009 New Revision: 90914 URL: http://llvm.org/viewvc/llvm-project?rev=90914&view=rev Log: If a callee returns a structure in registers, but the stored image of those registers is bigger than the destination, store the registers into a temporary, and copy the desired (smaller) part to the destination. The original testcase returned an array of three 32-bit floats, wrapped in a struct; the value was returned as two doubles in xmm0/1, and stored as a 128-bit value. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=90914&r1=90913&r2=90914&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Dec 8 18:55:56 2009 @@ -2776,8 +2776,26 @@ return 0; if (Client.isAggrReturn()) { - Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()->getPointerTo()); - LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc->Volatile,Builder); + if (TD.getTypeAllocSize(Call->getType()) <= TD.getTypeAllocSize(DestLoc->Ptr->getType())) { + Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()->getPointerTo()); + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc->Volatile,Builder); + } else { + // The call will return an aggregate value in registers, but + // those registers are bigger than DestLoc. Allocate a + // temporary to match the registers, store the registers there, + // cast the temporary into the correct (smaller) type, and using + // the correct type, copy the value into DestLoc. Assume the + // optimizer will delete the temporary and clean this up. + AllocaInst *biggerTmp = CreateTemporary(Call->getType()); + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,biggerTmp,/*Volatile=*/false, + Builder); + EmitAggregateCopy(*DestLoc, + MemRef(BitCastToType(biggerTmp,Call->getType()-> + getPointerTo()), + DestLoc->getAlignment(), + DestLoc->Volatile), + TREE_TYPE(exp)); + } return 0; } From sabre at nondot.org Tue Dec 8 18:56:14 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 00:56:14 -0000 Subject: [llvm-commits] [llvm] r90915 - in /llvm/trunk: include/llvm/Analysis/PHITransAddr.h lib/Analysis/PHITransAddr.cpp Message-ID: <200912090056.nB90uF4G031768@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 18:56:14 2009 New Revision: 90915 URL: http://llvm.org/viewvc/llvm-project?rev=90915&view=rev Log: fix many input tracking bugs. Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/include/llvm/Analysis/PHITransAddr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PHITransAddr.h?rev=90915&r1=90914&r2=90915&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PHITransAddr.h (original) +++ llvm/trunk/include/llvm/Analysis/PHITransAddr.h Tue Dec 8 18:56:14 2009 @@ -106,10 +106,13 @@ BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl &NewInsts); - /// ReplaceInstWithValue - Remove any instruction inputs in the InstInputs - /// array that are due to the specified instruction that is about to be - /// removed from the address, and add any corresponding to V. This returns V. - Value *ReplaceInstWithValue(Instruction *I, Value *V); + /// AddAsInput - If the specified value is an instruction, add it as an input. + Value *AddAsInput(Value *V) { + // If V is an instruction, it is now an input. + if (Instruction *VI = dyn_cast(V)) + InstInputs.push_back(VI); + return V; + } }; Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90915&r1=90914&r2=90915&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 18:56:14 2009 @@ -110,8 +110,11 @@ } -static void RemoveInstInputs(Instruction *I, +static void RemoveInstInputs(Value *V, SmallVectorImpl &InstInputs) { + Instruction *I = dyn_cast(V); + if (I == 0) return; + // If the instruction is in the InstInputs list, remove it. SmallVectorImpl::iterator Entry = std::find(InstInputs.begin(), InstInputs.end(), I); @@ -120,34 +123,15 @@ return; } + assert(!isa(I) && "Error, removing something that isn't an input"); + // Otherwise, it must have instruction inputs itself. Zap them recursively. - bool HadInstInputs = false; for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - if (Instruction *Op = dyn_cast(I->getOperand(i))) { + if (Instruction *Op = dyn_cast(I->getOperand(i))) RemoveInstInputs(Op, InstInputs); - HadInstInputs = true; - } } - - // This instruction had to have operands in the instinputs list or it should - // have been in the list itself. If not, the list is broken. - assert(HadInstInputs && "InstInputs list inconsistent!"); } -/// ReplaceInstWithValue - Remove any instruction inputs in the InstInputs -/// array that are due to the specified instruction that is about to be -/// removed from the address, and add any corresponding to V. This returns V. -Value *PHITransAddr::ReplaceInstWithValue(Instruction *I, Value *V) { - // Remove the old instruction from InstInputs. - RemoveInstInputs(I, InstInputs); - - // If V is an instruction, it is now an input. - if (Instruction *VI = dyn_cast(V)) - InstInputs.push_back(VI); - return V; -} - - Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB) { // If this is a non-instruction value, it can't require PHI translation. @@ -168,18 +152,18 @@ // If 'Inst' is defined in this block and is an input that needs to be phi // translated, we need to incorporate the value into the expression or fail. + // In either case, the instruction itself isn't an input any longer. + InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst)); + // If this is a PHI, go ahead and translate it. if (PHINode *PN = dyn_cast(Inst)) - return ReplaceInstWithValue(PN, PN->getIncomingValueForBlock(PredBB)); + return AddAsInput(PN->getIncomingValueForBlock(PredBB)); // If this is a non-phi value, and it is analyzable, we can incorporate it // into the expression by making all instruction operands be inputs. if (!CanPHITrans(Inst)) return 0; - // The instruction itself isn't an input any longer. - InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst)); - // All instruction operands are now inputs (and of course, they may also be // defined in this block, so they may need to be phi translated themselves. for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i) @@ -201,8 +185,7 @@ // Constants are trivial to find. if (Constant *C = dyn_cast(PHIIn)) - return ReplaceInstWithValue(BC, ConstantExpr::getBitCast(C, - BC->getType())); + return AddAsInput(ConstantExpr::getBitCast(C, BC->getType())); // Otherwise we have to see if a bitcasted version of the incoming pointer // is available. If so, we can use it, otherwise we have to fail. @@ -232,8 +215,12 @@ return GEP; // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) - return ReplaceInstWithValue(GEP, V); + if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) { + for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) + RemoveInstInputs(GEPOps[i], InstInputs); + + return AddAsInput(V); + } // Scan to see if we have this GEP available. Value *APHIOp = GEPOps[0]; @@ -274,11 +261,21 @@ LHS = BOp->getOperand(0); RHS = ConstantExpr::getAdd(RHS, CI); isNSW = isNUW = false; + + // If the old 'LHS' was an input, add the new 'LHS' as an input. + if (std::count(InstInputs.begin(), InstInputs.end(), BOp)) { + RemoveInstInputs(BOp, InstInputs); + AddAsInput(LHS); + } } // See if the add simplifies away. - if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) - return ReplaceInstWithValue(Inst, Res); + if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) { + // If we simplified the operands, the LHS is no longer an input, but Res + // is. + RemoveInstInputs(LHS, InstInputs); + return AddAsInput(Res); + } // Otherwise, see if we have this add available somewhere. for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); From stuart at apple.com Tue Dec 8 18:56:54 2009 From: stuart at apple.com (Stuart Hastings) Date: Wed, 09 Dec 2009 00:56:54 -0000 Subject: [llvm-commits] [test-suite] r90916 - /test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c Message-ID: <200912090056.nB90usBp031802@zion.cs.uiuc.edu> Author: stuart Date: Tue Dec 8 18:56:54 2009 New Revision: 90916 URL: http://llvm.org/viewvc/llvm-project?rev=90916&view=rev Log: Test case for r90914. Added: test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c Added: test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c?rev=90916&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c (added) +++ test-suite/trunk/SingleSource/UnitTests/2009-12-07-StructReturn.c Tue Dec 8 18:56:54 2009 @@ -0,0 +1,35 @@ +/* */ +/* Just enough complexity to frighten the optimizer and expose a bug + in an ugly one-file testcase. */ +extern int printf(const char * __restrict, ...); +extern void abort(void); +typedef struct { + float ary[3]; +} foostruct; +typedef struct { + foostruct foo; + float safe; +} barstruct; +barstruct bar_ary[4]; +float * __attribute__ ((__noinline__)) + spooky(int i) { + bar_ary[i].safe = 142.0; + return &bar_ary[i].safe; +} +foostruct __attribute__ ((__noinline__)) +foobify(void) { + static barstruct my_static_foo = { {42.0, 42.0, 42.0}, /*safe=*/42.0 }; + return my_static_foo.foo; +} +int +main(int argc, char *argv[]) { + float *pf = spooky(0); + /* This should store exactly 96 bits. Some compilers stored 128 + bits, clobbering beyond the end of the "foo" struct. */ + bar_ary[0].foo = foobify(); + if (*pf != 142.0) { + printf("error: store clobbered memory outside destination\n"); + abort(); + } + return 0; +} From evan.cheng at apple.com Tue Dec 8 19:05:00 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 01:05:00 -0000 Subject: [llvm-commits] [llvm] r90917 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200912090105.nB9150FC032051@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 19:04:59 2009 New Revision: 90917 URL: http://llvm.org/viewvc/llvm-project?rev=90917&view=rev Log: Refactor InferAlignment out of DAGCombine. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=90917&r1=90916&r2=90917&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Dec 8 19:04:59 2009 @@ -890,6 +890,10 @@ /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); + /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if + /// it cannot be inferred. + unsigned InferPtrAlignment(SDValue Ptr); + private: bool RemoveNodeFromCSEMaps(SDNode *N); void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=90917&r1=90916&r2=90917&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 8 19:04:59 2009 @@ -4811,49 +4811,6 @@ return false; } -/// InferAlignment - If we can infer some alignment information from this -/// pointer, return it. -static unsigned InferAlignment(SDValue Ptr, SelectionDAG &DAG) { - // If this is a direct reference to a stack slot, use information about the - // stack slot's alignment. - int FrameIdx = 1 << 31; - int64_t FrameOffset = 0; - if (FrameIndexSDNode *FI = dyn_cast(Ptr)) { - FrameIdx = FI->getIndex(); - } else if (Ptr.getOpcode() == ISD::ADD && - isa(Ptr.getOperand(1)) && - isa(Ptr.getOperand(0))) { - FrameIdx = cast(Ptr.getOperand(0))->getIndex(); - FrameOffset = Ptr.getConstantOperandVal(1); - } - - if (FrameIdx != (1 << 31)) { - // FIXME: Handle FI+CST. - const MachineFrameInfo &MFI = *DAG.getMachineFunction().getFrameInfo(); - if (MFI.isFixedObjectIndex(FrameIdx)) { - int64_t ObjectOffset = MFI.getObjectOffset(FrameIdx) + FrameOffset; - - // The alignment of the frame index can be determined from its offset from - // the incoming frame position. If the frame object is at offset 32 and - // the stack is guaranteed to be 16-byte aligned, then we know that the - // object is 16-byte aligned. - unsigned StackAlign = DAG.getTarget().getFrameInfo()->getStackAlignment(); - unsigned Align = MinAlign(ObjectOffset, StackAlign); - - // Finally, the frame object itself may have a known alignment. Factor - // the alignment + offset into a new alignment. For example, if we know - // the FI is 8 byte aligned, but the pointer is 4 off, we really have a - // 4-byte alignment of the resultant pointer. Likewise align 4 + 4-byte - // offset = 4-byte alignment, align 4 + 1-byte offset = align 1, etc. - unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx), - FrameOffset); - return std::max(Align, FIInfoAlign); - } - } - - return 0; -} - SDValue DAGCombiner::visitLOAD(SDNode *N) { LoadSDNode *LD = cast(N); SDValue Chain = LD->getChain(); @@ -4861,7 +4818,7 @@ // Try to infer better alignment information than the load already has. if (OptLevel != CodeGenOpt::None && LD->isUnindexed()) { - if (unsigned Align = InferAlignment(Ptr, DAG)) { + if (unsigned Align = DAG.InferPtrAlignment(Ptr)) { if (Align > LD->getAlignment()) return DAG.getExtLoad(LD->getExtensionType(), N->getDebugLoc(), LD->getValueType(0), @@ -5086,7 +5043,7 @@ // Try to infer better alignment information than the store already has. if (OptLevel != CodeGenOpt::None && ST->isUnindexed()) { - if (unsigned Align = InferAlignment(Ptr, DAG)) { + if (unsigned Align = DAG.InferPtrAlignment(Ptr)) { if (Align > ST->getAlignment()) return DAG.getTruncStore(Chain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(), Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=90917&r1=90916&r2=90917&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 8 19:04:59 2009 @@ -27,6 +27,7 @@ #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetInstrInfo.h" @@ -5867,6 +5868,49 @@ &Scalars[0], Scalars.size()); } +/// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if +/// it cannot be inferred. +unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) { + // If this is a direct reference to a stack slot, use information about the + // stack slot's alignment. + int FrameIdx = 1 << 31; + int64_t FrameOffset = 0; + if (FrameIndexSDNode *FI = dyn_cast(Ptr)) { + FrameIdx = FI->getIndex(); + } else if (Ptr.getOpcode() == ISD::ADD && + isa(Ptr.getOperand(1)) && + isa(Ptr.getOperand(0))) { + FrameIdx = cast(Ptr.getOperand(0))->getIndex(); + FrameOffset = Ptr.getConstantOperandVal(1); + } + + if (FrameIdx != (1 << 31)) { + // FIXME: Handle FI+CST. + const MachineFrameInfo &MFI = *getMachineFunction().getFrameInfo(); + if (MFI.isFixedObjectIndex(FrameIdx)) { + int64_t ObjectOffset = MFI.getObjectOffset(FrameIdx) + FrameOffset; + + // The alignment of the frame index can be determined from its offset from + // the incoming frame position. If the frame object is at offset 32 and + // the stack is guaranteed to be 16-byte aligned, then we know that the + // object is 16-byte aligned. + unsigned StackAlign = getTarget().getFrameInfo()->getStackAlignment(); + unsigned Align = MinAlign(ObjectOffset, StackAlign); + + // Finally, the frame object itself may have a known alignment. Factor + // the alignment + offset into a new alignment. For example, if we know + // the FI is 8 byte aligned, but the pointer is 4 off, we really have a + // 4-byte alignment of the resultant pointer. Likewise align 4 + 4-byte + // offset = 4-byte alignment, align 4 + 1-byte offset = align 1, etc. + unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx), + FrameOffset); + return std::max(Align, FIInfoAlign); + } + } + + return 0; +} + void SelectionDAG::dump() const { errs() << "SelectionDAG has " << AllNodes.size() << " nodes:"; From evan.cheng at apple.com Tue Dec 8 19:10:37 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 01:10:37 -0000 Subject: [llvm-commits] [llvm] r90918 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200912090110.nB91Abme032260@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 19:10:37 2009 New Revision: 90918 URL: http://llvm.org/viewvc/llvm-project?rev=90918&view=rev Log: Add const qualifier. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=90918&r1=90917&r2=90918&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Dec 8 19:10:37 2009 @@ -892,7 +892,7 @@ /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. - unsigned InferPtrAlignment(SDValue Ptr); + unsigned InferPtrAlignment(SDValue Ptr) const; private: bool RemoveNodeFromCSEMaps(SDNode *N); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=90918&r1=90917&r2=90918&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 8 19:10:37 2009 @@ -5870,7 +5870,7 @@ /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. -unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) { +unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { // If this is a direct reference to a stack slot, use information about the // stack slot's alignment. int FrameIdx = 1 << 31; From evan.cheng at apple.com Tue Dec 8 19:17:24 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 01:17:24 -0000 Subject: [llvm-commits] [llvm] r90919 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200912090117.nB91HOwX032489@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 19:17:24 2009 New Revision: 90919 URL: http://llvm.org/viewvc/llvm-project?rev=90919&view=rev Log: Infer alignment for non-fixed stack object. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=90919&r1=90918&r2=90919&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 8 19:17:24 2009 @@ -5887,6 +5887,8 @@ if (FrameIdx != (1 << 31)) { // FIXME: Handle FI+CST. const MachineFrameInfo &MFI = *getMachineFunction().getFrameInfo(); + unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx), + FrameOffset); if (MFI.isFixedObjectIndex(FrameIdx)) { int64_t ObjectOffset = MFI.getObjectOffset(FrameIdx) + FrameOffset; @@ -5899,13 +5901,12 @@ // Finally, the frame object itself may have a known alignment. Factor // the alignment + offset into a new alignment. For example, if we know - // the FI is 8 byte aligned, but the pointer is 4 off, we really have a + // the FI is 8 byte aligned, but the pointer is 4 off, we really have a // 4-byte alignment of the resultant pointer. Likewise align 4 + 4-byte // offset = 4-byte alignment, align 4 + 1-byte offset = align 1, etc. - unsigned FIInfoAlign = MinAlign(MFI.getObjectAlignment(FrameIdx), - FrameOffset); return std::max(Align, FIInfoAlign); } + return FIInfoAlign; } return 0; From sabre at nondot.org Tue Dec 8 19:19:16 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 01:19:16 -0000 Subject: [llvm-commits] [llvm] r90920 - /llvm/trunk/lib/Analysis/PHITransAddr.cpp Message-ID: <200912090119.nB91JGsU032553@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 19:19:16 2009 New Revision: 90920 URL: http://llvm.org/viewvc/llvm-project?rev=90920&view=rev Log: fix a nasty variable that was shadowing the real CurBB but with the wrong value. Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90920&r1=90919&r2=90920&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Tue Dec 8 19:19:16 2009 @@ -201,7 +201,6 @@ // Handle getelementptr with at least one PHI translatable operand. if (GetElementPtrInst *GEP = dyn_cast(Inst)) { SmallVector GEPOps; - BasicBlock *CurBB = GEP->getParent(); bool AnyChanged = false; for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); From dalej at apple.com Tue Dec 8 19:24:15 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 8 Dec 2009 17:24:15 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r90914 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200912090055.nB90tvrY031749@zion.cs.uiuc.edu> References: <200912090055.nB90tvrY031749@zion.cs.uiuc.edu> Message-ID: <4A46CD25-362B-426E-B6A1-DE5AF5B08FCA@apple.com> On Dec 8, 2009, at 4:55 PMPST, Stuart Hastings wrote: > Author: stuart > Date: Tue Dec 8 18:55:56 2009 > New Revision: 90914 > > URL: http://llvm.org/viewvc/llvm-project?rev=90914&view=rev > Log: > If a callee returns a structure in registers, but the stored image of > those registers is bigger than the destination, store the registers > into a temporary, and copy the desired (smaller) part to the > destination. > The original testcase returned an array of three 32-bit floats, > wrapped in a struct; the value was returned as two doubles in xmm0/1, > and stored as a 128-bit value. You're assuming the useful bits in the temp are at the address of the temp; this might not be true for some targets, especially big-endian ones. I'm therefore inclined to think this should go in the target- specific area(s). Don't know of a counterexample offhand, but please test on PPC in case I'm wrong:) (gcc compatibility tests at least). > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=90914&r1=90913&r2=90914&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Dec 8 18:55:56 2009 > @@ -2776,8 +2776,26 @@ > return 0; > > if (Client.isAggrReturn()) { > - Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()- > >getPointerTo()); > - LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc- > >Volatile,Builder); > + if (TD.getTypeAllocSize(Call->getType()) <= > TD.getTypeAllocSize(DestLoc->Ptr->getType())) { > + Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()- > >getPointerTo()); > + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc- > >Volatile,Builder); > + } else { > + // The call will return an aggregate value in registers, but > + // those registers are bigger than DestLoc. Allocate a > + // temporary to match the registers, store the registers there, > + // cast the temporary into the correct (smaller) type, and > using > + // the correct type, copy the value into DestLoc. Assume the > + // optimizer will delete the temporary and clean this up. > + AllocaInst *biggerTmp = CreateTemporary(Call->getType()); > + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,biggerTmp,/ > *Volatile=*/false, > + Builder); > + EmitAggregateCopy(*DestLoc, > + MemRef(BitCastToType(biggerTmp,Call->getType()-> > + getPointerTo()), > + DestLoc->getAlignment(), > + DestLoc->Volatile), > + TREE_TYPE(exp)); > + } > return 0; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Dec 8 19:36:00 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 01:36:00 -0000 Subject: [llvm-commits] [llvm] r90922 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/X86/X86ISelLowering.cpp Message-ID: <200912090136.nB91a1HJ000630@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 19:36:00 2009 New Revision: 90922 URL: http://llvm.org/viewvc/llvm-project?rev=90922&view=rev Log: Move isConsecutiveLoad to SelectionDAG. It's not target dependent and it's primary used by selectdag passes. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Dec 8 19:36:00 2009 @@ -890,6 +890,12 @@ /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); + /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a + /// location that is 'Dist' units away from the location that the 'Base' load + /// is loading from. + bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, + unsigned Bytes, int Dist) const; + /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. unsigned InferPtrAlignment(SDValue Ptr) const; Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Dec 8 19:36:00 2009 @@ -857,12 +857,6 @@ virtual bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const; - /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a - /// location that is 'Dist' units away from the location that the 'Base' load - /// is loading from. - bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, - int Dist, const MachineFrameInfo *MFI) const; - /// PerformDAGCombine - This method will be invoked for all target nodes and /// for any target-independent nodes that the target has registered with /// invoke it for. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 8 19:36:00 2009 @@ -3688,7 +3688,6 @@ if (!LD1 || !LD2 || !ISD::isNON_EXTLoad(LD1) || !LD1->hasOneUse()) return SDValue(); EVT LD1VT = LD1->getValueType(0); - const MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); if (ISD::isNON_EXTLoad(LD2) && LD2->hasOneUse() && @@ -3696,7 +3695,7 @@ // If one is volatile it might be ok, but play conservative and bail out. !LD1->isVolatile() && !LD2->isVolatile() && - TLI.isConsecutiveLoad(LD2, LD1, LD1VT.getSizeInBits()/8, 1, MFI)) { + DAG.isConsecutiveLoad(LD2, LD1, LD1VT.getSizeInBits()/8, 1)) { unsigned Align = LD1->getAlignment(); unsigned NewAlign = TLI.getTargetData()-> getABITypeAlignment(VT.getTypeForEVT(*DAG.getContext())); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 8 19:36:00 2009 @@ -5868,6 +5868,49 @@ &Scalars[0], Scalars.size()); } + +/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a +/// location that is 'Dist' units away from the location that the 'Base' load +/// is loading from. +bool SelectionDAG::isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, + unsigned Bytes, int Dist) const { + if (LD->getChain() != Base->getChain()) + return false; + EVT VT = LD->getValueType(0); + if (VT.getSizeInBits() / 8 != Bytes) + return false; + + SDValue Loc = LD->getOperand(1); + SDValue BaseLoc = Base->getOperand(1); + if (Loc.getOpcode() == ISD::FrameIndex) { + if (BaseLoc.getOpcode() != ISD::FrameIndex) + return false; + const MachineFrameInfo *MFI = getMachineFunction().getFrameInfo(); + int FI = cast(Loc)->getIndex(); + int BFI = cast(BaseLoc)->getIndex(); + int FS = MFI->getObjectSize(FI); + int BFS = MFI->getObjectSize(BFI); + if (FS != BFS || FS != (int)Bytes) return false; + return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes); + } + if (Loc.getOpcode() == ISD::ADD && Loc.getOperand(0) == BaseLoc) { + ConstantSDNode *V = dyn_cast(Loc.getOperand(1)); + if (V && (V->getSExtValue() == Dist*Bytes)) + return true; + } + + GlobalValue *GV1 = NULL; + GlobalValue *GV2 = NULL; + int64_t Offset1 = 0; + int64_t Offset2 = 0; + bool isGA1 = TLI.isGAPlusOffset(Loc.getNode(), GV1, Offset1); + bool isGA2 = TLI.isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2); + if (isGA1 && isGA2 && GV1 == GV2) + return Offset1 == (Offset2 + Dist*Bytes); + return false; +} + + /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Dec 8 19:36:00 2009 @@ -2184,48 +2184,6 @@ } -/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a -/// location that is 'Dist' units away from the location that the 'Base' load -/// is loading from. -bool TargetLowering::isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, - unsigned Bytes, int Dist, - const MachineFrameInfo *MFI) const { - if (LD->getChain() != Base->getChain()) - return false; - EVT VT = LD->getValueType(0); - if (VT.getSizeInBits() / 8 != Bytes) - return false; - - SDValue Loc = LD->getOperand(1); - SDValue BaseLoc = Base->getOperand(1); - if (Loc.getOpcode() == ISD::FrameIndex) { - if (BaseLoc.getOpcode() != ISD::FrameIndex) - return false; - int FI = cast(Loc)->getIndex(); - int BFI = cast(BaseLoc)->getIndex(); - int FS = MFI->getObjectSize(FI); - int BFS = MFI->getObjectSize(BFI); - if (FS != BFS || FS != (int)Bytes) return false; - return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes); - } - if (Loc.getOpcode() == ISD::ADD && Loc.getOperand(0) == BaseLoc) { - ConstantSDNode *V = dyn_cast(Loc.getOperand(1)); - if (V && (V->getSExtValue() == Dist*Bytes)) - return true; - } - - GlobalValue *GV1 = NULL; - GlobalValue *GV2 = NULL; - int64_t Offset1 = 0; - int64_t Offset2 = 0; - bool isGA1 = isGAPlusOffset(Loc.getNode(), GV1, Offset1); - bool isGA2 = isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2); - if (isGA1 && isGA2 && GV1 == GV2) - return Offset1 == (Offset2 + Dist*Bytes); - return false; -} - - SDValue TargetLowering:: PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { // Default implementation: no optimization. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=90922&r1=90921&r2=90922&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 8 19:36:00 2009 @@ -8366,7 +8366,7 @@ continue; LoadSDNode *LD = cast(Elt); - if (!TLI.isConsecutiveLoad(LD, LDBase, EltVT.getSizeInBits()/8, i, MFI)) + if (!DAG.isConsecutiveLoad(LD, LDBase, EltVT.getSizeInBits()/8, i)) return false; LastLoadedElt = i; } From dpatel at apple.com Tue Dec 8 19:46:00 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 09 Dec 2009 01:46:00 -0000 Subject: [llvm-commits] [llvm] r90923 - in /llvm/trunk/test/DebugInfo: 2008-10-17-C++DebugCrash.ll 2008-11-05-InlinedFuncStart.ll 2009-01-15-RecordVariableCrash.ll 2009-02-18-DefaultScope-Crash.ll 2009-06-12-Inline.ll 2009-06-12-InlineFuncStart.ll 2009-06-15-InlineFuncStart.ll 2009-06-15-abstract_origin.ll Message-ID: <200912090146.nB91k1t5000960@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 8 19:46:00 2009 New Revision: 90923 URL: http://llvm.org/viewvc/llvm-project?rev=90923&view=rev Log: Remove tests that are not suitable anymore. Plus they are not testing the original bugfixes anymore. These tests were inserted to check bug fixes in code that handled debug info intrinsics. These intrinsics are no longer used and now llvm parser simply ignores old .dbg intrinsics from these dead tests. Removed: llvm/trunk/test/DebugInfo/2008-10-17-C++DebugCrash.ll llvm/trunk/test/DebugInfo/2008-11-05-InlinedFuncStart.ll llvm/trunk/test/DebugInfo/2009-01-15-RecordVariableCrash.ll llvm/trunk/test/DebugInfo/2009-02-18-DefaultScope-Crash.ll llvm/trunk/test/DebugInfo/2009-06-12-Inline.ll llvm/trunk/test/DebugInfo/2009-06-12-InlineFuncStart.ll llvm/trunk/test/DebugInfo/2009-06-15-InlineFuncStart.ll llvm/trunk/test/DebugInfo/2009-06-15-abstract_origin.ll Removed: llvm/trunk/test/DebugInfo/2008-10-17-C++DebugCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2008-10-17-C%2B%2BDebugCrash.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2008-10-17-C++DebugCrash.ll (original) +++ llvm/trunk/test/DebugInfo/2008-10-17-C++DebugCrash.ll (removed) @@ -1,58 +0,0 @@ -; RUN: llc < %s -; PR2885 - -;; NOTE: This generates bad debug info in this case! But that's better than -;; ICEing. - -; ModuleID = 'bug.bc' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" -target triple = "i386-pc-linux-gnu" - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* } - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([11 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 14, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true } ; <%llvm.dbg.subprogram.type*> [#uses=0] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 } ; <%llvm.dbg.anchor.type*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 393233, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([7 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([16 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) } ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 } ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [7 x i8] c"die.cc\00" ; <[7 x i8]*> [#uses=1] - at .str1 = internal constant [16 x i8] c"/home/nicholas/\00" ; <[16 x i8]*> [#uses=1] - at .str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5623) (LLVM build)\00" ; <[52 x i8]*> [#uses=1] - at .str3 = internal constant [11 x i8] c"AssertFail\00" ; <[11 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 } ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"int\00" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram5 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([7 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 19, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype7 to { }*), i1 true, i1 true } ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str6 = internal constant [7 x i8] c"FooOne\00" ; <[7 x i8]*> [#uses=1] - at llvm.dbg.basictype7 = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([9 x i8]* @.str8, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 } ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str8 = internal constant [9 x i8] c"long int\00" ; <[9 x i8]*> [#uses=1] - at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 393473, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*), i8* getelementptr ([6 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 19, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype10 to { }*) } ; <%llvm.dbg.variable.type*> [#uses=0] - at .str9 = internal constant [6 x i8] c"count\00" ; <[6 x i8]*> [#uses=1] - at llvm.dbg.basictype10 = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str11, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7 } ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str11 = internal constant [18 x i8] c"long unsigned int\00" ; <[18 x i8]*> [#uses=1] - at llvm.dbg.subprogram12 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([7 x i8]* @.str13, i32 0, i32 0), i8* getelementptr ([7 x i8]* @.str13, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 24, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype7 to { }*), i1 true, i1 true } ; <%llvm.dbg.subprogram.type*> [#uses=0] - at .str13 = internal constant [7 x i8] c"FooTwo\00" ; <[7 x i8]*> [#uses=1] - at llvm.dbg.subprogram14 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([9 x i8]* @.str15, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str15, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str16, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 29, { }* null, i1 false, i1 true } ; <%llvm.dbg.subprogram.type*> [#uses=0] - at .str15 = internal constant [9 x i8] c"FooThree\00" ; <[9 x i8]*> [#uses=1] - at .str16 = internal constant [13 x i8] c"_Z8FooThreev\00" ; <[13 x i8]*> [#uses=1] - -declare void @_Z8FooThreev() nounwind - -define internal i32 @_ZL10AssertFailv() nounwind { -entry: - unreachable -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @abort() noreturn nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -declare i32 @_ZL6FooOnem(i32) nounwind - -declare void @llvm.dbg.declare({ }*, { }*) nounwind - -declare i32 @_ZL6FooTwov() nounwind Removed: llvm/trunk/test/DebugInfo/2008-11-05-InlinedFuncStart.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2008-11-05-InlinedFuncStart.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2008-11-05-InlinedFuncStart.ll (original) +++ llvm/trunk/test/DebugInfo/2008-11-05-InlinedFuncStart.ll (removed) @@ -1,72 +0,0 @@ -; RUN: llc < %s -; RUN: llc %s -o - -O0 - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 393233, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at .str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5627) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] - at .str3 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram5 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - -define i32 @foo() nounwind alwaysinline { -entry: - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 42, i32* %0, align 4 - %1 = load i32* %0, align 4 ; [#uses=1] - store i32 %1, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval1 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -define i32 @main() nounwind { -entry: - %retval.i = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %retval = alloca i32 ; [#uses=2] - %1 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - store i32 42, i32* %0, align 4 - %2 = load i32* %0, align 4 ; [#uses=1] - store i32 %2, i32* %retval.i, align 4 - %retval1.i = load i32* %retval.i ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - store i32 %retval1.i, i32* %1, align 4 - %3 = load i32* %1, align 4 ; [#uses=1] - store i32 %3, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - ret i32 %retval1 -} Removed: llvm/trunk/test/DebugInfo/2009-01-15-RecordVariableCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-01-15-RecordVariableCrash.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-01-15-RecordVariableCrash.ll (original) +++ llvm/trunk/test/DebugInfo/2009-01-15-RecordVariableCrash.ll (removed) @@ -1,353 +0,0 @@ -; RUN: llc %s -o /dev/null -verify-dom-info -verify-loop-info - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } - %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, i8*, i8* } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }*, i8*, i8* } - %struct._RuneCharClass = type { [14 x i8], i32 } - %struct._RuneEntry = type { i32, i32, i32, i32* } - %struct._RuneLocale = type { [8 x i8], [32 x i8], i32 (i8*, i32, i8**)*, i32 (i32, i8*, i32, i8**)*, i32, [256 x i32], [256 x i32], [256 x i32], %struct._RuneRange, %struct._RuneRange, %struct._RuneRange, i8*, i32, i32, %struct._RuneCharClass* } - %struct._RuneRange = type { i32, %struct._RuneEntry* } - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"x.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at .str2 = internal constant [57 x i8] c"4.2.1 (Based on Apple Inc. build 5628) (LLVM build 9999)\00", section "llvm.metadata" ; <[57 x i8]*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([57 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at .str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str4 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 21, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str5 = internal constant [2 x i8] c"i\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] - at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 22, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str6 = internal constant [8 x i8] c"islower\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at llvm.dbg.subprogram9 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 267, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str10 = internal constant [3 x i8] c"_c\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] - at llvm.dbg.variable11 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 266, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str12 = internal constant [9 x i8] c"__istype\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1] - at llvm.dbg.subprogram13 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 171, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str14 = internal constant [19 x i8] c"__darwin_ct_rune_t\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1] - at .str15 = internal constant [9 x i8] c"_types.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1] - at .str16 = internal constant [18 x i8] c"/usr/include/i386\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] - at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458774, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([19 x i8]* @.str14, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 70, i64 0, i64 0, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([9 x i8]* @.str15, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str16, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.variable17 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str18 = internal constant [18 x i8] c"long unsigned int\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] - at llvm.dbg.basictype19 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str18, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str20 = internal constant [3 x i8] c"_f\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] - at llvm.dbg.variable21 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str20, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at _DefaultRuneLocale = external global %struct._RuneLocale ; <%struct._RuneLocale*> [#uses=1] - at .str22 = internal constant [8 x i8] c"isascii\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at llvm.dbg.subprogram23 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 153, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 152, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str25 = internal constant [8 x i8] c"toupper\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at llvm.dbg.subprogram26 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 316, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.variable27 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 315, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - -define i32 @main() nounwind { -entry: - %retval = alloca i32 ; [#uses=1] - %i = alloca i32 ; [#uses=16] - %iftmp.5 = alloca i32 ; [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - %0 = bitcast i32* %i to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) - call void @llvm.dbg.stoppoint(i32 23, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 0, i32* %i, align 4 - br label %bb13 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 23, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb - -bb: ; preds = %bb13, %1 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %2 = load i32* %i, align 4 ; [#uses=1] - %3 = call i32 @islower(i32 %2) nounwind ; [#uses=1] - %4 = icmp eq i32 %3, 0 ; [#uses=1] - br i1 %4, label %bb3, label %bb1 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb1 - -bb1: ; preds = %5, %bb - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %6 = load i32* %i, align 4 ; [#uses=1] - %7 = icmp sle i32 %6, 96 ; [#uses=1] - br i1 %7, label %bb11, label %bb2 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb2 - -bb2: ; preds = %8, %bb1 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %9 = load i32* %i, align 4 ; [#uses=1] - %10 = icmp sgt i32 %9, 122 ; [#uses=1] - br i1 %10, label %bb11, label %bb3 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb3 - -bb3: ; preds = %11, %bb2, %bb - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %12 = load i32* %i, align 4 ; [#uses=1] - %13 = call i32 @islower(i32 %12) nounwind ; [#uses=1] - %14 = icmp ne i32 %13, 0 ; [#uses=1] - br i1 %14, label %bb6, label %bb4 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb4 - -bb4: ; preds = %15, %bb3 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %16 = load i32* %i, align 4 ; [#uses=1] - %17 = icmp sle i32 %16, 96 ; [#uses=1] - br i1 %17, label %bb6, label %bb5 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb5 - -bb5: ; preds = %18, %bb4 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %19 = load i32* %i, align 4 ; [#uses=1] - %20 = icmp sle i32 %19, 122 ; [#uses=1] - br i1 %20, label %bb11, label %bb6 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb6 - -bb6: ; preds = %21, %bb5, %bb4, %bb3 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %22 = load i32* %i, align 4 ; [#uses=1] - %23 = call i32 @toupper(i32 %22) nounwind ; [#uses=1] - %24 = load i32* %i, align 4 ; [#uses=1] - %25 = icmp sle i32 %24, 96 ; [#uses=1] - br i1 %25, label %bb9, label %bb7 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb7 - -bb7: ; preds = %26, %bb6 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %27 = load i32* %i, align 4 ; [#uses=1] - %28 = icmp sgt i32 %27, 122 ; [#uses=1] - br i1 %28, label %bb9, label %bb8 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb8 - -bb8: ; preds = %29, %bb7 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %30 = load i32* %i, align 4 ; [#uses=1] - %31 = sub i32 %30, 32 ; [#uses=1] - store i32 %31, i32* %iftmp.5, align 4 - br label %bb10 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb9 - -bb9: ; preds = %32, %bb7, %bb6 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %33 = load i32* %i, align 4 ; [#uses=1] - store i32 %33, i32* %iftmp.5, align 4 - br label %bb10 - -bb10: ; preds = %bb9, %bb8 - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %34 = load i32* %iftmp.5, align 4 ; [#uses=1] - %35 = icmp ne i32 %23, %34 ; [#uses=1] - br i1 %35, label %bb11, label %bb12 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 24, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb11 - -bb11: ; preds = %36, %bb10, %bb5, %bb2, %bb1 - call void @llvm.dbg.stoppoint(i32 26, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @exit(i32 2) noreturn nounwind - unreachable - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 26, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb12 - -bb12: ; preds = %37, %bb10 - call void @llvm.dbg.stoppoint(i32 23, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %38 = load i32* %i, align 4 ; [#uses=1] - %39 = add i32 %38, 1 ; [#uses=1] - store i32 %39, i32* %i, align 4 - br label %bb13 - -bb13: ; preds = %bb12, %entry - call void @llvm.dbg.stoppoint(i32 23, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %40 = load i32* %i, align 4 ; [#uses=1] - %41 = icmp sle i32 %40, 255 ; [#uses=1] - br i1 %41, label %bb, label %bb14 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 23, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb14 - -bb14: ; preds = %42, %bb13 - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @exit(i32 0) noreturn nounwind - unreachable - -return: ; No predecessors! - %retval15 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval15 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.declare({ }*, { }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -define internal i32 @islower(i32 %_c) nounwind { -entry: - %_c_addr = alloca i32 ; [#uses=3] - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*)) - %1 = bitcast i32* %_c_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable11 to { }*)) - store i32 %_c, i32* %_c_addr - call void @llvm.dbg.stoppoint(i32 268, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %2 = load i32* %_c_addr, align 4 ; [#uses=1] - %3 = call i32 @__istype(i32 %2, i32 4096) nounwind ; [#uses=1] - store i32 %3, i32* %0, align 4 - %4 = load i32* %0, align 4 ; [#uses=1] - store i32 %4, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 268, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*)) - ret i32 %retval1 -} - -define internal i32 @toupper(i32 %_c) nounwind { -entry: - %_c_addr = alloca i32 ; [#uses=3] - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*)) - %1 = bitcast i32* %_c_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable27 to { }*)) - store i32 %_c, i32* %_c_addr - call void @llvm.dbg.stoppoint(i32 317, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %2 = load i32* %_c_addr, align 4 ; [#uses=1] - %3 = call i32 @__toupper(i32 %2) nounwind ; [#uses=1] - store i32 %3, i32* %0, align 4 - %4 = load i32* %0, align 4 ; [#uses=1] - store i32 %4, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 317, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*)) - ret i32 %retval1 -} - -declare void @exit(i32) noreturn nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -define internal i32 @__istype(i32 %_c, i32 %_f) nounwind { -entry: - %_c_addr = alloca i32 ; [#uses=5] - %_f_addr = alloca i32 ; [#uses=4] - %retval = alloca i32 ; [#uses=2] - %iftmp.0 = alloca i32 ; [#uses=3] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*)) - %1 = bitcast i32* %_c_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable17 to { }*)) - store i32 %_c, i32* %_c_addr - %2 = bitcast i32* %_f_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %2, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable21 to { }*)) - store i32 %_f, i32* %_f_addr - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %3 = load i32* %_c_addr, align 4 ; [#uses=1] - %4 = call i32 @isascii(i32 %3) nounwind ; [#uses=1] - %5 = icmp ne i32 %4, 0 ; [#uses=1] - br i1 %5, label %bb, label %bb1 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb - -bb: ; preds = %6, %entry - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %7 = load i32* %_c_addr, align 4 ; [#uses=1] - %8 = getelementptr [256 x i32]* getelementptr (%struct._RuneLocale* @_DefaultRuneLocale, i32 0, i32 5), i32 0, i32 %7 ; [#uses=1] - %9 = load i32* %8, align 4 ; [#uses=1] - %10 = load i32* %_f_addr, align 4 ; [#uses=1] - %11 = and i32 %9, %10 ; [#uses=1] - %12 = icmp ne i32 %11, 0 ; [#uses=1] - %13 = zext i1 %12 to i32 ; [#uses=1] - store i32 %13, i32* %iftmp.0, align 4 - br label %bb2 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb1 - -bb1: ; preds = %14, %entry - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %15 = load i32* %_c_addr, align 4 ; [#uses=1] - %16 = load i32* %_f_addr, align 4 ; [#uses=1] - %17 = call i32 @__maskrune(i32 %15, i32 %16) nounwind ; [#uses=1] - %18 = icmp ne i32 %17, 0 ; [#uses=1] - %19 = zext i1 %18 to i32 ; [#uses=1] - store i32 %19, i32* %iftmp.0, align 4 - br label %bb2 - -bb2: ; preds = %bb1, %bb - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %20 = load i32* %iftmp.0, align 4 ; [#uses=1] - store i32 %20, i32* %0, align 4 - %21 = load i32* %0, align 4 ; [#uses=1] - store i32 %21, i32* %retval, align 4 - br label %return - -return: ; preds = %bb2 - %retval3 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 175, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*)) - ret i32 %retval3 -} - -define internal i32 @isascii(i32 %_c) nounwind { -entry: - %_c_addr = alloca i32 ; [#uses=3] - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*)) - %1 = bitcast i32* %_c_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable24 to { }*)) - store i32 %_c, i32* %_c_addr - call void @llvm.dbg.stoppoint(i32 154, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %2 = load i32* %_c_addr, align 4 ; [#uses=1] - %3 = and i32 %2, -128 ; [#uses=1] - %4 = icmp eq i32 %3, 0 ; [#uses=1] - %5 = zext i1 %4 to i32 ; [#uses=1] - store i32 %5, i32* %0, align 4 - %6 = load i32* %0, align 4 ; [#uses=1] - store i32 %6, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 154, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*)) - ret i32 %retval1 -} - -declare i32 @__maskrune(i32, i32) - -declare i32 @__toupper(i32) Removed: llvm/trunk/test/DebugInfo/2009-02-18-DefaultScope-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-02-18-DefaultScope-Crash.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-02-18-DefaultScope-Crash.ll (original) +++ llvm/trunk/test/DebugInfo/2009-02-18-DefaultScope-Crash.ll (removed) @@ -1,31 +0,0 @@ -; RUN: llc %s -o /dev/null - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } - %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at .str2 = internal constant [57 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 2098)\00", section "llvm.metadata" ; <[57 x i8]*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([57 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at .str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at llvm.dbg.array = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] - at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - - at llvm.dbg.array1 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) ], section "llvm.metadata" - -define i32 @foo() nounwind ssp { -entry: - ret i32 42 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind Removed: llvm/trunk/test/DebugInfo/2009-06-12-Inline.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-06-12-Inline.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-06-12-Inline.ll (original) +++ llvm/trunk/test/DebugInfo/2009-06-12-Inline.ll (removed) @@ -1,94 +0,0 @@ -; RUN: llc %s -o /dev/null - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 } - %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i32 } - %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* } - %struct._objc_cache = type opaque - %struct._objc_category = type { i8*, i8*, %struct._objc_method_list*, %struct._objc_method_list*, %struct._objc_protocol_list*, i32, %struct._prop_list_t* } - %struct._objc_class = type { %struct._objc_class*, %struct._objc_class*, i8*, i32, i32, i32, %struct._objc_ivar_list*, %struct._objc_method_list*, %struct._objc_cache*, %struct._objc_protocol_list*, i8*, %struct._objc_class_extension* } - %struct._objc_class_extension = type { i32, i8*, %struct._prop_list_t* } - %struct._objc_exception_data = type { [18 x i32], [4 x i8*] } - %struct._objc_ivar = type { i8*, i8*, i32 } - %struct._objc_ivar_list = type opaque - %struct._objc_method = type { %struct.objc_selector*, i8*, i8* } - %struct._objc_method_description = type { %struct.objc_selector*, i8* } - %struct._objc_method_description_list = type { i32, [0 x %struct._objc_method_description] } - %struct._objc_method_list = type opaque - %struct._objc_module = type { i32, i32, i8*, %struct._objc_symtab* } - %struct._objc_protocol = type { %struct._objc_protocol_extension*, i8*, %struct._objc_protocol_list*, %struct._objc_method_description_list*, %struct._objc_method_description_list* } - %struct._objc_protocol_extension = type { i32, %struct._objc_method_description_list*, %struct._objc_method_description_list*, %struct._prop_list_t* } - %struct._objc_protocol_list = type { %struct._objc_protocol_list*, i32, [0 x %struct._objc_protocol] } - %struct._objc_super = type <{ %struct.objc_object*, %struct.objc_class* }> - %struct._objc_symtab = type { i32, %struct.objc_selector*, i16, i16, [0 x i8*] } - %struct._prop_list_t = type { i32, i32, [0 x %struct._prop_t] } - %struct._prop_t = type { i8*, i8* } - %struct.objc_class = type opaque - %struct.objc_object = type opaque - %struct.objc_selector = type opaque -@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__OBJC, __image_info,regular" ; <[2 x i32]*> [#uses=1] - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"t.m\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [20 x i8] c"/Volumes/work/Radar\00", section "llvm.metadata" ; <[20 x i8]*> [#uses=1] - at .str2 = internal constant [10 x i8] c"clang 1.0\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 16, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([20 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([10 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str3 = internal constant [3 x i8] c"f1\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([3 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* null, i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at llvm.dbg.array = internal constant [2 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* null, i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at .str5 = internal constant [3 x i8] c"l0\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] - at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([3 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 5, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str6 = internal constant [3 x i8] c"f0\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] - at llvm.dbg.subprogram7 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([3 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str6, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* null, i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str8 = internal constant [2 x i8] c"x\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] - at llvm.dbg.variable9 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*), i8* getelementptr ([2 x i8]* @.str8, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] -@"\01L_OBJC_CLASS_NAME_" = internal global [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1 ; <[1 x i8]*> [#uses=1] -@"\01L_OBJC_MODULES" = internal global %struct._objc_module { i32 7, i32 16, i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_", i32 0, i32 0), %struct._objc_symtab* null }, section "__OBJC,__module_info,regular,no_dead_strip", align 4 ; <%struct._objc_module*> [#uses=1] - at llvm.used = appending global [3 x i8*] [i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*), i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_", i32 0, i32 0), i8* bitcast (%struct._objc_module* @"\01L_OBJC_MODULES" to i8*)], section "llvm.metadata" ; <[3 x i8*]*> [#uses=0] - -define void @f1() nounwind { -entry: - %x.addr.i = alloca i32 ; [#uses=2] - %l0 = alloca void (i32)*, align 4 ; [#uses=2] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - call void @llvm.dbg.stoppoint(i32 4, i32 3, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*)) - store i32 1, i32* %x.addr.i - %0 = bitcast i32* %x.addr.i to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable9 to { }*)) - call void @llvm.dbg.stoppoint(i32 2, i32 66, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.stoppoint(i32 5, i32 3, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*)) - %1 = bitcast void (i32)** %l0 to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) - store void (i32)* @f0, void (i32)** %l0 - call void @llvm.dbg.stoppoint(i32 6, i32 1, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret void -} - -declare void @llvm.dbg.func.start({ }*) nounwind readnone - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind readnone - -define internal void @f0(i32 %x) nounwind alwaysinline { -entry: - %x.addr = alloca i32 ; [#uses=2] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*)) - store i32 %x, i32* %x.addr - %0 = bitcast i32* %x.addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable9 to { }*)) - call void @llvm.dbg.stoppoint(i32 2, i32 66, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram7 to { }*)) - ret void -} - -declare void @llvm.dbg.declare({ }*, { }*) nounwind readnone - -declare void @llvm.dbg.region.end({ }*) nounwind readnone Removed: llvm/trunk/test/DebugInfo/2009-06-12-InlineFuncStart.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-06-12-InlineFuncStart.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-06-12-InlineFuncStart.ll (original) +++ llvm/trunk/test/DebugInfo/2009-06-12-InlineFuncStart.ll (removed) @@ -1,75 +0,0 @@ -; RUN: llc < %s -; RUN: llc %s -o - -O0 - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 393233, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at .str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5627) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] - at .str3 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram5 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - -define i32 @foo() nounwind alwaysinline { -entry: - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 42, i32* %0, align 4 - %1 = load i32* %0, align 4 ; [#uses=1] - store i32 %1, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval1 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -define i32 @main() nounwind { -entry: - %retval.i = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %retval = alloca i32 ; [#uses=2] - %1 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - br label %bb1 - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - ret i32 %retval1 - -bb1: - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - store i32 42, i32* %0, align 4 - %2 = load i32* %0, align 4 ; [#uses=1] - store i32 %2, i32* %retval.i, align 4 - %retval1.i = load i32* %retval.i ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - store i32 %retval1.i, i32* %1, align 4 - %3 = load i32* %1, align 4 ; [#uses=1] - store i32 %3, i32* %retval, align 4 - br label %return -} Removed: llvm/trunk/test/DebugInfo/2009-06-15-InlineFuncStart.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-06-15-InlineFuncStart.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-06-15-InlineFuncStart.ll (original) +++ llvm/trunk/test/DebugInfo/2009-06-15-InlineFuncStart.ll (removed) @@ -1,77 +0,0 @@ -; Test inlined function handling. This test case is copied from -; 2009-06-12-InlineFunctStart.ll with one change. In function main, the bb1 -; does not have llvm.dbg.stoppiont intrinsic before llvm.dbg.func.start. -; RUN: llc < %s -; RUN: llc %s -o - -O0 - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 393233, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at .str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5627) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] - at .str3 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.subprogram5 = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - -define i32 @foo() nounwind alwaysinline { -entry: - %retval = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 42, i32* %0, align 4 - %1 = load i32* %0, align 4 ; [#uses=1] - store i32 %1, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval1 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind - -define i32 @main() nounwind { -entry: - %retval.i = alloca i32 ; [#uses=2] - %0 = alloca i32 ; [#uses=2] - %retval = alloca i32 ; [#uses=2] - %1 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - br label %bb1 - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram5 to { }*)) - ret i32 %retval1 - -bb1: - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - store i32 42, i32* %0, align 4 - %2 = load i32* %0, align 4 ; [#uses=1] - store i32 %2, i32* %retval.i, align 4 - %retval1.i = load i32* %retval.i ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) nounwind - store i32 %retval1.i, i32* %1, align 4 - %3 = load i32* %1, align 4 ; [#uses=1] - store i32 %3, i32* %retval, align 4 - br label %return -} Removed: llvm/trunk/test/DebugInfo/2009-06-15-abstract_origin.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2009-06-15-abstract_origin.ll?rev=90922&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2009-06-15-abstract_origin.ll (original) +++ llvm/trunk/test/DebugInfo/2009-06-15-abstract_origin.ll (removed) @@ -1,275 +0,0 @@ -; RUN: llc %s -o - -asm-verbose -O0 | not grep ".long 0x0 ## DW_AT_abstract_origin" - - %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 } - %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i32 } - %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* } - %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* } - %struct.AAAAAImageParser = type { %struct.CObject* } - %struct.CObject = type { i32 } - at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str = internal constant [9 x i8] c"tcase.cc\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1] - at .str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1] - at .str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5646) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1] - at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([9 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at .str3 = internal constant [8 x i8] c"tcase.h\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at llvm.dbg.compile_unit4 = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([8 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] - at .str5 = internal constant [8 x i8] c"CObject\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at .str6 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] - at .str7 = internal constant [2 x i8] c"d\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] - at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 6, i64 32, i64 32, i64 0, i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.derivedtype8 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.array = internal constant [3 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype8 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*)], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] - at llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str10 = internal constant [4 x i8] c"set\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at .str11 = internal constant [18 x i8] c"_ZN7CObject3setEi\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] - at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str11, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 3, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.array12 = internal constant [2 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype8 to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite13 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array12 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str14 = internal constant [8 x i8] c"release\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] - at .str15 = internal constant [22 x i8] c"_ZN7CObject7releaseEv\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1] - at llvm.dbg.subprogram16 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str14, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str14, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str15, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite13 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.array17 = internal constant [3 x { }*] [{ }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to { }*)], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] - at llvm.dbg.composite18 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 1, i64 32, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array17 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.derivedtype19 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.array20 = internal constant [2 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array20 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.subprogram21 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str14, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str14, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str15, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.derivedtype22 = internal constant %llvm.dbg.derivedtype.type { i32 458790, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at .str23 = internal constant [5 x i8] c"this\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram21 to { }*), i8* getelementptr ([5 x i8]* @.str23, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 4, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype22 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at llvm.dbg.array24 = internal constant [2 x { }*] [{ }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite25 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array24 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str26 = internal constant [14 x i8] c"ReleaseObject\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1] - at .str27 = internal constant [27 x i8] c"_Z13ReleaseObjectP7CObject\00", section "llvm.metadata" ; <[27 x i8]*> [#uses=1] - at llvm.dbg.subprogram28 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([14 x i8]* @.str26, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str26, i32 0, i32 0), i8* getelementptr ([27 x i8]* @.str27, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 10, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite25 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str29 = internal constant [7 x i8] c"object\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1] - at llvm.dbg.variable30 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram28 to { }*), i8* getelementptr ([7 x i8]* @.str29, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 10, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype22 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str31 = internal constant [17 x i8] c"AAAAAImageParser\00", section "llvm.metadata" ; <[17 x i8]*> [#uses=1] - at .str33 = internal constant [13 x i8] c"mCustomWhite\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1] - at llvm.dbg.derivedtype34 = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([13 x i8]* @.str33, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 21, i64 32, i64 32, i64 0, i32 1, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.derivedtype35 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite45 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.array36 = internal constant [3 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype35 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*)], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] - at llvm.dbg.composite37 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array36 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str38 = internal constant [18 x i8] c"~AAAAAImageParser\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] - at llvm.dbg.subprogram39 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 24, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite37 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.array40 = internal constant [3 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype35 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*)], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] - at llvm.dbg.composite41 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array40 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str42 = internal constant [36 x i8] c"_ZN16AAAAAImageParser3setEP7CObject\00", section "llvm.metadata" ; <[36 x i8]*> [#uses=1] - at llvm.dbg.subprogram43 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([36 x i8]* @.str42, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 19, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite41 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.array44 = internal constant [3 x { }*] [{ }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype34 to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram39 to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram43 to { }*)], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] - at llvm.dbg.composite45 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([17 x i8]* @.str31, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 16, i64 32, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array44 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at llvm.dbg.derivedtype46 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite45 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.array47 = internal constant [2 x { }*] [{ }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype46 to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] - at llvm.dbg.composite48 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array47 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str49 = internal constant [26 x i8] c"_ZN16AAAAAImageParserD2Ev\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1] - at llvm.dbg.subprogram50 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str49, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 24, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite48 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.derivedtype51 = internal constant %llvm.dbg.derivedtype.type { i32 458790, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype46 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] - at llvm.dbg.variable52 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram50 to { }*), i8* getelementptr ([5 x i8]* @.str23, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 24, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype51 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at .str53 = internal constant [26 x i8] c"_ZN16AAAAAImageParserD1Ev\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1] - at llvm.dbg.subprogram54 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str38, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str53, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 24, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite48 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at llvm.dbg.variable55 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram54 to { }*), i8* getelementptr ([5 x i8]* @.str23, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*), i32 24, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype51 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at llvm.dbg.array56 = internal constant [1 x { }*] [{ }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*)], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] - at llvm.dbg.composite57 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array56 to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] - at .str58 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] - at llvm.dbg.subprogram59 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str58, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str58, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str58, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite57 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] - at .str60 = internal constant [2 x i8] c"C\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] - at llvm.dbg.variable61 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram59 to { }*), i8* getelementptr ([2 x i8]* @.str60, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype46 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] - at _ZZ4mainE3C.0 = private constant %struct.AAAAAImageParser zeroinitializer ; <%struct.AAAAAImageParser*> [#uses=2] - at llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] - at .str62 = internal constant [14 x i8] c"_ZZ4mainE3C.0\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1] - at .str63 = internal constant [4 x i8] c"C.0\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([14 x i8]* @.str62, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str63, i32 0, i32 0), i8* getelementptr ([14 x i8]* @.str62, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite45 to { }*), i1 false, i1 true, { }* bitcast (%struct.AAAAAImageParser* @_ZZ4mainE3C.0 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0] - -define void @_ZN16AAAAAImageParserD2Ev(%struct.AAAAAImageParser* %this) nounwind ssp { -entry: - %object_addr.i = alloca %struct.CObject* ; <%struct.CObject**> [#uses=4] - %retval.i = alloca %struct.CObject* ; <%struct.CObject**> [#uses=2] - %0 = alloca %struct.CObject* ; <%struct.CObject**> [#uses=2] - %this_addr = alloca %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser**> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram50 to { }*)) - %1 = bitcast %struct.AAAAAImageParser** %this_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable52 to { }*)) - store %struct.AAAAAImageParser* %this, %struct.AAAAAImageParser** %this_addr - call void @llvm.dbg.stoppoint(i32 26, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - %2 = load %struct.AAAAAImageParser** %this_addr, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - %3 = getelementptr %struct.AAAAAImageParser* %2, i32 0, i32 0 ; <%struct.CObject**> [#uses=1] - %4 = load %struct.CObject** %3, align 4 ; <%struct.CObject*> [#uses=1] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram28 to { }*)) nounwind - %5 = bitcast %struct.CObject** %object_addr.i to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %5, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable30 to { }*)) nounwind - store %struct.CObject* %4, %struct.CObject** %object_addr.i - call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - %6 = load %struct.CObject** %object_addr.i, align 4 ; <%struct.CObject*> [#uses=1] - %7 = icmp ne %struct.CObject* %6, null ; [#uses=1] - br i1 %7, label %bb.i, label %_Z13ReleaseObjectP7CObject.exit - -bb.i: ; preds = %entry - call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - %8 = load %struct.CObject** %object_addr.i, align 4 ; <%struct.CObject*> [#uses=1] - call void @_ZN7CObject7releaseEv(%struct.CObject* %8) nounwind - br label %_Z13ReleaseObjectP7CObject.exit - -_Z13ReleaseObjectP7CObject.exit: ; preds = %bb.i, %entry - call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - store %struct.CObject* null, %struct.CObject** %0, align 4 - %9 = load %struct.CObject** %0, align 4 ; <%struct.CObject*> [#uses=1] - store %struct.CObject* %9, %struct.CObject** %retval.i, align 4 - %retval2.i = load %struct.CObject** %retval.i ; <%struct.CObject*> [#uses=0] - call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram28 to { }*)) - br label %bb - -bb: ; preds = %_Z13ReleaseObjectP7CObject.exit - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - br label %return - -return: ; preds = %bb - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram50 to { }*)) - ret void -} - -define linkonce_odr void @_ZN7CObject7releaseEv(%struct.CObject* %this) nounwind ssp { -entry: - %this_addr = alloca %struct.CObject* ; <%struct.CObject**> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram21 to { }*)) - %0 = bitcast %struct.CObject** %this_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) - store %struct.CObject* %this, %struct.CObject** %this_addr - call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - %1 = load %struct.CObject** %this_addr, align 4 ; <%struct.CObject*> [#uses=1] - %2 = getelementptr %struct.CObject* %1, i32 0, i32 0 ; [#uses=1] - store i32 0, i32* %2, align 4 - br label %return - -return: ; preds = %entry - call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram21 to { }*)) - ret void -} - -declare void @llvm.dbg.func.start({ }*) nounwind readnone - -declare void @llvm.dbg.declare({ }*, { }*) nounwind readnone - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind readnone - -declare void @llvm.dbg.region.end({ }*) nounwind readnone - -define void @_ZN16AAAAAImageParserD1Ev(%struct.AAAAAImageParser* %this) nounwind ssp { -entry: - %object_addr.i = alloca %struct.CObject* ; <%struct.CObject**> [#uses=4] - %retval.i = alloca %struct.CObject* ; <%struct.CObject**> [#uses=2] - %0 = alloca %struct.CObject* ; <%struct.CObject**> [#uses=2] - %this_addr = alloca %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser**> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram54 to { }*)) - %1 = bitcast %struct.AAAAAImageParser** %this_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable55 to { }*)) - store %struct.AAAAAImageParser* %this, %struct.AAAAAImageParser** %this_addr - call void @llvm.dbg.stoppoint(i32 26, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - %2 = load %struct.AAAAAImageParser** %this_addr, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - %3 = getelementptr %struct.AAAAAImageParser* %2, i32 0, i32 0 ; <%struct.CObject**> [#uses=1] - %4 = load %struct.CObject** %3, align 4 ; <%struct.CObject*> [#uses=1] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram28 to { }*)) nounwind - %5 = bitcast %struct.CObject** %object_addr.i to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %5, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable30 to { }*)) nounwind - store %struct.CObject* %4, %struct.CObject** %object_addr.i - call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - %6 = load %struct.CObject** %object_addr.i, align 4 ; <%struct.CObject*> [#uses=1] - %7 = icmp ne %struct.CObject* %6, null ; [#uses=1] - br i1 %7, label %bb.i, label %_Z13ReleaseObjectP7CObject.exit - -bb.i: ; preds = %entry - call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - %8 = load %struct.CObject** %object_addr.i, align 4 ; <%struct.CObject*> [#uses=1] - call void @_ZN7CObject7releaseEv(%struct.CObject* %8) nounwind - br label %_Z13ReleaseObjectP7CObject.exit - -_Z13ReleaseObjectP7CObject.exit: ; preds = %bb.i, %entry - call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - store %struct.CObject* null, %struct.CObject** %0, align 4 - %9 = load %struct.CObject** %0, align 4 ; <%struct.CObject*> [#uses=1] - store %struct.CObject* %9, %struct.CObject** %retval.i, align 4 - %retval2.i = load %struct.CObject** %retval.i ; <%struct.CObject*> [#uses=0] - call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) nounwind - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram28 to { }*)) - br label %bb - -bb: ; preds = %_Z13ReleaseObjectP7CObject.exit - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - br label %return - -return: ; preds = %bb - call void @llvm.dbg.stoppoint(i32 27, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit4 to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram54 to { }*)) - ret void -} - -define i32 @main() ssp { -entry: - %retval = alloca i32 ; [#uses=2] - %C = alloca %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser**> [#uses=3] - %0 = alloca i32 ; [#uses=2] - %C.1 = alloca %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser**> [#uses=4] - %1 = alloca %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser**> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram59 to { }*)) - %2 = bitcast %struct.AAAAAImageParser** %C to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %2, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable61 to { }*)) - call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %3 = call i8* @_Znwm(i32 4) ; [#uses=1] - %4 = bitcast i8* %3 to %struct.AAAAAImageParser* ; <%struct.AAAAAImageParser*> [#uses=1] - store %struct.AAAAAImageParser* %4, %struct.AAAAAImageParser** %1, align 4 - %5 = load %struct.AAAAAImageParser** %1, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - %6 = getelementptr %struct.AAAAAImageParser* %5, i32 0, i32 0 ; <%struct.CObject**> [#uses=1] - %7 = load %struct.CObject** getelementptr (%struct.AAAAAImageParser* @_ZZ4mainE3C.0, i32 0, i32 0), align 4 ; <%struct.CObject*> [#uses=1] - store %struct.CObject* %7, %struct.CObject** %6, align 4 - %8 = load %struct.AAAAAImageParser** %1, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - store %struct.AAAAAImageParser* %8, %struct.AAAAAImageParser** %C, align 4 - call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %9 = load %struct.AAAAAImageParser** %C, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - store %struct.AAAAAImageParser* %9, %struct.AAAAAImageParser** %C.1, align 4 - %10 = load %struct.AAAAAImageParser** %C.1, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - %11 = icmp ne %struct.AAAAAImageParser* %10, null ; [#uses=1] - br i1 %11, label %bb, label %bb1 - ; No predecessors! - call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - br label %bb - -bb: ; preds = %12, %entry - call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %13 = load %struct.AAAAAImageParser** %C.1, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - call void @_ZN16AAAAAImageParserD1Ev(%struct.AAAAAImageParser* %13) nounwind - %14 = load %struct.AAAAAImageParser** %C.1, align 4 ; <%struct.AAAAAImageParser*> [#uses=1] - %15 = bitcast %struct.AAAAAImageParser* %14 to i8* ; [#uses=1] - call void @_ZdlPv(i8* %15) nounwind - br label %bb1 - -bb1: ; preds = %bb, %entry - call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 0, i32* %0, align 4 - %16 = load i32* %0, align 4 ; [#uses=1] - store i32 %16, i32* %retval, align 4 - br label %return - -return: ; preds = %bb1 - %retval2 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram59 to { }*)) - ret i32 %retval2 -} - -declare i8* @_Znwm(i32) - -declare void @_ZdlPv(i8*) nounwind From evan.cheng at apple.com Tue Dec 8 19:53:58 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 01:53:58 -0000 Subject: [llvm-commits] [llvm] r90925 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/CellSPU/call_indirect.ll Message-ID: <200912090153.nB91rxcD001247@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 8 19:53:58 2009 New Revision: 90925 URL: http://llvm.org/viewvc/llvm-project?rev=90925&view=rev Log: Teach InferPtrAlignment to infer GV+cst alignment and use it to simplify x86 isl lowering code. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=90925&r1=90924&r2=90925&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Dec 8 19:53:58 2009 @@ -5914,6 +5914,12 @@ /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { + // If this is a GlobalAddress + cst, return the alignment. + GlobalValue *GV; + int64_t GVOffset = 0; + if (TLI.isGAPlusOffset(Ptr.getNode(), GV, GVOffset)) + return MinAlign(GV->getAlignment(), GVOffset); + // If this is a direct reference to a stack slot, use information about the // stack slot's alignment. int FrameIdx = 1 << 31; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=90925&r1=90924&r2=90925&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 8 19:53:58 2009 @@ -8327,16 +8327,6 @@ return TargetLowering::isGAPlusOffset(N, GA, Offset); } -static bool isBaseAlignmentOfN(unsigned N, SDNode *Base, - const TargetLowering &TLI) { - GlobalValue *GV; - int64_t Offset = 0; - if (TLI.isGAPlusOffset(Base, GV, Offset)) - return (GV->getAlignment() >= N && (Offset % N) == 0); - // DAG combine handles the stack object case. - return false; -} - static bool EltsFromConsecutiveLoads(ShuffleVectorSDNode *N, unsigned NumElems, EVT EltVT, LoadSDNode *&LDBase, unsigned &LastLoadedElt, @@ -8399,7 +8389,7 @@ return SDValue(); if (LastLoadedElt == NumElems - 1) { - if (isBaseAlignmentOfN(16, LD->getBasePtr().getNode(), TLI)) + if (DAG.InferPtrAlignment(LD->getBasePtr()) >= 16) return DAG.getLoad(VT, dl, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(), LD->getSrcValueOffset(), LD->isVolatile()); Modified: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll?rev=90925&r1=90924&r2=90925&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Tue Dec 8 19:53:58 2009 @@ -2,17 +2,17 @@ ; RUN: llc < %s -march=cellspu -mattr=large_mem > %t2.s ; RUN: grep bisl %t1.s | count 7 ; RUN: grep ila %t1.s | count 1 -; RUN: grep rotqby %t1.s | count 6 +; RUN: grep rotqby %t1.s | count 5 ; RUN: grep lqa %t1.s | count 1 ; RUN: grep lqd %t1.s | count 12 ; RUN: grep dispatch_tab %t1.s | count 5 ; RUN: grep bisl %t2.s | count 7 ; RUN: grep ilhu %t2.s | count 2 ; RUN: grep iohl %t2.s | count 2 -; RUN: grep rotqby %t2.s | count 6 +; RUN: grep rotqby %t2.s | count 5 ; RUN: grep lqd %t2.s | count 13 ; RUN: grep ilhu %t2.s | count 2 -; RUN: grep ai %t2.s | count 9 +; RUN: grep ai %t2.s | count 8 ; RUN: grep dispatch_tab %t2.s | count 6 ; ModuleID = 'call_indirect.bc' From sabre at nondot.org Tue Dec 8 19:59:31 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 01:59:31 -0000 Subject: [llvm-commits] [llvm] r90926 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/rle.ll Message-ID: <200912090159.nB91xW9g001424@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 19:59:31 2009 New Revision: 90926 URL: http://llvm.org/viewvc/llvm-project?rev=90926&view=rev Log: Switch GVN and memdep to use PHITransAddr, which correctly handles phi translation of complex expressions like &A[i+1]. This has the following benefits: 1. The phi translation logic is all contained in its own class with a strong interface and verification that it is self consistent. 2. The logic is more correct than before. Previously, if intermediate expressions got PHI translated, we'd miss the update and scan for the wrong pointers in predecessor blocks. @phi_trans2 is a testcase for this. 3. We have a lot less code in memdep. We can handle phi translation across blocks of things like @phi_trans3, which is pretty insane :). This patch should fix the miscompiles of 255.vortex, and I tested it with a bootstrap of llvm-gcc, llvm-test and dejagnu of course. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/test/Transforms/GVN/rle.ll Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=90926&r1=90925&r2=90926&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Tue Dec 8 19:59:31 2009 @@ -31,6 +31,7 @@ class MemoryDependenceAnalysis; class PredIteratorCache; class DominatorTree; + class PHITransAddr; /// MemDepResult - A memory dependence query can return one of three different /// answers, described below. @@ -245,29 +246,6 @@ BasicBlock *BB, SmallVectorImpl &Result); - /// GetPHITranslatedValue - Find an available version of the specified value - /// PHI translated across the specified edge. If MemDep isn't able to - /// satisfy this request, it returns null. - Value *GetPHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD) const; - - /// GetAvailablePHITranslatedValue - Return the value computed by - /// PHITranslatePointer if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const; - - /// InsertPHITranslatedPointer - Insert a computation of the PHI translated - /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB - /// block. All newly created instructions are added to the NewInsts list. - Value *InsertPHITranslatedPointer(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const; - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); @@ -288,7 +266,7 @@ MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB); - bool getNonLocalPointerDepFromBB(Value *Pointer, uint64_t Size, + bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size, bool isLoad, BasicBlock *BB, SmallVectorImpl &Result, DenseMap &Visited, Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=90926&r1=90925&r2=90926&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Tue Dec 8 19:59:31 2009 @@ -23,6 +23,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/PHITransAddr.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/PredIteratorCache.h" @@ -587,12 +588,14 @@ const Type *EltTy = cast(Pointer->getType())->getElementType(); uint64_t PointeeSize = AA->getTypeStoreSize(EltTy); + PHITransAddr Address(Pointer, TD); + // This is the set of blocks we've inspected, and the pointer we consider in // each block. Because of critical edges, we currently bail out if querying // a block with multiple different pointers. This can happen during PHI // translation. DenseMap Visited; - if (!getNonLocalPointerDepFromBB(Pointer, PointeeSize, isLoad, FromBB, + if (!getNonLocalPointerDepFromBB(Address, PointeeSize, isLoad, FromBB, Result, Visited, true)) return; Result.clear(); @@ -707,275 +710,6 @@ } } -/// isPHITranslatable - Return true if the specified computation is derived from -/// a PHI node in the current block and if it is simple enough for us to handle. -static bool isPHITranslatable(Instruction *Inst) { - if (isa(Inst)) - return true; - - // We can handle bitcast of a PHI, but the PHI needs to be in the same block - // as the bitcast. - if (BitCastInst *BC = dyn_cast(Inst)) { - Instruction *OpI = dyn_cast(BC->getOperand(0)); - if (OpI == 0 || OpI->getParent() != Inst->getParent()) - return true; - return isPHITranslatable(OpI); - } - - // We can translate a GEP if all of its operands defined in this block are phi - // translatable. - if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { - Instruction *OpI = dyn_cast(GEP->getOperand(i)); - if (OpI == 0 || OpI->getParent() != Inst->getParent()) - continue; - - if (!isPHITranslatable(OpI)) - return false; - } - return true; - } - - if (Inst->getOpcode() == Instruction::Add && - isa(Inst->getOperand(1))) { - Instruction *OpI = dyn_cast(Inst->getOperand(0)); - if (OpI == 0 || OpI->getParent() != Inst->getParent()) - return true; - return isPHITranslatable(OpI); - } - - // cerr << "MEMDEP: Could not PHI translate: " << *Pointer; - // if (isa(PtrInst) || isa(PtrInst)) - // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); - - return false; -} - -/// GetPHITranslatedValue - Given a computation that satisfied the -/// isPHITranslatable predicate, see if we can translate the computation into -/// the specified predecessor block. If so, return that value. -Value *MemoryDependenceAnalysis:: -GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred, - const TargetData *TD) const { - // If the input value is not an instruction, or if it is not defined in CurBB, - // then we don't need to phi translate it. - Instruction *Inst = dyn_cast(InVal); - if (Inst == 0 || Inst->getParent() != CurBB) - return InVal; - - if (PHINode *PN = dyn_cast(Inst)) - return PN->getIncomingValueForBlock(Pred); - - // Handle bitcast of PHI. - if (BitCastInst *BC = dyn_cast(Inst)) { - // PHI translate the input operand. - Value *PHIIn = GetPHITranslatedValue(BC->getOperand(0), CurBB, Pred, TD); - if (PHIIn == 0) return 0; - - // Constants are trivial to phi translate. - if (Constant *C = dyn_cast(PHIIn)) - return ConstantExpr::getBitCast(C, BC->getType()); - - // Otherwise we have to see if a bitcasted version of the incoming pointer - // is available. If so, we can use it, otherwise we have to fail. - for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end(); - UI != E; ++UI) { - if (BitCastInst *BCI = dyn_cast(*UI)) - if (BCI->getType() == BC->getType()) - return BCI; - } - return 0; - } - - // Handle getelementptr with at least one PHI translatable operand. - if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - SmallVector GEPOps; - BasicBlock *CurBB = GEP->getParent(); - for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { - Value *GEPOp = GEP->getOperand(i); - // No PHI translation is needed of operands whose values are live in to - // the predecessor block. - if (!isa(GEPOp) || - cast(GEPOp)->getParent() != CurBB) { - GEPOps.push_back(GEPOp); - continue; - } - - // If the operand is a phi node, do phi translation. - Value *InOp = GetPHITranslatedValue(GEPOp, CurBB, Pred, TD); - if (InOp == 0) return 0; - - GEPOps.push_back(InOp); - } - - // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) - return V; - - // Scan to see if we have this GEP available. - Value *APHIOp = GEPOps[0]; - for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end(); - UI != E; ++UI) { - if (GetElementPtrInst *GEPI = dyn_cast(*UI)) - if (GEPI->getType() == GEP->getType() && - GEPI->getNumOperands() == GEPOps.size() && - GEPI->getParent()->getParent() == CurBB->getParent()) { - bool Mismatch = false; - for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) - if (GEPI->getOperand(i) != GEPOps[i]) { - Mismatch = true; - break; - } - if (!Mismatch) - return GEPI; - } - } - return 0; - } - - // Handle add with a constant RHS. - if (Inst->getOpcode() == Instruction::Add && - isa(Inst->getOperand(1))) { - // PHI translate the LHS. - Value *LHS; - Constant *RHS = cast(Inst->getOperand(1)); - Instruction *OpI = dyn_cast(Inst->getOperand(0)); - bool isNSW = cast(Inst)->hasNoSignedWrap(); - bool isNUW = cast(Inst)->hasNoUnsignedWrap(); - - if (OpI == 0 || OpI->getParent() != Inst->getParent()) - LHS = Inst->getOperand(0); - else { - LHS = GetPHITranslatedValue(Inst->getOperand(0), CurBB, Pred, TD); - if (LHS == 0) - return 0; - } - - // If the PHI translated LHS is an add of a constant, fold the immediates. - if (BinaryOperator *BOp = dyn_cast(LHS)) - if (BOp->getOpcode() == Instruction::Add) - if (ConstantInt *CI = dyn_cast(BOp->getOperand(1))) { - LHS = BOp->getOperand(0); - RHS = ConstantExpr::getAdd(RHS, CI); - isNSW = isNUW = false; - } - - // See if the add simplifies away. - if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) - return Res; - - // Otherwise, see if we have this add available somewhere. - for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); - UI != E; ++UI) { - if (BinaryOperator *BO = dyn_cast(*UI)) - if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && - BO->getParent()->getParent() == CurBB->getParent()) - return BO; - } - - return 0; - } - - return 0; -} - -/// GetAvailablePHITranslatePointer - Return the value computed by -/// PHITranslatePointer if it dominates PredBB, otherwise return null. -Value *MemoryDependenceAnalysis:: -GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const { - // See if PHI translation succeeds. - V = GetPHITranslatedValue(V, CurBB, PredBB, TD); - if (V == 0) return 0; - - // Make sure the value is live in the predecessor. - if (Instruction *Inst = dyn_cast_or_null(V)) - if (!DT.dominates(Inst->getParent(), PredBB)) - return 0; - return V; -} - - -/// InsertPHITranslatedPointer - Insert a computation of the PHI translated -/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB -/// block. All newly created instructions are added to the NewInsts list. -/// -Value *MemoryDependenceAnalysis:: -InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB, - BasicBlock *PredBB, const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const { - // See if we have a version of this value already available and dominating - // PredBB. If so, there is no need to insert a new copy. - if (Value *Res = GetAvailablePHITranslatedValue(InVal, CurBB, PredBB, TD, DT)) - return Res; - - // If we don't have an available version of this value, it must be an - // instruction. - Instruction *Inst = cast(InVal); - - // Handle bitcast of PHI translatable value. - if (BitCastInst *BC = dyn_cast(Inst)) { - Value *OpVal = InsertPHITranslatedPointer(BC->getOperand(0), - CurBB, PredBB, TD, DT, NewInsts); - if (OpVal == 0) return 0; - - // Otherwise insert a bitcast at the end of PredBB. - BitCastInst *New = new BitCastInst(OpVal, InVal->getType(), - InVal->getName()+".phi.trans.insert", - PredBB->getTerminator()); - NewInsts.push_back(New); - return New; - } - - // Handle getelementptr with at least one PHI operand. - if (GetElementPtrInst *GEP = dyn_cast(Inst)) { - SmallVector GEPOps; - BasicBlock *CurBB = GEP->getParent(); - for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { - Value *OpVal = InsertPHITranslatedPointer(GEP->getOperand(i), - CurBB, PredBB, TD, DT, NewInsts); - if (OpVal == 0) return 0; - GEPOps.push_back(OpVal); - } - - GetElementPtrInst *Result = - GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(), - InVal->getName()+".phi.trans.insert", - PredBB->getTerminator()); - Result->setIsInBounds(GEP->isInBounds()); - NewInsts.push_back(Result); - return Result; - } - -#if 0 - // FIXME: This code works, but it is unclear that we actually want to insert - // a big chain of computation in order to make a value available in a block. - // This needs to be evaluated carefully to consider its cost trade offs. - - // Handle add with a constant RHS. - if (Inst->getOpcode() == Instruction::Add && - isa(Inst->getOperand(1))) { - // PHI translate the LHS. - Value *OpVal = InsertPHITranslatedPointer(Inst->getOperand(0), - CurBB, PredBB, TD, DT, NewInsts); - if (OpVal == 0) return 0; - - BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), - InVal->getName()+".phi.trans.insert", - PredBB->getTerminator()); - Res->setHasNoSignedWrap(cast(Inst)->hasNoSignedWrap()); - Res->setHasNoUnsignedWrap(cast(Inst)->hasNoUnsignedWrap()); - NewInsts.push_back(Res); - return Res; - } -#endif - - return 0; -} - /// getNonLocalPointerDepFromBB - Perform a dependency query based on /// pointer/pointeesize starting at the end of StartBB. Add any clobber/def /// results to the results vector and keep track of which blocks are visited in @@ -989,14 +723,14 @@ /// not compute dependence information for some reason. This should be treated /// as a clobber dependence on the first instruction in the predecessor block. bool MemoryDependenceAnalysis:: -getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, +getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize, bool isLoad, BasicBlock *StartBB, SmallVectorImpl &Result, DenseMap &Visited, bool SkipFirstBlock) { // Look up the cached info for Pointer. - ValueIsLoadPair CacheKey(Pointer, isLoad); + ValueIsLoadPair CacheKey(Pointer.getAddr(), isLoad); std::pair *CacheInfo = &NonLocalPointerDeps[CacheKey]; @@ -1014,7 +748,8 @@ for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end(); I != E; ++I) { DenseMap::iterator VI = Visited.find(I->first); - if (VI == Visited.end() || VI->second == Pointer) continue; + if (VI == Visited.end() || VI->second == Pointer.getAddr()) + continue; // We have a pointer mismatch in a block. Just return clobber, saying // that something was clobbered in this result. We could also do a @@ -1025,7 +760,7 @@ for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end(); I != E; ++I) { - Visited.insert(std::make_pair(I->first, Pointer)); + Visited.insert(std::make_pair(I->first, Pointer.getAddr())); if (!I->second.isNonLocal()) Result.push_back(*I); } @@ -1065,8 +800,9 @@ // Get the dependency info for Pointer in BB. If we have cached // information, we will use it, otherwise we compute it. DEBUG(AssertSorted(*Cache, NumSortedEntries)); - MemDepResult Dep = GetNonLocalInfoForBlock(Pointer, PointeeSize, isLoad, - BB, Cache, NumSortedEntries); + MemDepResult Dep = GetNonLocalInfoForBlock(Pointer.getAddr(), PointeeSize, + isLoad, BB, Cache, + NumSortedEntries); // If we got a Def or Clobber, add this to the list of results. if (!Dep.isNonLocal()) { @@ -1077,18 +813,14 @@ // If 'Pointer' is an instruction defined in this block, then we need to do // phi translation to change it into a value live in the predecessor block. - // If phi translation fails, then we can't continue dependence analysis. - Instruction *PtrInst = dyn_cast(Pointer); - bool NeedsPHITranslation = PtrInst && PtrInst->getParent() == BB; - - // If no PHI translation is needed, just add all the predecessors of this - // block to scan them as well. - if (!NeedsPHITranslation) { + // If not, we just add the predecessors to the worklist and scan them with + // the same Pointer. + if (!Pointer.NeedsPHITranslationFromBlock(BB)) { SkipFirstBlock = false; for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) { // Verify that we haven't looked at this block yet. std::pair::iterator, bool> - InsertRes = Visited.insert(std::make_pair(*PI, Pointer)); + InsertRes = Visited.insert(std::make_pair(*PI, Pointer.getAddr())); if (InsertRes.second) { // First time we've looked at *PI. Worklist.push_back(*PI); @@ -1098,16 +830,17 @@ // If we have seen this block before, but it was with a different // pointer then we have a phi translation failure and we have to treat // this as a clobber. - if (InsertRes.first->second != Pointer) + if (InsertRes.first->second != Pointer.getAddr()) goto PredTranslationFailure; } continue; } - // If we do need to do phi translation, then there are a bunch of different - // cases, because we have to find a Value* live in the predecessor block. We - // know that PtrInst is defined in this block at least. - + // We do need to do phi translation, if we know ahead of time we can't phi + // translate this value, don't even try. + if (!Pointer.IsPotentiallyPHITranslatable()) + goto PredTranslationFailure; + // We may have added values to the cache list before this PHI translation. // If so, we haven't done anything to ensure that the cache remains sorted. // Sort it now (if needed) so that recursive invocations of @@ -1117,19 +850,17 @@ SortNonLocalDepInfoCache(*Cache, NumSortedEntries); NumSortedEntries = Cache->size(); } - - // If this is a computation derived from a PHI node, use the suitably - // translated incoming values for each pred as the phi translated version. - if (!isPHITranslatable(PtrInst)) - goto PredTranslationFailure; - Cache = 0; - + for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) { BasicBlock *Pred = *PI; - // Get the PHI translated pointer in this predecessor. This can fail and - // return null if not translatable. - Value *PredPtr = GetPHITranslatedValue(PtrInst, BB, Pred, TD); + + // Get the PHI translated pointer in this predecessor. This can fail if + // not translatable, in which case the getAddr() returns null. + PHITransAddr PredPointer(Pointer); + PredPointer.PHITranslateValue(BB, Pred); + + Value *PredPtrVal = PredPointer.getAddr(); // Check to see if we have already visited this pred block with another // pointer. If so, we can't do this lookup. This failure can occur @@ -1137,12 +868,12 @@ // the successor translates to a pointer value different than the // pointer the block was first analyzed with. std::pair::iterator, bool> - InsertRes = Visited.insert(std::make_pair(Pred, PredPtr)); + InsertRes = Visited.insert(std::make_pair(Pred, PredPtrVal)); if (!InsertRes.second) { // If the predecessor was visited with PredPtr, then we already did // the analysis and can ignore it. - if (InsertRes.first->second == PredPtr) + if (InsertRes.first->second == PredPtrVal) continue; // Otherwise, the block was previously analyzed with a different @@ -1155,7 +886,7 @@ // predecessor, then we have to assume that the pointer is clobbered in // that predecessor. We can still do PRE of the load, which would insert // a computation of the pointer in this predecessor. - if (PredPtr == 0) { + if (PredPtrVal == 0) { // Add the entry to the Result list. NonLocalDepEntry Entry(Pred, MemDepResult::getClobber(Pred->getTerminator())); @@ -1201,7 +932,7 @@ // If we have a problem phi translating, fall through to the code below // to handle the failure condition. - if (getNonLocalPointerDepFromBB(PredPtr, PointeeSize, isLoad, Pred, + if (getNonLocalPointerDepFromBB(PredPointer, PointeeSize, isLoad, Pred, Result, Visited)) goto PredTranslationFailure; } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90926&r1=90925&r2=90926&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 8 19:59:31 2009 @@ -36,6 +36,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/PHITransAddr.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -1597,39 +1598,43 @@ // Do PHI translation to get its value in the predecessor if necessary. The // returned pointer (if non-null) is guaranteed to dominate UnavailablePred. // - // FIXME: This may insert a computation, but we don't tell scalar GVN - // optimization stuff about it. How do we do this? SmallVector NewInsts; - Value *LoadPtr = 0; // If all preds have a single successor, then we know it is safe to insert the // load on the pred (?!?), so we can insert code to materialize the pointer if // it is not available. + PHITransAddr Address(LI->getOperand(0), TD); + Value *LoadPtr = 0; if (allSingleSucc) { - LoadPtr = MD->InsertPHITranslatedPointer(LI->getOperand(0), LoadBB, - UnavailablePred, TD, *DT,NewInsts); + LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred, + *DT, NewInsts); } else { - LoadPtr = MD->GetAvailablePHITranslatedValue(LI->getOperand(0), LoadBB, - UnavailablePred, TD, *DT); + Address.PHITranslateValue(LoadBB, UnavailablePred); + LoadPtr = Address.getAddr(); + + // Make sure the value is live in the predecessor. + if (Instruction *Inst = dyn_cast_or_null(LoadPtr)) + if (!DT->dominates(Inst->getParent(), UnavailablePred)) + LoadPtr = 0; } - // Assign value numbers to these new instructions. - for (SmallVector::iterator NI = NewInsts.begin(), - NE = NewInsts.end(); NI != NE; ++NI) { - // FIXME: We really _ought_ to insert these value numbers into their - // parent's availability map. However, in doing so, we risk getting into - // ordering issues. If a block hasn't been processed yet, we would be - // marking a value as AVAIL-IN, which isn't what we intend. - VN.lookup_or_add(*NI); - } - // If we couldn't find or insert a computation of this phi translated value, // we fail PRE. if (LoadPtr == 0) { + assert(NewInsts.empty() && "Shouldn't insert insts on failure"); DEBUG(errs() << "COULDN'T INSERT PHI TRANSLATED VALUE OF: " << *LI->getOperand(0) << "\n"); return false; } + + // Assign value numbers to these new instructions. + for (unsigned i = 0, e = NewInsts.size(); i != e; ++i) { + // FIXME: We really _ought_ to insert these value numbers into their + // parent's availability map. However, in doing so, we risk getting into + // ordering issues. If a block hasn't been processed yet, we would be + // marking a value as AVAIL-IN, which isn't what we intend. + VN.lookup_or_add(NewInsts[i]); + } // Make sure it is valid to move this load here. We have to watch out for: // @1 = getelementptr (i8* p, ... Modified: llvm/trunk/test/Transforms/GVN/rle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/rle.ll?rev=90926&r1=90925&r2=90926&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/rle.ll (original) +++ llvm/trunk/test/Transforms/GVN/rle.ll Tue Dec 8 19:59:31 2009 @@ -388,6 +388,7 @@ declare i1 @cond2() readonly define i32 @phi_trans2() { +; CHECK: @phi_trans2 entry: %P = alloca i32, i32 400 br label %F1 @@ -411,9 +412,57 @@ br label %F1 TX: - ret i32 %x ;; SHOULD NOT BE COMPILED TO 'ret i32 42'. + ; This load should not be compiled to 'ret i32 42'. An overly clever + ; implementation of GVN would see that we're returning 17 if the loop + ; executes once or 42 if it executes more than that, but we'd have to do + ; loop restructuring to expose this, and GVN shouldn't do this sort of CFG + ; transformation. + +; CHECK: TX: +; CHECK: ret i32 %x + ret i32 %x TY: ret i32 0 } +define i32 @phi_trans3(i32* %p) { +; CHECK: @phi_trans3 +block1: + br i1 true, label %block2, label %block3 + +block2: + store i32 87, i32* %p + br label %block4 + +block3: + %p2 = getelementptr i32* %p, i32 43 + store i32 97, i32* %p2 + br label %block4 + +block4: + %A = phi i32 [-1, %block2], [42, %block3] + br i1 true, label %block5, label %exit + +; CHECK: block4: +; CHECK-NEXT: %D = phi i32 [ 87, %block2 ], [ 97, %block3 ] +; CHECK-NOT: load + +block5: + %B = add i32 %A, 1 + br i1 true, label %block6, label %exit + +block6: + %C = getelementptr i32* %p, i32 %B + br i1 true, label %block7, label %exit + +block7: + %D = load i32* %C + ret i32 %D + +; CHECK: block7: +; CHECK-NEXT: ret i32 %D + +exit: + ret i32 -1 +} From sabre at nondot.org Tue Dec 8 20:41:54 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 02:41:54 -0000 Subject: [llvm-commits] [llvm] r90929 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200912090241.nB92fsEj003181@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 20:41:54 2009 New Revision: 90929 URL: http://llvm.org/viewvc/llvm-project?rev=90929&view=rev Log: add some aborts to #if 0's. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90929&r1=90928&r2=90929&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 8 20:41:54 2009 @@ -1026,6 +1026,7 @@ << "Load Offs = " << LoadOffset << " - " << *L << "\n\n"; errs() << "'" << L->getParent()->getParent()->getName() << "'" << *L->getParent(); + abort(); #endif return -1; } @@ -1059,6 +1060,7 @@ << "Load Offs = " << LoadOffset << " - " << *L << "\n\n"; errs() << "'" << L->getParent()->getParent()->getName() << "'" << *L->getParent(); + abort(); #endif return -1; } From sabre at nondot.org Tue Dec 8 20:43:05 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 02:43:05 -0000 Subject: [llvm-commits] [llvm] r90930 - /llvm/trunk/test/Transforms/GVN/rle.ll Message-ID: <200912090243.nB92h6db003319@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 8 20:43:05 2009 New Revision: 90930 URL: http://llvm.org/viewvc/llvm-project?rev=90930&view=rev Log: the code in GVN that tries to forward large loads to small stores is not phi translating, thus it miscompiles really crazy testcases. This is from inspection, I haven't seen this in the wild. Modified: llvm/trunk/test/Transforms/GVN/rle.ll Modified: llvm/trunk/test/Transforms/GVN/rle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/rle.ll?rev=90930&r1=90929&r2=90930&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/rle.ll (original) +++ llvm/trunk/test/Transforms/GVN/rle.ll Tue Dec 8 20:43:05 2009 @@ -466,3 +466,57 @@ ret i32 -1 } +define i8 @phi_trans4(i8* %p) { +; CHECK: @phi_trans4 +entry: + %X = getelementptr i8* %p, i32 4 + %Y = load i8* %X + br label %loop + +loop: + %i = phi i32 [4, %entry], [192, %loop] + %X2 = getelementptr i8* %p, i32 %i + %Y2 = load i8* %X + + %cond = call i1 @cond2() + + %Z = bitcast i8 *%X2 to i32* + store i32 0, i32* %Z + br i1 %cond, label %loop, label %out + +out: + %R = add i8 %Y, %Y2 + ret i8 %R +} + +define i8 @phi_trans5(i8* %p) { +; CHECK: @phi_trans5 +entry: + %X4 = getelementptr i8* %p, i32 2 + store i8 19, i8* %X4 + + %X = getelementptr i8* %p, i32 4 + %Y = load i8* %X + br label %loop + +loop: + %i = phi i32 [4, %entry], [3, %cont] + %X2 = getelementptr i8* %p, i32 %i + %Y2 = load i8* %X2 + ;; FIXME: This load is being incorrectly replaced! + %cond = call i1 @cond2() + br i1 %cond, label %cont, label %out + +cont: + %Z = getelementptr i8* %X2, i32 -1 + %Z2 = bitcast i8 *%Z to i32* + store i32 50462976, i32* %Z2 ;; (1 << 8) | (2 << 16) | (3 << 24) + br label %loop + +out: + %R = add i8 %Y, %Y2 + ret i8 %R +} + + + From daniel at zuster.org Tue Dec 8 20:58:09 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 09 Dec 2009 02:58:09 -0000 Subject: [llvm-commits] [llvm] r90934 - in /llvm/trunk: include/llvm/ADT/DenseSet.h utils/TableGen/CodeEmitterGen.h utils/TableGen/CodeGenDAGPatterns.h utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200912090258.nB92w9EM004058@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Dec 8 20:58:09 2009 New Revision: 90934 URL: http://llvm.org/viewvc/llvm-project?rev=90934&view=rev Log: Remove unneeded ';' and a class/struct mismatch (noticed by clang). Modified: llvm/trunk/include/llvm/ADT/DenseSet.h llvm/trunk/utils/TableGen/CodeEmitterGen.h llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/ADT/DenseSet.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseSet.h?rev=90934&r1=90933&r2=90934&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseSet.h (original) +++ llvm/trunk/include/llvm/ADT/DenseSet.h Tue Dec 8 20:58:09 2009 @@ -73,7 +73,7 @@ const ValueT& operator*() { return I->first; } const ValueT* operator->() { return &I->first; } - ConstIterator& operator++() { ++I; return *this; }; + ConstIterator& operator++() { ++I; return *this; } bool operator==(const ConstIterator& X) const { return I == X.I; } bool operator!=(const ConstIterator& X) const { return I != X.I; } }; Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.h?rev=90934&r1=90933&r2=90934&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeEmitterGen.h (original) +++ llvm/trunk/utils/TableGen/CodeEmitterGen.h Tue Dec 8 20:58:09 2009 @@ -23,7 +23,7 @@ class RecordVal; class BitsInit; -class Init; +struct Init; class CodeEmitterGen : public TableGenBackend { RecordKeeper &Records; Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=90934&r1=90933&r2=90934&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Tue Dec 8 20:58:09 2009 @@ -445,7 +445,7 @@ const std::vector &dstregs, unsigned complexity): Predicates(preds), SrcPattern(src), DstPattern(dst), Dstregs(dstregs), - AddedComplexity(complexity) {}; + AddedComplexity(complexity) {} ListInit *Predicates; // Top level predicate conditions to match. TreePatternNode *SrcPattern; // Source pattern to match. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=90934&r1=90933&r2=90934&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue Dec 8 20:58:09 2009 @@ -162,7 +162,7 @@ public: RegisterSorter(std::map, LessRecord> &RS) - : RegisterSubRegs(RS) {}; + : RegisterSubRegs(RS) {} bool operator()(Record *RegA, Record *RegB) { // B is sub-register of A. From daniel at zuster.org Tue Dec 8 21:26:34 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 09 Dec 2009 03:26:34 -0000 Subject: [llvm-commits] [llvm] r90937 - /llvm/trunk/lib/System/Unix/Path.inc Message-ID: <200912090326.nB93QYvJ005051@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Dec 8 21:26:33 2009 New Revision: 90937 URL: http://llvm.org/viewvc/llvm-project?rev=90937&view=rev Log: Remove spurious extern. Modified: llvm/trunk/lib/System/Unix/Path.inc Modified: llvm/trunk/lib/System/Unix/Path.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Path.inc?rev=90937&r1=90936&r2=90937&view=diff ============================================================================== --- llvm/trunk/lib/System/Unix/Path.inc (original) +++ llvm/trunk/lib/System/Unix/Path.inc Tue Dec 8 21:26:33 2009 @@ -77,7 +77,7 @@ namespace llvm { using namespace sys; -extern const char sys::PathSeparator = ':'; +const char sys::PathSeparator = ':'; Path::Path(const std::string& p) : path(p) {} From lhames at gmail.com Tue Dec 8 23:39:14 2009 From: lhames at gmail.com (Lang Hames) Date: Wed, 09 Dec 2009 05:39:14 -0000 Subject: [llvm-commits] [llvm] r90951 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveInterval.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/Spiller.cpp lib/CodeGen/Spiller.h Message-ID: <200912090539.nB95dEid009257@zion.cs.uiuc.edu> Author: lhames Date: Tue Dec 8 23:39:12 2009 New Revision: 90951 URL: http://llvm.org/viewvc/llvm-project?rev=90951&view=rev Log: Added a new "splitting" spiller. When a call is placed to spill an interval this spiller will first try to break the interval up into its component values. Single value intervals and intervals which have already been split (or are the result of previous splits) are spilled by the default spiller. Splitting intervals as described above may improve the performance of generated code in some circumstances. This work is experimental however, and it still miscompiles many benchmarks. It's not recommended for general use yet. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveInterval.cpp llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp llvm/trunk/lib/CodeGen/Spiller.cpp llvm/trunk/lib/CodeGen/Spiller.h Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue Dec 8 23:39:12 2009 @@ -186,6 +186,10 @@ return indexes_->getMBBFromIndex(index); } + SlotIndex getMBBTerminatorGap(const MachineBasicBlock *mbb) { + return indexes_->getTerminatorGap(mbb); + } + SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) { return indexes_->insertMachineInstrInMaps(MI); } Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Tue Dec 8 23:39:12 2009 @@ -847,7 +847,7 @@ if (vni->isUnused()) { OS << "x"; } else { - if (!vni->isDefAccurate()) + if (!vni->isDefAccurate() && !vni->isPHIDef()) OS << "?"; else OS << vni->def; Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Dec 8 23:39:12 2009 @@ -401,7 +401,7 @@ interval.removeRange(Start, End); assert(interval.ranges.size() == 1 && "Newly discovered PHI interval has >1 ranges."); - MachineBasicBlock *killMBB = getMBBFromIndex(interval.endIndex()); + MachineBasicBlock *killMBB = getMBBFromIndex(VNI->def); VNI->addKill(indexes_->getTerminatorGap(killMBB)); VNI->setHasPHIKill(true); DEBUG({ @@ -412,7 +412,7 @@ // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) LiveRange LR(Start, End, - interval.getNextValue(SlotIndex(getMBBStartIdx(mbb), true), + interval.getNextValue(SlotIndex(getMBBStartIdx(Killer->getParent()), true), 0, false, VNInfoAllocator)); LR.valno->setIsPHIDef(true); DEBUG(errs() << " replace range with " << LR); Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Tue Dec 8 23:39:12 2009 @@ -1261,9 +1261,9 @@ // The earliest start of a Spilled interval indicates up to where // in handled we need to roll back + assert(!spillIs.empty() && "No spill intervals?"); + SlotIndex earliestStart = spillIs[0]->beginIndex(); - LiveInterval *earliestStartInterval = cur; - // Spill live intervals of virtual regs mapped to the physical register we // want to clear (and its aliases). We only spill those that overlap with the // current interval as the rest do not affect its allocation. we also keep @@ -1274,19 +1274,16 @@ LiveInterval *sli = spillIs.back(); spillIs.pop_back(); DEBUG(errs() << "\t\t\tspilling(a): " << *sli << '\n'); - earliestStartInterval = - (earliestStartInterval->beginIndex() < sli->beginIndex()) ? - earliestStartInterval : sli; + if (sli->beginIndex() < earliestStart) + earliestStart = sli->beginIndex(); std::vector newIs; - newIs = spiller_->spill(sli, spillIs); + newIs = spiller_->spill(sli, spillIs, &earliestStart); addStackInterval(sli, ls_, li_, mri_, *vrm_); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(sli->reg); } - SlotIndex earliestStart = earliestStartInterval->beginIndex(); - DEBUG(errs() << "\t\trolling back to: " << earliestStart << '\n'); // Scan handled in reverse order up to the earliest start of a @@ -1295,7 +1292,7 @@ while (!handled_.empty()) { LiveInterval* i = handled_.back(); // If this interval starts before t we are done. - if (i->beginIndex() < earliestStart) + if (!i->empty() && i->beginIndex() < earliestStart) break; DEBUG(errs() << "\t\t\tundo changes for: " << *i << '\n'); handled_.pop_back(); Modified: llvm/trunk/lib/CodeGen/Spiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.cpp?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Spiller.cpp (original) +++ llvm/trunk/lib/CodeGen/Spiller.cpp Tue Dec 8 23:39:12 2009 @@ -20,22 +20,25 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include using namespace llvm; namespace { - enum SpillerName { trivial, standard }; + enum SpillerName { trivial, standard, splitting }; } static cl::opt spillerOpt("spiller", cl::desc("Spiller to use: (default: standard)"), cl::Prefix, - cl::values(clEnumVal(trivial, "trivial spiller"), - clEnumVal(standard, "default spiller"), + cl::values(clEnumVal(trivial, "trivial spiller"), + clEnumVal(standard, "default spiller"), + clEnumVal(splitting, "splitting spiller"), clEnumValEnd), cl::init(standard)); +// Spiller virtual destructor implementation. Spiller::~Spiller() {} namespace { @@ -170,7 +173,8 @@ : SpillerBase(mf, lis, vrm) {} std::vector spill(LiveInterval *li, - SmallVectorImpl &spillIs) { + SmallVectorImpl &spillIs, + SlotIndex*) { // Ignore spillIs - we don't use it. return trivialSpillEverywhere(li); } @@ -179,23 +183,336 @@ /// Falls back on LiveIntervals::addIntervalsForSpills. class StandardSpiller : public Spiller { -private: +protected: LiveIntervals *lis; const MachineLoopInfo *loopInfo; VirtRegMap *vrm; public: - StandardSpiller(MachineFunction *mf, LiveIntervals *lis, - const MachineLoopInfo *loopInfo, VirtRegMap *vrm) + StandardSpiller(LiveIntervals *lis, const MachineLoopInfo *loopInfo, + VirtRegMap *vrm) : lis(lis), loopInfo(loopInfo), vrm(vrm) {} /// Falls back on LiveIntervals::addIntervalsForSpills. std::vector spill(LiveInterval *li, - SmallVectorImpl &spillIs) { + SmallVectorImpl &spillIs, + SlotIndex*) { return lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm); } }; +/// When a call to spill is placed this spiller will first try to break the +/// interval up into its component values (one new interval per value). +/// If this fails, or if a call is placed to spill a previously split interval +/// then the spiller falls back on the standard spilling mechanism. +class SplittingSpiller : public StandardSpiller { +public: + SplittingSpiller(MachineFunction *mf, LiveIntervals *lis, + const MachineLoopInfo *loopInfo, VirtRegMap *vrm) + : StandardSpiller(lis, loopInfo, vrm) { + + mri = &mf->getRegInfo(); + tii = mf->getTarget().getInstrInfo(); + tri = mf->getTarget().getRegisterInfo(); + } + + std::vector spill(LiveInterval *li, + SmallVectorImpl &spillIs, + SlotIndex *earliestStart) { + + if (worthTryingToSplit(li)) { + return tryVNISplit(li, earliestStart); + } + // else + return StandardSpiller::spill(li, spillIs, earliestStart); + } + +private: + + MachineRegisterInfo *mri; + const TargetInstrInfo *tii; + const TargetRegisterInfo *tri; + DenseSet alreadySplit; + + bool worthTryingToSplit(LiveInterval *li) const { + return (!alreadySplit.count(li) && li->getNumValNums() > 1); + } + + /// Try to break a LiveInterval into its component values. + std::vector tryVNISplit(LiveInterval *li, + SlotIndex *earliestStart) { + + DEBUG(errs() << "Trying VNI split of %reg" << *li << "\n"); + + std::vector added; + SmallVector vnis; + + std::copy(li->vni_begin(), li->vni_end(), std::back_inserter(vnis)); + + for (SmallVectorImpl::iterator vniItr = vnis.begin(), + vniEnd = vnis.end(); vniItr != vniEnd; ++vniItr) { + VNInfo *vni = *vniItr; + + // Skip unused VNIs, or VNIs with no kills. + if (vni->isUnused() || vni->kills.empty()) + continue; + + DEBUG(errs() << " Extracted Val #" << vni->id << " as "); + LiveInterval *splitInterval = extractVNI(li, vni); + + if (splitInterval != 0) { + DEBUG(errs() << *splitInterval << "\n"); + added.push_back(splitInterval); + alreadySplit.insert(splitInterval); + if (earliestStart != 0) { + if (splitInterval->beginIndex() < *earliestStart) + *earliestStart = splitInterval->beginIndex(); + } + } else { + DEBUG(errs() << "0\n"); + } + } + + DEBUG(errs() << "Original LI: " << *li << "\n"); + + // If there original interval still contains some live ranges + // add it to added and alreadySplit. + if (!li->empty()) { + added.push_back(li); + alreadySplit.insert(li); + if (earliestStart != 0) { + if (li->beginIndex() < *earliestStart) + *earliestStart = li->beginIndex(); + } + } + + return added; + } + + /// Extract the given value number from the interval. + LiveInterval* extractVNI(LiveInterval *li, VNInfo *vni) const { + assert(vni->isDefAccurate() || vni->isPHIDef()); + assert(!vni->kills.empty()); + + // Create a new vreg and live interval, copy VNI kills & ranges over. + const TargetRegisterClass *trc = mri->getRegClass(li->reg); + unsigned newVReg = mri->createVirtualRegister(trc); + vrm->grow(); + LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); + VNInfo *newVNI = newLI->createValueCopy(vni, lis->getVNInfoAllocator()); + + // Start by copying all live ranges in the VN to the new interval. + for (LiveInterval::iterator rItr = li->begin(), rEnd = li->end(); + rItr != rEnd; ++rItr) { + if (rItr->valno == vni) { + newLI->addRange(LiveRange(rItr->start, rItr->end, newVNI)); + } + } + + // Erase the old VNI & ranges. + li->removeValNo(vni); + + // Collect all current uses of the register belonging to the given VNI. + // We'll use this to rename the register after we've dealt with the def. + std::set uses; + for (MachineRegisterInfo::use_iterator + useItr = mri->use_begin(li->reg), useEnd = mri->use_end(); + useItr != useEnd; ++useItr) { + uses.insert(&*useItr); + } + + // Process the def instruction for this VNI. + if (newVNI->isPHIDef()) { + // Insert a copy at the start of the MBB. The range proceeding the + // copy will be attached to the original LiveInterval. + MachineBasicBlock *defMBB = lis->getMBBFromIndex(newVNI->def); + tii->copyRegToReg(*defMBB, defMBB->begin(), newVReg, li->reg, trc, trc); + MachineInstr *copyMI = defMBB->begin(); + copyMI->addRegisterKilled(li->reg, tri); + SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); + VNInfo *phiDefVNI = li->getNextValue(lis->getMBBStartIdx(defMBB), + 0, false, lis->getVNInfoAllocator()); + phiDefVNI->setIsPHIDef(true); + phiDefVNI->addKill(copyIdx.getDefIndex()); + li->addRange(LiveRange(phiDefVNI->def, copyIdx.getDefIndex(), phiDefVNI)); + LiveRange *oldPHIDefRange = + newLI->getLiveRangeContaining(lis->getMBBStartIdx(defMBB)); + + // If the old phi def starts in the middle of the range chop it up. + if (oldPHIDefRange->start < lis->getMBBStartIdx(defMBB)) { + LiveRange oldPHIDefRange2(copyIdx.getDefIndex(), oldPHIDefRange->end, + oldPHIDefRange->valno); + oldPHIDefRange->end = lis->getMBBStartIdx(defMBB); + newLI->addRange(oldPHIDefRange2); + } else if (oldPHIDefRange->start == lis->getMBBStartIdx(defMBB)) { + // Otherwise if it's at the start of the range just trim it. + oldPHIDefRange->start = copyIdx.getDefIndex(); + } else { + assert(false && "PHI def range doesn't cover PHI def?"); + } + + newVNI->def = copyIdx.getDefIndex(); + newVNI->setCopy(copyMI); + newVNI->setIsPHIDef(false); // not a PHI def anymore. + newVNI->setIsDefAccurate(true); + } else { + // non-PHI def. Rename the def. If it's two-addr that means renaming the use + // and inserting a new copy too. + MachineInstr *defInst = lis->getInstructionFromIndex(newVNI->def); + // We'll rename this now, so we can remove it from uses. + uses.erase(defInst); + unsigned defOpIdx = defInst->findRegisterDefOperandIdx(li->reg); + bool isTwoAddr = defInst->isRegTiedToUseOperand(defOpIdx), + twoAddrUseIsUndef = false; + + for (unsigned i = 0; i < defInst->getNumOperands(); ++i) { + MachineOperand &mo = defInst->getOperand(i); + if (mo.isReg() && (mo.isDef() || isTwoAddr) && (mo.getReg()==li->reg)) { + mo.setReg(newVReg); + if (isTwoAddr && mo.isUse() && mo.isUndef()) + twoAddrUseIsUndef = true; + } + } + + SlotIndex defIdx = lis->getInstructionIndex(defInst); + newVNI->def = defIdx.getDefIndex(); + + if (isTwoAddr && !twoAddrUseIsUndef) { + MachineBasicBlock *defMBB = defInst->getParent(); + tii->copyRegToReg(*defMBB, defInst, newVReg, li->reg, trc, trc); + MachineInstr *copyMI = prior(MachineBasicBlock::iterator(defInst)); + SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); + copyMI->addRegisterKilled(li->reg, tri); + LiveRange *origUseRange = + li->getLiveRangeContaining(newVNI->def.getUseIndex()); + VNInfo *origUseVNI = origUseRange->valno; + origUseRange->end = copyIdx.getDefIndex(); + bool updatedKills = false; + for (unsigned k = 0; k < origUseVNI->kills.size(); ++k) { + if (origUseVNI->kills[k] == defIdx.getDefIndex()) { + origUseVNI->kills[k] = copyIdx.getDefIndex(); + updatedKills = true; + break; + } + } + assert(updatedKills && "Failed to update VNI kill list."); + VNInfo *copyVNI = newLI->getNextValue(copyIdx.getDefIndex(), copyMI, + true, lis->getVNInfoAllocator()); + copyVNI->addKill(defIdx.getDefIndex()); + LiveRange copyRange(copyIdx.getDefIndex(),defIdx.getDefIndex(),copyVNI); + newLI->addRange(copyRange); + } + } + + for (std::set::iterator + usesItr = uses.begin(), usesEnd = uses.end(); + usesItr != usesEnd; ++usesItr) { + MachineInstr *useInst = *usesItr; + SlotIndex useIdx = lis->getInstructionIndex(useInst); + LiveRange *useRange = + newLI->getLiveRangeContaining(useIdx.getUseIndex()); + + // If this use doesn't belong to the new interval skip it. + if (useRange == 0) + continue; + + // This use doesn't belong to the VNI, skip it. + if (useRange->valno != newVNI) + continue; + + // Check if this instr is two address. + unsigned useOpIdx = useInst->findRegisterUseOperandIdx(li->reg); + bool isTwoAddress = useInst->isRegTiedToDefOperand(useOpIdx); + + // Rename uses (and defs for two-address instrs). + for (unsigned i = 0; i < useInst->getNumOperands(); ++i) { + MachineOperand &mo = useInst->getOperand(i); + if (mo.isReg() && (mo.isUse() || isTwoAddress) && + (mo.getReg() == li->reg)) { + mo.setReg(newVReg); + } + } + + // If this is a two address instruction we've got some extra work to do. + if (isTwoAddress) { + // We modified the def operand, so we need to copy back to the original + // reg. + MachineBasicBlock *useMBB = useInst->getParent(); + MachineBasicBlock::iterator useItr(useInst); + tii->copyRegToReg(*useMBB, next(useItr), li->reg, newVReg, trc, trc); + MachineInstr *copyMI = next(useItr); + copyMI->addRegisterKilled(newVReg, tri); + SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); + + // Change the old two-address defined range & vni to start at + // (and be defined by) the copy. + LiveRange *origDefRange = + li->getLiveRangeContaining(useIdx.getDefIndex()); + origDefRange->start = copyIdx.getDefIndex(); + origDefRange->valno->def = copyIdx.getDefIndex(); + origDefRange->valno->setCopy(copyMI); + + // Insert a new range & vni for the two-address-to-copy value. This + // will be attached to the new live interval. + VNInfo *copyVNI = + newLI->getNextValue(useIdx.getDefIndex(), 0, true, + lis->getVNInfoAllocator()); + copyVNI->addKill(copyIdx.getDefIndex()); + LiveRange copyRange(useIdx.getDefIndex(),copyIdx.getDefIndex(),copyVNI); + newLI->addRange(copyRange); + } + } + + // Iterate over any PHI kills - we'll need to insert new copies for them. + for (VNInfo::KillSet::iterator + killItr = newVNI->kills.begin(), killEnd = newVNI->kills.end(); + killItr != killEnd; ++killItr) { + SlotIndex killIdx(*killItr); + if (killItr->isPHI()) { + MachineBasicBlock *killMBB = lis->getMBBFromIndex(killIdx); + LiveRange *oldKillRange = + newLI->getLiveRangeContaining(killIdx); + + assert(oldKillRange != 0 && "No kill range?"); + + tii->copyRegToReg(*killMBB, killMBB->getFirstTerminator(), + li->reg, newVReg, trc, trc); + MachineInstr *copyMI = prior(killMBB->getFirstTerminator()); + copyMI->addRegisterKilled(newVReg, tri); + SlotIndex copyIdx = lis->InsertMachineInstrInMaps(copyMI); + + // Save the current end. We may need it to add a new range if the + // current range runs of the end of the MBB. + SlotIndex newKillRangeEnd = oldKillRange->end; + oldKillRange->end = copyIdx.getDefIndex(); + + if (newKillRangeEnd != lis->getMBBEndIdx(killMBB).getNextSlot()) { + assert(newKillRangeEnd > lis->getMBBEndIdx(killMBB).getNextSlot() && + "PHI kill range doesn't reach kill-block end. Not sane."); + newLI->addRange(LiveRange(lis->getMBBEndIdx(killMBB).getNextSlot(), + newKillRangeEnd, newVNI)); + } + + *killItr = oldKillRange->end; + VNInfo *newKillVNI = li->getNextValue(copyIdx.getDefIndex(), + copyMI, true, + lis->getVNInfoAllocator()); + newKillVNI->addKill(lis->getMBBTerminatorGap(killMBB)); + newKillVNI->setHasPHIKill(true); + li->addRange(LiveRange(copyIdx.getDefIndex(), + lis->getMBBEndIdx(killMBB).getNextSlot(), + newKillVNI)); + } + + } + + newVNI->setHasPHIKill(false); + + return newLI; + } + +}; + } llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis, @@ -203,7 +520,8 @@ VirtRegMap *vrm) { switch (spillerOpt) { case trivial: return new TrivialSpiller(mf, lis, vrm); break; - case standard: return new StandardSpiller(mf, lis, loopInfo, vrm); break; + case standard: return new StandardSpiller(lis, loopInfo, vrm); break; + case splitting: return new SplittingSpiller(mf, lis, loopInfo, vrm); break; default: llvm_unreachable("Unreachable!"); break; } } Modified: llvm/trunk/lib/CodeGen/Spiller.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Spiller.h?rev=90951&r1=90950&r2=90951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Spiller.h (original) +++ llvm/trunk/lib/CodeGen/Spiller.h Tue Dec 8 23:39:12 2009 @@ -21,6 +21,7 @@ class MachineFunction; class MachineInstr; class MachineLoopInfo; + class SlotIndex; class VirtRegMap; class VNInfo; @@ -35,7 +36,8 @@ /// Spill the given live range. The method used will depend on the Spiller /// implementation selected. virtual std::vector spill(LiveInterval *li, - SmallVectorImpl &spillIs) = 0; + SmallVectorImpl &spillIs, + SlotIndex *earliestIndex = 0) = 0; }; From sabre at nondot.org Wed Dec 9 01:08:01 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 07:08:01 -0000 Subject: [llvm-commits] [llvm] r90956 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200912090708.nB9781hY012049@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 01:08:01 2009 New Revision: 90956 URL: http://llvm.org/viewvc/llvm-project?rev=90956&view=rev Log: change NonLocalDepEntry from being a typedef for an std::pair to be its own small class. No functionality change. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=90956&r1=90955&r2=90956&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Wed Dec 9 01:08:01 2009 @@ -131,6 +131,27 @@ } }; + /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache, and an + /// entry in the results set for a non-local query. For each BasicBlock (the + /// BB entry) it keeps a MemDepResult. + class NonLocalDepEntry { + BasicBlock *BB; + MemDepResult Result; + public: + NonLocalDepEntry(BasicBlock *bb, MemDepResult result) + : BB(bb), Result(result) {} + + // BB is the sort key, it can't be changed. + BasicBlock *getBB() const { return BB; } + + const MemDepResult &getResult() const { return Result; } + void setResult(const MemDepResult &R) { Result = R; } + + bool operator<(const NonLocalDepEntry &RHS) const { + return BB < RHS.BB; + } + }; + /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, @@ -152,7 +173,6 @@ LocalDepMapType LocalDeps; public: - typedef std::pair NonLocalDepEntry; typedef std::vector NonLocalDepInfo; private: /// ValueIsLoadPair - This is a pair where the bool is true if Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=90956&r1=90955&r2=90956&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Dec 9 01:08:01 2009 @@ -422,7 +422,7 @@ if (Count == 0) return; for (unsigned i = 1; i != unsigned(Count); ++i) - assert(Cache[i-1] <= Cache[i] && "Cache isn't sorted!"); + assert(!(Cache[i] < Cache[i-1]) && "Cache isn't sorted!"); } #endif @@ -463,8 +463,8 @@ // determine what is dirty, seeding our initial DirtyBlocks worklist. for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E; ++I) - if (I->second.isDirty()) - DirtyBlocks.push_back(I->first); + if (I->getResult().isDirty()) + DirtyBlocks.push_back(I->getBB()); // Sort the cache so that we can do fast binary search lookups below. std::sort(Cache.begin(), Cache.end()); @@ -502,27 +502,27 @@ DEBUG(AssertSorted(Cache, NumSortedEntries)); NonLocalDepInfo::iterator Entry = std::upper_bound(Cache.begin(), Cache.begin()+NumSortedEntries, - std::make_pair(DirtyBB, MemDepResult())); - if (Entry != Cache.begin() && prior(Entry)->first == DirtyBB) + NonLocalDepEntry(DirtyBB, MemDepResult())); + if (Entry != Cache.begin() && prior(Entry)->getBB() == DirtyBB) --Entry; - MemDepResult *ExistingResult = 0; + NonLocalDepEntry *ExistingResult = 0; if (Entry != Cache.begin()+NumSortedEntries && - Entry->first == DirtyBB) { + Entry->getBB() == DirtyBB) { // If we already have an entry, and if it isn't already dirty, the block // is done. - if (!Entry->second.isDirty()) + if (!Entry->getResult().isDirty()) continue; // Otherwise, remember this slot so we can update the value. - ExistingResult = &Entry->second; + ExistingResult = &*Entry; } // If the dirty entry has a pointer, start scanning from it so we don't have // to rescan the entire block. BasicBlock::iterator ScanPos = DirtyBB->end(); if (ExistingResult) { - if (Instruction *Inst = ExistingResult->getInst()) { + if (Instruction *Inst = ExistingResult->getResult().getInst()) { ScanPos = Inst; // We're removing QueryInst's use of Inst. RemoveFromReverseMap(ReverseNonLocalDeps, Inst, @@ -546,9 +546,9 @@ // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. if (ExistingResult) - *ExistingResult = Dep; + ExistingResult->setResult(Dep); else - Cache.push_back(std::make_pair(DirtyBB, Dep)); + Cache.push_back(NonLocalDepEntry(DirtyBB, Dep)); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember the association! @@ -599,8 +599,8 @@ Result, Visited, true)) return; Result.clear(); - Result.push_back(std::make_pair(FromBB, - MemDepResult::getClobber(FromBB->begin()))); + Result.push_back(NonLocalDepEntry(FromBB, + MemDepResult::getClobber(FromBB->begin()))); } /// GetNonLocalInfoForBlock - Compute the memdep value for BB with @@ -616,30 +616,30 @@ // the cache set. If so, find it. NonLocalDepInfo::iterator Entry = std::upper_bound(Cache->begin(), Cache->begin()+NumSortedEntries, - std::make_pair(BB, MemDepResult())); - if (Entry != Cache->begin() && prior(Entry)->first == BB) + NonLocalDepEntry(BB, MemDepResult())); + if (Entry != Cache->begin() && (Entry-1)->getBB() == BB) --Entry; - MemDepResult *ExistingResult = 0; - if (Entry != Cache->begin()+NumSortedEntries && Entry->first == BB) - ExistingResult = &Entry->second; + NonLocalDepEntry *ExistingResult = 0; + if (Entry != Cache->begin()+NumSortedEntries && Entry->getBB() == BB) + ExistingResult = &*Entry; // If we have a cached entry, and it is non-dirty, use it as the value for // this dependency. - if (ExistingResult && !ExistingResult->isDirty()) { + if (ExistingResult && !ExistingResult->getResult().isDirty()) { ++NumCacheNonLocalPtr; - return *ExistingResult; + return ExistingResult->getResult(); } // Otherwise, we have to scan for the value. If we have a dirty cache // entry, start scanning from its position, otherwise we scan from the end // of the block. BasicBlock::iterator ScanPos = BB->end(); - if (ExistingResult && ExistingResult->getInst()) { - assert(ExistingResult->getInst()->getParent() == BB && + if (ExistingResult && ExistingResult->getResult().getInst()) { + assert(ExistingResult->getResult().getInst()->getParent() == BB && "Instruction invalidated?"); ++NumCacheDirtyNonLocalPtr; - ScanPos = ExistingResult->getInst(); + ScanPos = ExistingResult->getResult().getInst(); // Eliminating the dirty entry from 'Cache', so update the reverse info. ValueIsLoadPair CacheKey(Pointer, isLoad); @@ -655,9 +655,9 @@ // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. if (ExistingResult) - *ExistingResult = Dep; + ExistingResult->setResult(Dep); else - Cache->push_back(std::make_pair(BB, Dep)); + Cache->push_back(NonLocalDepEntry(BB, Dep)); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember the reverse association because we just added it @@ -686,7 +686,7 @@ break; case 2: { // Two new entries, insert the last one into place. - MemoryDependenceAnalysis::NonLocalDepEntry Val = Cache.back(); + NonLocalDepEntry Val = Cache.back(); Cache.pop_back(); MemoryDependenceAnalysis::NonLocalDepInfo::iterator Entry = std::upper_bound(Cache.begin(), Cache.end()-1, Val); @@ -696,7 +696,7 @@ case 1: // One new entry, Just insert the new value at the appropriate position. if (Cache.size() != 1) { - MemoryDependenceAnalysis::NonLocalDepEntry Val = Cache.back(); + NonLocalDepEntry Val = Cache.back(); Cache.pop_back(); MemoryDependenceAnalysis::NonLocalDepInfo::iterator Entry = std::upper_bound(Cache.begin(), Cache.end(), Val); @@ -747,7 +747,7 @@ if (!Visited.empty()) { for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end(); I != E; ++I) { - DenseMap::iterator VI = Visited.find(I->first); + DenseMap::iterator VI = Visited.find(I->getBB()); if (VI == Visited.end() || VI->second == Pointer.getAddr()) continue; @@ -760,8 +760,8 @@ for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end(); I != E; ++I) { - Visited.insert(std::make_pair(I->first, Pointer.getAddr())); - if (!I->second.isNonLocal()) + Visited.insert(std::make_pair(I->getBB(), Pointer.getAddr())); + if (!I->getResult().isNonLocal()) Result.push_back(*I); } ++NumCacheCompleteNonLocalPtr; @@ -898,27 +898,27 @@ MemoryDependenceAnalysis::NonLocalDepInfo::iterator It = std::upper_bound(Cache->begin(), Cache->end(), Entry); - if (It != Cache->begin() && prior(It)->first == Pred) + if (It != Cache->begin() && (It-1)->getBB() == Pred) --It; - if (It == Cache->end() || It->first != Pred) { + if (It == Cache->end() || It->getBB() != Pred) { Cache->insert(It, Entry); // Add it to the reverse map. ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey); - } else if (!It->second.isDirty()) { + } else if (!It->getResult().isDirty()) { // noop - } else if (It->second.getInst() == Pred->getTerminator()) { + } else if (It->getResult().getInst() == Pred->getTerminator()) { // Same instruction, clear the dirty marker. - It->second = Entry.second; - } else if (It->second.getInst() == 0) { + It->setResult(Entry.getResult()); + } else if (It->getResult().getInst() == 0) { // Dirty, with no instruction, just add this. - It->second = Entry.second; + It->setResult(Entry.getResult()); ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey); } else { // Otherwise, dirty with a different instruction. - RemoveFromReverseMap(ReverseNonLocalPtrDeps, It->second.getInst(), - CacheKey); - It->second = Entry.second; + RemoveFromReverseMap(ReverseNonLocalPtrDeps, + It->getResult().getInst(), CacheKey); + It->setResult(Entry.getResult()); ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey); } Cache = 0; @@ -976,12 +976,12 @@ for (NonLocalDepInfo::reverse_iterator I = Cache->rbegin(); ; ++I) { assert(I != Cache->rend() && "Didn't find current block??"); - if (I->first != BB) + if (I->getBB() != BB) continue; - assert(I->second.isNonLocal() && + assert(I->getResult().isNonLocal() && "Should only be here with transparent block"); - I->second = MemDepResult::getClobber(BB->begin()); + I->setResult(MemDepResult::getClobber(BB->begin())); ReverseNonLocalPtrDeps[BB->begin()].insert(CacheKey); Result.push_back(*I); break; @@ -1007,9 +1007,9 @@ NonLocalDepInfo &PInfo = It->second.second; for (unsigned i = 0, e = PInfo.size(); i != e; ++i) { - Instruction *Target = PInfo[i].second.getInst(); + Instruction *Target = PInfo[i].getResult().getInst(); if (Target == 0) continue; // Ignore non-local dep results. - assert(Target->getParent() == PInfo[i].first); + assert(Target->getParent() == PInfo[i].getBB()); // Eliminating the dirty entry from 'Cache', so update the reverse info. RemoveFromReverseMap(ReverseNonLocalPtrDeps, Target, P); @@ -1046,7 +1046,7 @@ NonLocalDepInfo &BlockMap = NLDI->second.first; for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) - if (Instruction *Inst = DI->second.getInst()) + if (Instruction *Inst = DI->getResult().getInst()) RemoveFromReverseMap(ReverseNonLocalDeps, Inst, RemInst); NonLocalDeps.erase(NLDI); } @@ -1134,10 +1134,10 @@ for (NonLocalDepInfo::iterator DI = INLD.first.begin(), DE = INLD.first.end(); DI != DE; ++DI) { - if (DI->second.getInst() != RemInst) continue; + if (DI->getResult().getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - DI->second = NewDirtyVal; + DI->setResult(NewDirtyVal); if (Instruction *NextI = NewDirtyVal.getInst()) ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); @@ -1176,10 +1176,10 @@ // Update any entries for RemInst to use the instruction after it. for (NonLocalDepInfo::iterator DI = NLPDI.begin(), DE = NLPDI.end(); DI != DE; ++DI) { - if (DI->second.getInst() != RemInst) continue; + if (DI->getResult().getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - DI->second = NewDirtyVal; + DI->setResult(NewDirtyVal); if (Instruction *NewDirtyInst = NewDirtyVal.getInst()) ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P)); @@ -1220,7 +1220,7 @@ const NonLocalDepInfo &Val = I->second.second; for (NonLocalDepInfo::const_iterator II = Val.begin(), E = Val.end(); II != E; ++II) - assert(II->second.getInst() != D && "Inst occurs as NLPD value"); + assert(II->getResult().getInst() != D && "Inst occurs as NLPD value"); } for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), @@ -1229,7 +1229,7 @@ const PerInstNLInfo &INLD = I->second; for (NonLocalDepInfo::const_iterator II = INLD.first.begin(), EE = INLD.first.end(); II != EE; ++II) - assert(II->second.getInst() != D && "Inst occurs in data structures"); + assert(II->getResult().getInst() != D && "Inst occurs in data structures"); } for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90956&r1=90955&r2=90956&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 01:08:01 2009 @@ -491,21 +491,21 @@ // Check to see if we have a single dominating call instruction that is // identical to C. for (unsigned i = 0, e = deps.size(); i != e; ++i) { - const MemoryDependenceAnalysis::NonLocalDepEntry *I = &deps[i]; + const NonLocalDepEntry *I = &deps[i]; // Ignore non-local dependencies. - if (I->second.isNonLocal()) + if (I->getResult().isNonLocal()) continue; // We don't handle non-depedencies. If we already have a call, reject // instruction dependencies. - if (I->second.isClobber() || cdep != 0) { + if (I->getResult().isClobber() || cdep != 0) { cdep = 0; break; } - CallInst *NonLocalDepCall = dyn_cast(I->second.getInst()); + CallInst *NonLocalDepCall = dyn_cast(I->getResult().getInst()); // FIXME: All duplicated with non-local case. - if (NonLocalDepCall && DT->properlyDominates(I->first, C->getParent())){ + if (NonLocalDepCall && DT->properlyDominates(I->getBB(), C->getParent())){ cdep = NonLocalDepCall; continue; } @@ -1344,7 +1344,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI, SmallVectorImpl &toErase) { // Find the non-local dependencies of the load. - SmallVector Deps; + SmallVector Deps; MD->getNonLocalPointerDependency(LI->getOperand(0), true, LI->getParent(), Deps); //DEBUG(errs() << "INVESTIGATING NONLOCAL LOAD: " @@ -1358,11 +1358,11 @@ // If we had a phi translation failure, we'll have a single entry which is a // clobber in the current block. Reject this early. - if (Deps.size() == 1 && Deps[0].second.isClobber()) { + if (Deps.size() == 1 && Deps[0].getResult().isClobber()) { DEBUG( errs() << "GVN: non-local load "; WriteAsOperand(errs(), LI); - errs() << " is clobbered by " << *Deps[0].second.getInst() << '\n'; + errs() << " is clobbered by " << *Deps[0].getResult().getInst() << '\n'; ); return false; } @@ -1377,8 +1377,8 @@ const TargetData *TD = 0; for (unsigned i = 0, e = Deps.size(); i != e; ++i) { - BasicBlock *DepBB = Deps[i].first; - MemDepResult DepInfo = Deps[i].second; + BasicBlock *DepBB = Deps[i].getBB(); + MemDepResult DepInfo = Deps[i].getResult(); if (DepInfo.isClobber()) { // If the dependence is to a store that writes to a superset of the bits From daniel at zuster.org Wed Dec 9 01:19:48 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 09 Dec 2009 07:19:48 -0000 Subject: [llvm-commits] [llvm] r90957 - in /llvm/trunk: include/llvm/ADT/DeltaAlgorithm.h lib/Support/DeltaAlgorithm.cpp Message-ID: <200912090719.nB97JnM3012460@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 01:19:48 2009 New Revision: 90957 URL: http://llvm.org/viewvc/llvm-project?rev=90957&view=rev Log: DeltaAlgorithm: Add a virtual destructor and home. Modified: llvm/trunk/include/llvm/ADT/DeltaAlgorithm.h llvm/trunk/lib/Support/DeltaAlgorithm.cpp Modified: llvm/trunk/include/llvm/ADT/DeltaAlgorithm.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DeltaAlgorithm.h?rev=90957&r1=90956&r2=90957&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DeltaAlgorithm.h (original) +++ llvm/trunk/include/llvm/ADT/DeltaAlgorithm.h Wed Dec 9 01:19:48 2009 @@ -78,6 +78,8 @@ virtual bool ExecuteOneTest(const changeset_ty &S) = 0; public: + virtual ~DeltaAlgorithm(); + /// Run - Minimize the set \arg Changes by executing \see ExecuteOneTest() on /// subsets of changes and returning the smallest set which still satisfies /// the test predicate. Modified: llvm/trunk/lib/Support/DeltaAlgorithm.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DeltaAlgorithm.cpp?rev=90957&r1=90956&r2=90957&view=diff ============================================================================== --- llvm/trunk/lib/Support/DeltaAlgorithm.cpp (original) +++ llvm/trunk/lib/Support/DeltaAlgorithm.cpp Wed Dec 9 01:19:48 2009 @@ -11,6 +11,9 @@ #include using namespace llvm; +DeltaAlgorithm::~DeltaAlgorithm() { +} + bool DeltaAlgorithm::GetTestResult(const changeset_ty &Changes) { if (FailedTestsCache.count(Changes)) return false; From sabre at nondot.org Wed Dec 9 01:31:04 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 07:31:04 -0000 Subject: [llvm-commits] [llvm] r90958 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200912090731.nB97V4s4012865@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 01:31:04 2009 New Revision: 90958 URL: http://llvm.org/viewvc/llvm-project?rev=90958&view=rev Log: enhance NonLocalDepEntry to keep the per-block phi translated address of the query. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=90958&r1=90957&r2=90958&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Wed Dec 9 01:31:04 2009 @@ -16,6 +16,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Pass.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" @@ -133,20 +134,38 @@ /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache, and an /// entry in the results set for a non-local query. For each BasicBlock (the - /// BB entry) it keeps a MemDepResult. + /// BB entry) it keeps a MemDepResult and the (potentially phi translated) + /// address that was live in the block. class NonLocalDepEntry { BasicBlock *BB; MemDepResult Result; + WeakVH Address; public: - NonLocalDepEntry(BasicBlock *bb, MemDepResult result) - : BB(bb), Result(result) {} - + NonLocalDepEntry(BasicBlock *bb, MemDepResult result, Value *address) + : BB(bb), Result(result), Address(address) {} + + // This is used for searches. + NonLocalDepEntry(BasicBlock *bb) : BB(bb) {} + // BB is the sort key, it can't be changed. BasicBlock *getBB() const { return BB; } + void setResult(const MemDepResult &R, Value *Addr) { + Result = R; + Address = Addr; + } + const MemDepResult &getResult() const { return Result; } - void setResult(const MemDepResult &R) { Result = R; } + /// getAddress - Return the address of this pointer in this block. This can + /// be different than the address queried for the non-local result because + /// of phi translation. This returns null if the address was not available + /// in a block (i.e. because phi translation failed) or if this is a cached + /// result and that address was deleted. + /// + /// The address is always null for a non-local 'call' dependence. + Value *getAddress() const { return Address; } + bool operator<(const NonLocalDepEntry &RHS) const { return BB < RHS.BB; } Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=90958&r1=90957&r2=90958&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Dec 9 01:31:04 2009 @@ -502,7 +502,7 @@ DEBUG(AssertSorted(Cache, NumSortedEntries)); NonLocalDepInfo::iterator Entry = std::upper_bound(Cache.begin(), Cache.begin()+NumSortedEntries, - NonLocalDepEntry(DirtyBB, MemDepResult())); + NonLocalDepEntry(DirtyBB)); if (Entry != Cache.begin() && prior(Entry)->getBB() == DirtyBB) --Entry; @@ -546,9 +546,9 @@ // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. if (ExistingResult) - ExistingResult->setResult(Dep); + ExistingResult->setResult(Dep, 0); else - Cache.push_back(NonLocalDepEntry(DirtyBB, Dep)); + Cache.push_back(NonLocalDepEntry(DirtyBB, Dep, 0)); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember the association! @@ -600,7 +600,8 @@ return; Result.clear(); Result.push_back(NonLocalDepEntry(FromBB, - MemDepResult::getClobber(FromBB->begin()))); + MemDepResult::getClobber(FromBB->begin()), + Pointer)); } /// GetNonLocalInfoForBlock - Compute the memdep value for BB with @@ -616,7 +617,7 @@ // the cache set. If so, find it. NonLocalDepInfo::iterator Entry = std::upper_bound(Cache->begin(), Cache->begin()+NumSortedEntries, - NonLocalDepEntry(BB, MemDepResult())); + NonLocalDepEntry(BB)); if (Entry != Cache->begin() && (Entry-1)->getBB() == BB) --Entry; @@ -655,9 +656,9 @@ // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. if (ExistingResult) - ExistingResult->setResult(Dep); + ExistingResult->setResult(Dep, Pointer); else - Cache->push_back(NonLocalDepEntry(BB, Dep)); + Cache->push_back(NonLocalDepEntry(BB, Dep, Pointer)); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember the reverse association because we just added it @@ -806,7 +807,7 @@ // If we got a Def or Clobber, add this to the list of results. if (!Dep.isNonLocal()) { - Result.push_back(NonLocalDepEntry(BB, Dep)); + Result.push_back(NonLocalDepEntry(BB, Dep, Pointer.getAddr())); continue; } } @@ -889,7 +890,8 @@ if (PredPtrVal == 0) { // Add the entry to the Result list. NonLocalDepEntry Entry(Pred, - MemDepResult::getClobber(Pred->getTerminator())); + MemDepResult::getClobber(Pred->getTerminator()), + PredPtrVal); Result.push_back(Entry); // Add it to the cache for this CacheKey so that subsequent queries get @@ -909,16 +911,16 @@ // noop } else if (It->getResult().getInst() == Pred->getTerminator()) { // Same instruction, clear the dirty marker. - It->setResult(Entry.getResult()); + It->setResult(Entry.getResult(), PredPtrVal); } else if (It->getResult().getInst() == 0) { // Dirty, with no instruction, just add this. - It->setResult(Entry.getResult()); + It->setResult(Entry.getResult(), PredPtrVal); ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey); } else { // Otherwise, dirty with a different instruction. RemoveFromReverseMap(ReverseNonLocalPtrDeps, It->getResult().getInst(), CacheKey); - It->setResult(Entry.getResult()); + It->setResult(Entry.getResult(),PredPtrVal); ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey); } Cache = 0; @@ -981,7 +983,7 @@ assert(I->getResult().isNonLocal() && "Should only be here with transparent block"); - I->setResult(MemDepResult::getClobber(BB->begin())); + I->setResult(MemDepResult::getClobber(BB->begin()), Pointer.getAddr()); ReverseNonLocalPtrDeps[BB->begin()].insert(CacheKey); Result.push_back(*I); break; @@ -1137,7 +1139,7 @@ if (DI->getResult().getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - DI->setResult(NewDirtyVal); + DI->setResult(NewDirtyVal, DI->getAddress()); if (Instruction *NextI = NewDirtyVal.getInst()) ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); @@ -1179,7 +1181,7 @@ if (DI->getResult().getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - DI->setResult(NewDirtyVal); + DI->setResult(NewDirtyVal, DI->getAddress()); if (Instruction *NewDirtyInst = NewDirtyVal.getInst()) ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P)); From sabre at nondot.org Wed Dec 9 01:34:10 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 07:34:10 -0000 Subject: [llvm-commits] [llvm] r90959 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200912090734.nB97YAiY012961@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 01:34:10 2009 New Revision: 90959 URL: http://llvm.org/viewvc/llvm-project?rev=90959&view=rev Log: change AnalyzeLoadFromClobberingWrite and clients to pass in type and pointer instead of the load. No functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90959&r1=90958&r2=90959&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 01:34:10 2009 @@ -998,18 +998,19 @@ /// Check this case to see if there is anything more we can do before we give /// up. This returns -1 if we have to give up, or a byte number in the stored /// value of the piece that feeds the load. -static int AnalyzeLoadFromClobberingWrite(LoadInst *L, Value *WritePtr, +static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr, + Value *WritePtr, uint64_t WriteSizeInBits, const TargetData &TD) { // If the loaded or stored value is an first class array or struct, don't try // to transform them. We need to be able to bitcast to integer. - if (isa(L->getType()) || isa(L->getType())) + if (isa(LoadTy) || isa(LoadTy)) return -1; int64_t StoreOffset = 0, LoadOffset = 0; Value *StoreBase = GetBaseWithConstantOffset(WritePtr, StoreOffset, TD); Value *LoadBase = - GetBaseWithConstantOffset(L->getPointerOperand(), LoadOffset, TD); + GetBaseWithConstantOffset(LoadPtr, LoadOffset, TD); if (StoreBase != LoadBase) return -1; @@ -1022,10 +1023,8 @@ << "Base = " << *StoreBase << "\n" << "Store Ptr = " << *WritePtr << "\n" << "Store Offs = " << StoreOffset << "\n" - << "Load Ptr = " << *L->getPointerOperand() << "\n" + << "Load Ptr = " << *LoadPtr << "\n" << "Load Offs = " << LoadOffset << " - " << *L << "\n\n"; - errs() << "'" << L->getParent()->getParent()->getName() << "'" - << *L->getParent(); abort(); #endif return -1; @@ -1036,7 +1035,7 @@ // must have gotten confused. // FIXME: Investigate cases where this bails out, e.g. rdar://7238614. Then // remove this check, as it is duplicated with what we have below. - uint64_t LoadSize = TD.getTypeSizeInBits(L->getType()); + uint64_t LoadSize = TD.getTypeSizeInBits(LoadTy); if ((WriteSizeInBits & 7) | (LoadSize & 7)) return -1; @@ -1089,7 +1088,8 @@ Value *StorePtr = DepSI->getPointerOperand(); uint64_t StoreSize = TD.getTypeSizeInBits(StorePtr->getType()); - return AnalyzeLoadFromClobberingWrite(L, StorePtr, StoreSize, TD); + return AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), + StorePtr, StoreSize, TD); } static int AnalyzeLoadFromClobberingMemInst(LoadInst *L, MemIntrinsic *MI, @@ -1102,7 +1102,8 @@ // If this is memset, we just need to see if the offset is valid in the size // of the memset.. if (MI->getIntrinsicID() == Intrinsic::memset) - return AnalyzeLoadFromClobberingWrite(L, MI->getDest(), MemSizeInBits, TD); + return AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), + MI->getDest(), MemSizeInBits, TD); // If we have a memcpy/memmove, the only case we can handle is if this is a // copy from constant memory. In that case, we can read directly from the @@ -1117,7 +1118,8 @@ // See if the access is within the bounds of the transfer. int Offset = - AnalyzeLoadFromClobberingWrite(L, MI->getDest(), MemSizeInBits, TD); + AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), + MI->getDest(), MemSizeInBits, TD); if (Offset == -1) return Offset; From sabre at nondot.org Wed Dec 9 01:37:07 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 07:37:07 -0000 Subject: [llvm-commits] [llvm] r90960 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200912090737.nB97b7X0013090@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 01:37:07 2009 New Revision: 90960 URL: http://llvm.org/viewvc/llvm-project?rev=90960&view=rev Log: change AnalyzeLoadFromClobberingMemInst/AnalyzeLoadFromClobberingStore to require the load ty/ptr to be passed in, no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90960&r1=90959&r2=90960&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 01:37:07 2009 @@ -1079,7 +1079,8 @@ /// AnalyzeLoadFromClobberingStore - This function is called when we have a /// memdep query of a load that ends up being a clobbering store. -static int AnalyzeLoadFromClobberingStore(LoadInst *L, StoreInst *DepSI, +static int AnalyzeLoadFromClobberingStore(const Type *LoadTy, Value *LoadPtr, + StoreInst *DepSI, const TargetData &TD) { // Cannot handle reading from store of first-class aggregate yet. if (isa(DepSI->getOperand(0)->getType()) || @@ -1088,11 +1089,12 @@ Value *StorePtr = DepSI->getPointerOperand(); uint64_t StoreSize = TD.getTypeSizeInBits(StorePtr->getType()); - return AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), + return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, StorePtr, StoreSize, TD); } -static int AnalyzeLoadFromClobberingMemInst(LoadInst *L, MemIntrinsic *MI, +static int AnalyzeLoadFromClobberingMemInst(const Type *LoadTy, Value *LoadPtr, + MemIntrinsic *MI, const TargetData &TD) { // If the mem operation is a non-constant size, we can't handle it. ConstantInt *SizeCst = dyn_cast(MI->getLength()); @@ -1102,8 +1104,8 @@ // If this is memset, we just need to see if the offset is valid in the size // of the memset.. if (MI->getIntrinsicID() == Intrinsic::memset) - return AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), - MI->getDest(), MemSizeInBits, TD); + return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, MI->getDest(), + MemSizeInBits, TD); // If we have a memcpy/memmove, the only case we can handle is if this is a // copy from constant memory. In that case, we can read directly from the @@ -1117,9 +1119,8 @@ if (GV == 0 || !GV->isConstant()) return -1; // See if the access is within the bounds of the transfer. - int Offset = - AnalyzeLoadFromClobberingWrite(L->getType(), L->getPointerOperand(), - MI->getDest(), MemSizeInBits, TD); + int Offset = AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, + MI->getDest(), MemSizeInBits, TD); if (Offset == -1) return Offset; @@ -1130,7 +1131,7 @@ Constant *OffsetCst = ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); Src = ConstantExpr::getGetElementPtr(Src, &OffsetCst, 1); - Src = ConstantExpr::getBitCast(Src, PointerType::getUnqual(L->getType())); + Src = ConstantExpr::getBitCast(Src, PointerType::getUnqual(LoadTy)); if (ConstantFoldLoadFromConstPtr(Src, &TD)) return Offset; return -1; @@ -1390,7 +1391,9 @@ if (TD == 0) TD = getAnalysisIfAvailable(); if (TD) { - int Offset = AnalyzeLoadFromClobberingStore(LI, DepSI, *TD); + int Offset = AnalyzeLoadFromClobberingStore(LI->getType(), + LI->getPointerOperand(), + DepSI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, DepSI->getOperand(0), @@ -1406,7 +1409,9 @@ if (TD == 0) TD = getAnalysisIfAvailable(); if (TD) { - int Offset = AnalyzeLoadFromClobberingMemInst(LI, DepMI, *TD); + int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), + LI->getPointerOperand(), + DepMI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::getMI(DepBB, DepMI, Offset)); @@ -1711,7 +1716,9 @@ Value *AvailVal = 0; if (StoreInst *DepSI = dyn_cast(Dep.getInst())) if (const TargetData *TD = getAnalysisIfAvailable()) { - int Offset = AnalyzeLoadFromClobberingStore(L, DepSI, *TD); + int Offset = AnalyzeLoadFromClobberingStore(L->getType(), + L->getPointerOperand(), + DepSI, *TD); if (Offset != -1) AvailVal = GetStoreValueForLoad(DepSI->getOperand(0), Offset, L->getType(), L, *TD); @@ -1721,7 +1728,9 @@ // a value on from it. if (MemIntrinsic *DepMI = dyn_cast(Dep.getInst())) { if (const TargetData *TD = getAnalysisIfAvailable()) { - int Offset = AnalyzeLoadFromClobberingMemInst(L, DepMI, *TD); + int Offset = AnalyzeLoadFromClobberingMemInst(L->getType(), + L->getPointerOperand(), + DepMI, *TD); if (Offset != -1) AvailVal = GetMemInstValueForLoad(DepMI, Offset, L->getType(), L,*TD); } From echristo at apple.com Wed Dec 9 02:29:34 2009 From: echristo at apple.com (Eric Christopher) Date: Wed, 09 Dec 2009 08:29:34 -0000 Subject: [llvm-commits] [llvm] r90962 - /llvm/trunk/include/llvm/Target/TargetData.h Message-ID: <200912090829.nB98TaDQ014861@zion.cs.uiuc.edu> Author: echristo Date: Wed Dec 9 02:29:32 2009 New Revision: 90962 URL: http://llvm.org/viewvc/llvm-project?rev=90962&view=rev Log: Silence conversion warning from 64 to 32-bit. Modified: llvm/trunk/include/llvm/Target/TargetData.h Modified: llvm/trunk/include/llvm/Target/TargetData.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=90962&r1=90961&r2=90962&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetData.h (original) +++ llvm/trunk/include/llvm/Target/TargetData.h Wed Dec 9 02:29:32 2009 @@ -150,7 +150,7 @@ /// The width is specified in bits. /// bool isLegalInteger(unsigned Width) const { - for (unsigned i = 0, e = LegalIntWidths.size(); i != e; ++i) + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) if (LegalIntWidths[i] == Width) return true; return false; From baldrick at free.fr Wed Dec 9 03:03:12 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 09 Dec 2009 10:03:12 +0100 Subject: [llvm-commits] [llvm] r90910 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp In-Reply-To: <200912090028.nB90Sinv030745@zion.cs.uiuc.edu> References: <200912090028.nB90Sinv030745@zion.cs.uiuc.edu> Message-ID: <4B1F67D0.6000704@free.fr> Hi Dan, > - SmallVector Worklist; > - SmallSet Visited; > + SmallVector Worklist; > + SmallSet Visited; maybe better to use Threshold here rather than 20. Ciao, Duncan. From sabre at nondot.org Wed Dec 9 11:17:27 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 17:17:27 -0000 Subject: [llvm-commits] [llvm] r90969 - in /llvm/trunk/test/Transforms/GVN: crash-2.ll crash.ll Message-ID: <200912091717.nB9HHR2Q019912@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 11:17:26 2009 New Revision: 90969 URL: http://llvm.org/viewvc/llvm-project?rev=90969&view=rev Log: merge crash-2.ll into crash.ll Removed: llvm/trunk/test/Transforms/GVN/crash-2.ll Modified: llvm/trunk/test/Transforms/GVN/crash.ll Removed: llvm/trunk/test/Transforms/GVN/crash-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/crash-2.ll?rev=90968&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/crash-2.ll (original) +++ llvm/trunk/test/Transforms/GVN/crash-2.ll (removed) @@ -1,43 +0,0 @@ -; RUN: opt -gvn -S %s -; rdar://7438974 - -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-apple-darwin9.0" - - at g = external global i64, align 8 - -define i32* @foo() { -do.end17.i: - %tmp18.i = load i7** undef - %tmp1 = bitcast i7* %tmp18.i to i8* - br i1 undef, label %do.body36.i, label %if.then21.i - -if.then21.i: - %tmp2 = bitcast i7* %tmp18.i to i8* - ret i32* undef - -do.body36.i: - %ivar38.i = load i64* @g - %tmp3 = bitcast i7* %tmp18.i to i8* - %add.ptr39.sum.i = add i64 %ivar38.i, 8 - %tmp40.i = getelementptr inbounds i8* %tmp3, i64 %add.ptr39.sum.i - %tmp4 = bitcast i8* %tmp40.i to i64* - %tmp41.i = load i64* %tmp4 - br i1 undef, label %if.then48.i, label %do.body57.i - -if.then48.i: - %call54.i = call i32 @foo2() - br label %do.body57.i - -do.body57.i: - %tmp58.i = load i7** undef - %ivar59.i = load i64* @g - %tmp5 = bitcast i7* %tmp58.i to i8* - %add.ptr65.sum.i = add i64 %ivar59.i, 8 - %tmp66.i = getelementptr inbounds i8* %tmp5, i64 %add.ptr65.sum.i - %tmp6 = bitcast i8* %tmp66.i to i64* - %tmp67.i = load i64* %tmp6 - ret i32* undef -} - -declare i32 @foo2() Modified: llvm/trunk/test/Transforms/GVN/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/crash.ll?rev=90969&r1=90968&r2=90969&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/crash.ll (original) +++ llvm/trunk/test/Transforms/GVN/crash.ll Wed Dec 9 11:17:26 2009 @@ -92,3 +92,46 @@ bb66.i: ; Unreachable br label %bb69.i } + + + +; rdar://7438974 + + at g = external global i64, align 8 + +define i32* @foo() { +do.end17.i: + %tmp18.i = load i7** undef + %tmp1 = bitcast i7* %tmp18.i to i8* + br i1 undef, label %do.body36.i, label %if.then21.i + +if.then21.i: + %tmp2 = bitcast i7* %tmp18.i to i8* + ret i32* undef + +do.body36.i: + %ivar38.i = load i64* @g + %tmp3 = bitcast i7* %tmp18.i to i8* + %add.ptr39.sum.i = add i64 %ivar38.i, 8 + %tmp40.i = getelementptr inbounds i8* %tmp3, i64 %add.ptr39.sum.i + %tmp4 = bitcast i8* %tmp40.i to i64* + %tmp41.i = load i64* %tmp4 + br i1 undef, label %if.then48.i, label %do.body57.i + +if.then48.i: + %call54.i = call i32 @foo2() + br label %do.body57.i + +do.body57.i: + %tmp58.i = load i7** undef + %ivar59.i = load i64* @g + %tmp5 = bitcast i7* %tmp58.i to i8* + %add.ptr65.sum.i = add i64 %ivar59.i, 8 + %tmp66.i = getelementptr inbounds i8* %tmp5, i64 %add.ptr65.sum.i + %tmp6 = bitcast i8* %tmp66.i to i64* + %tmp67.i = load i64* %tmp6 + ret i32* undef +} + +declare i32 @foo2() + From david_goodwin at apple.com Wed Dec 9 11:18:22 2009 From: david_goodwin at apple.com (David Goodwin) Date: Wed, 09 Dec 2009 17:18:22 -0000 Subject: [llvm-commits] [llvm] r90970 - in /llvm/trunk/lib/CodeGen: AggressiveAntiDepBreaker.cpp AggressiveAntiDepBreaker.h CriticalAntiDepBreaker.cpp PostRASchedulerList.cpp Message-ID: <200912091718.nB9HINZU019955@zion.cs.uiuc.edu> Author: david_goodwin Date: Wed Dec 9 11:18:22 2009 New Revision: 90970 URL: http://llvm.org/viewvc/llvm-project?rev=90970&view=rev Log: . Track only physical registers that are valid for the target. Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=90970&r1=90969&r2=90970&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Wed Dec 9 11:18:22 2009 @@ -38,16 +38,19 @@ cl::desc("Debug control for aggressive anti-dep breaker"), cl::init(0), cl::Hidden); -AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) : - GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { - // Initialize all registers to be in their own group. Initially we - // assign the register to the same-indexed GroupNode. - for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) +AggressiveAntiDepState::AggressiveAntiDepState(const unsigned TargetRegs, + MachineBasicBlock *BB) : + NumTargetRegs(TargetRegs), GroupNodes(TargetRegs, 0) { + + const unsigned BBSize = BB->size(); + for (unsigned i = 0; i < NumTargetRegs; ++i) { + // Initialize all registers to be in their own group. Initially we + // assign the register to the same-indexed GroupNode. GroupNodeIndices[i] = i; - - // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); - std::fill(DefIndices, array_endof(DefIndices), BB->size()); + // Initialize the indices to indicate that no registers are live. + KillIndices[i] = ~0u; + DefIndices[i] = BBSize; + } } unsigned AggressiveAntiDepState::GetGroup(unsigned Reg) @@ -64,7 +67,7 @@ std::vector &Regs, std::multimap *RegRefs) { - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + for (unsigned Reg = 0; Reg != NumTargetRegs; ++Reg) { if ((GetGroup(Reg) == Group) && (RegRefs->count(Reg) > 0)) Regs.push_back(Reg); } @@ -137,7 +140,7 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { assert(State == NULL); - State = new AggressiveAntiDepState(BB); + State = new AggressiveAntiDepState(TRI->getNumRegs(), BB); bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); unsigned *KillIndices = State->GetKillIndices(); @@ -220,7 +223,7 @@ DEBUG(errs() << "\tRegs:"); unsigned *DefIndices = State->GetDefIndices(); - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg) { // If Reg is current live, then mark that it can't be renamed as // we don't know the extent of its live-range anymore (now that it // has been scheduled). If it is not live but was defined in the Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=90970&r1=90969&r2=90970&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Wed Dec 9 11:18:22 2009 @@ -44,6 +44,10 @@ } RegisterReference; private: + /// NumTargetRegs - Number of non-virtual target registers + /// (i.e. TRI->getNumRegs()). + const unsigned NumTargetRegs; + /// GroupNodes - Implements a disjoint-union data structure to /// form register groups. A node is represented by an index into /// the vector. A node can "point to" itself to indicate that it @@ -69,7 +73,7 @@ unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; public: - AggressiveAntiDepState(MachineBasicBlock *BB); + AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB); /// GetKillIndices - Return the kill indices. unsigned *GetKillIndices() { return KillIndices; } Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=90970&r1=90969&r2=90970&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Wed Dec 9 11:18:22 2009 @@ -43,8 +43,11 @@ static_cast(0)); // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); - std::fill(DefIndices, array_endof(DefIndices), BB->size()); + const unsigned BBSize = BB->size(); + for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { + KillIndices[i] = ~0u; + DefIndices[i] = BBSize; + } // Clear "do not change" set. KeepRegs.clear(); @@ -122,7 +125,7 @@ // may have been rescheduled and its lifetime may overlap with registers // in ways not reflected in our current liveness state. For each such // register, adjust the liveness state to be conservatively correct. - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) + for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg) if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); // Mark this register to be non-renamable. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=90970&r1=90969&r2=90970&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 9 11:18:22 2009 @@ -373,7 +373,8 @@ /// void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); + for (unsigned i = 0; i < TRI->getNumRegs(); ++i) + KillIndices[i] = ~0u; // Determine the live-out physregs for this block. if (!BB->empty() && BB->back().getDesc().isReturn()) { From sabre at nondot.org Wed Dec 9 11:18:49 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 17:18:49 -0000 Subject: [llvm-commits] [llvm] r90971 - in /llvm/trunk: lib/Analysis/PHITransAddr.cpp test/Transforms/GVN/crash-2.ll Message-ID: <200912091718.nB9HInFu019978@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 11:18:49 2009 New Revision: 90971 URL: http://llvm.org/viewvc/llvm-project?rev=90971&view=rev Log: fix PR5733, a case where we'd replace an add with a lexically identical binary operator that wasn't an add. In this case, a xor. Whoops. Added: llvm/trunk/test/Transforms/GVN/crash-2.ll Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90971&r1=90970&r2=90971&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Wed Dec 9 11:18:49 2009 @@ -280,7 +280,8 @@ for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); UI != E; ++UI) { if (BinaryOperator *BO = dyn_cast(*UI)) - if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && + if (BO->getOpcode() == Instruction::Add && + BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && BO->getParent()->getParent() == CurBB->getParent()) return BO; } Added: llvm/trunk/test/Transforms/GVN/crash-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/crash-2.ll?rev=90971&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/crash-2.ll (added) +++ llvm/trunk/test/Transforms/GVN/crash-2.ll Wed Dec 9 11:18:49 2009 @@ -0,0 +1,66 @@ +; RUN: opt -instcombine -gvn -S %s +; PR5733 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i686-linux-gnu" + + at ff_cropTbl = external global [2304 x i8] ; <[2304 x i8]*> [#uses=1] + +define void @ff_pred8x8_plane_c(i8* nocapture %src, i32 %stride) nounwind { +entry: + br i1 true, label %bb.nph41, label %for.end + + +bb.nph41: ; preds = %entry + %sub.ptr.neg37 = sub i32 0, %stride ; [#uses=1] + %tmp55 = add i32 %sub.ptr.neg37, -1 ; [#uses=1] + %tmp73 = add i32 %stride, -1 ; [#uses=2] + %sub.ptr38 = getelementptr i8* %src, i32 %tmp73 ; [#uses=1] + %tmp60 = load i8* %sub.ptr38 ; [#uses=1] + %conv61 = zext i8 %tmp60 to i32 ; [#uses=1] + %sub62 = sub i32 0, %conv61 ; [#uses=1] + %mul63 = mul i32 %sub62, 2 ; [#uses=1] + %add65 = add nsw i32 %mul63, 0 ; [#uses=1] + %tmp71.2 = mul i32 2, %stride ; [#uses=1] + %tmp72.2 = sub i32 0, %tmp71.2 ; [#uses=1] + %tmp74.2 = add i32 %tmp72.2, %tmp73 ; [#uses=1] + %sub.ptr38.2 = getelementptr i8* %src, i32 %tmp74.2 ; [#uses=1] + %tmp60.2 = load i8* %sub.ptr38.2 ; [#uses=1] + %conv61.2 = zext i8 %tmp60.2 to i32 ; [#uses=1] + %sub62.2 = sub i32 0, %conv61.2 ; [#uses=1] + %mul63.2 = mul i32 %sub62.2, 4 ; [#uses=1] + %add65.2 = add nsw i32 %mul63.2, %add65 ; [#uses=1] + %scevgep = getelementptr i8* %src, i32 %tmp55 ; [#uses=1] + br label %for.end + +for.end: ; preds = %for.cond.2, %entry + %V.0.lcssa = phi i32 [ %add65.2, %bb.nph41 ], [ 0, %entry ] ; [#uses=1] + %src2.0.lcssa = phi i8* [ %scevgep, %bb.nph41 ], [ null, %entry ] ; [#uses=1] + %mul71 = mul i32 %V.0.lcssa, 17 ; [#uses=1] + %add72 = add nsw i32 %mul71, 16 ; [#uses=1] + %shr73 = ashr i32 %add72, 5 ; [#uses=1] + br i1 true, label %bb.nph, label %for.end181 + +bb.nph: ; preds = %for.end + %arrayidx79 = getelementptr inbounds i8* %src2.0.lcssa, i32 8 ; [#uses=1] + %tmp80 = load i8* %arrayidx79 ; [#uses=1] + %tmp9 = mul i32 %shr73, -3 ; [#uses=1] + %tmp11 = zext i8 %tmp80 to i32 ; [#uses=1] + %tmp12 = add i32 0, %tmp11 ; [#uses=1] + %tmp13 = mul i32 %tmp12, 16 ; [#uses=1] + %tmp38 = add i32 %tmp9, %tmp13 ; [#uses=1] + %tmp39 = add i32 %tmp38, 16 ; [#uses=1] + br label %for.body94 + +for.body94: ; preds = %bb.nph, %for.cond90 + %add129 = add i32 0, %tmp39 ; [#uses=1] + %shr130 = ashr i32 %add129, 5 ; [#uses=1] + %.sum4 = add i32 %shr130, 1024 ; [#uses=1] + %arrayidx132 = getelementptr inbounds [2304 x i8]* @ff_cropTbl, i32 0, i32 %.sum4 ; [#uses=1] + %tmp133 = load i8* %arrayidx132 ; [#uses=1] + store i8 %tmp133, i8* undef + br label %for.body94 + +for.end181: ; preds = %for.cond90.for.end181_crit_edge, %for.end + ret void + +} From asl at math.spbu.ru Wed Dec 9 11:26:02 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Wed, 09 Dec 2009 17:26:02 -0000 Subject: [llvm-commits] [llvm] r90972 - /llvm/trunk/docs/GettingStarted.html Message-ID: <200912091726.nB9HQ2o7020286@zion.cs.uiuc.edu> Author: asl Date: Wed Dec 9 11:26:02 2009 New Revision: 90972 URL: http://llvm.org/viewvc/llvm-project?rev=90972&view=rev Log: Add note about loadable modules on windows. Patch by Gregory Petrosyan! Modified: llvm/trunk/docs/GettingStarted.html Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=90972&r1=90971&r2=90972&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Wed Dec 9 11:26:02 2009 @@ -252,7 +252,8 @@ Cygwin/Win32 - x861,8 + x861,8, + 11 GCC 3.4.X, binutils 2.15 @@ -331,6 +332,9 @@ before any Windows-based versions such as Strawberry Perl and ActivePerl, as these have Windows-specifics that will cause the build to fail. +
  • In general, LLVM modules requiring dynamic linking can + not be built on Windows. However, you can build LLVM tools using + "make tools-only".
  • From sabre at nondot.org Wed Dec 9 11:27:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 17:27:46 -0000 Subject: [llvm-commits] [llvm] r90973 - in /llvm/trunk: lib/Analysis/PHITransAddr.cpp test/Transforms/GVN/crash-2.ll Message-ID: <200912091727.nB9HRkWP020351@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 11:27:45 2009 New Revision: 90973 URL: http://llvm.org/viewvc/llvm-project?rev=90973&view=rev Log: Add a minor optimization: if we haven't changed the operands of an add, there is no need to scan the world to find the same add again. This invalidates the previous testcase, which wasn't wonderful anyway, because it needed a run of instcombine to permute the use-lists in just the right way to before GVN was run (so it was really fragile). Not a big loss. Removed: llvm/trunk/test/Transforms/GVN/crash-2.ll Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp Modified: llvm/trunk/lib/Analysis/PHITransAddr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PHITransAddr.cpp?rev=90973&r1=90972&r2=90973&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PHITransAddr.cpp (original) +++ llvm/trunk/lib/Analysis/PHITransAddr.cpp Wed Dec 9 11:27:45 2009 @@ -275,6 +275,10 @@ RemoveInstInputs(LHS, InstInputs); return AddAsInput(Res); } + + // If we didn't modify the add, just return it. + if (LHS == Inst->getOperand(0) && RHS == Inst->getOperand(1)) + return Inst; // Otherwise, see if we have this add available somewhere. for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); Removed: llvm/trunk/test/Transforms/GVN/crash-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/crash-2.ll?rev=90972&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/crash-2.ll (original) +++ llvm/trunk/test/Transforms/GVN/crash-2.ll (removed) @@ -1,66 +0,0 @@ -; RUN: opt -instcombine -gvn -S %s -; PR5733 -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" -target triple = "i686-linux-gnu" - - at ff_cropTbl = external global [2304 x i8] ; <[2304 x i8]*> [#uses=1] - -define void @ff_pred8x8_plane_c(i8* nocapture %src, i32 %stride) nounwind { -entry: - br i1 true, label %bb.nph41, label %for.end - - -bb.nph41: ; preds = %entry - %sub.ptr.neg37 = sub i32 0, %stride ; [#uses=1] - %tmp55 = add i32 %sub.ptr.neg37, -1 ; [#uses=1] - %tmp73 = add i32 %stride, -1 ; [#uses=2] - %sub.ptr38 = getelementptr i8* %src, i32 %tmp73 ; [#uses=1] - %tmp60 = load i8* %sub.ptr38 ; [#uses=1] - %conv61 = zext i8 %tmp60 to i32 ; [#uses=1] - %sub62 = sub i32 0, %conv61 ; [#uses=1] - %mul63 = mul i32 %sub62, 2 ; [#uses=1] - %add65 = add nsw i32 %mul63, 0 ; [#uses=1] - %tmp71.2 = mul i32 2, %stride ; [#uses=1] - %tmp72.2 = sub i32 0, %tmp71.2 ; [#uses=1] - %tmp74.2 = add i32 %tmp72.2, %tmp73 ; [#uses=1] - %sub.ptr38.2 = getelementptr i8* %src, i32 %tmp74.2 ; [#uses=1] - %tmp60.2 = load i8* %sub.ptr38.2 ; [#uses=1] - %conv61.2 = zext i8 %tmp60.2 to i32 ; [#uses=1] - %sub62.2 = sub i32 0, %conv61.2 ; [#uses=1] - %mul63.2 = mul i32 %sub62.2, 4 ; [#uses=1] - %add65.2 = add nsw i32 %mul63.2, %add65 ; [#uses=1] - %scevgep = getelementptr i8* %src, i32 %tmp55 ; [#uses=1] - br label %for.end - -for.end: ; preds = %for.cond.2, %entry - %V.0.lcssa = phi i32 [ %add65.2, %bb.nph41 ], [ 0, %entry ] ; [#uses=1] - %src2.0.lcssa = phi i8* [ %scevgep, %bb.nph41 ], [ null, %entry ] ; [#uses=1] - %mul71 = mul i32 %V.0.lcssa, 17 ; [#uses=1] - %add72 = add nsw i32 %mul71, 16 ; [#uses=1] - %shr73 = ashr i32 %add72, 5 ; [#uses=1] - br i1 true, label %bb.nph, label %for.end181 - -bb.nph: ; preds = %for.end - %arrayidx79 = getelementptr inbounds i8* %src2.0.lcssa, i32 8 ; [#uses=1] - %tmp80 = load i8* %arrayidx79 ; [#uses=1] - %tmp9 = mul i32 %shr73, -3 ; [#uses=1] - %tmp11 = zext i8 %tmp80 to i32 ; [#uses=1] - %tmp12 = add i32 0, %tmp11 ; [#uses=1] - %tmp13 = mul i32 %tmp12, 16 ; [#uses=1] - %tmp38 = add i32 %tmp9, %tmp13 ; [#uses=1] - %tmp39 = add i32 %tmp38, 16 ; [#uses=1] - br label %for.body94 - -for.body94: ; preds = %bb.nph, %for.cond90 - %add129 = add i32 0, %tmp39 ; [#uses=1] - %shr130 = ashr i32 %add129, 5 ; [#uses=1] - %.sum4 = add i32 %shr130, 1024 ; [#uses=1] - %arrayidx132 = getelementptr inbounds [2304 x i8]* @ff_cropTbl, i32 0, i32 %.sum4 ; [#uses=1] - %tmp133 = load i8* %arrayidx132 ; [#uses=1] - store i8 %tmp133, i8* undef - br label %for.body94 - -for.end181: ; preds = %for.cond90.for.end181_crit_edge, %for.end - ret void - -} From bob.wilson at apple.com Wed Dec 9 12:05:27 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 09 Dec 2009 18:05:27 -0000 Subject: [llvm-commits] [llvm] r90975 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200912091805.nB9I5R6a021681@zion.cs.uiuc.edu> Author: bwilson Date: Wed Dec 9 12:05:27 2009 New Revision: 90975 URL: http://llvm.org/viewvc/llvm-project?rev=90975&view=rev Log: Fix a comment. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=90975&r1=90974&r2=90975&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Dec 9 12:05:27 2009 @@ -1347,7 +1347,7 @@ } /// CanConvertToScalar - V is a pointer. If we can convert the pointee and all -/// its accesses to use a to single vector type, return true, and set VecTy to +/// its accesses to a single vector type, return true and set VecTy to /// the new type. If we could convert the alloca into a single promotable /// integer, return true but set VecTy to VoidTy. Further, if the use is not a /// completely trivial use that mem2reg could promote, set IsNotTrivial. Offset From sabre at nondot.org Wed Dec 9 12:13:28 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 18:13:28 -0000 Subject: [llvm-commits] [llvm] r90977 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200912091813.nB9IDS3s022128@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 12:13:28 2009 New Revision: 90977 URL: http://llvm.org/viewvc/llvm-project?rev=90977&view=rev Log: change GetStoreValueForLoad to use IRBuilder, which is cleaner and implicitly constant folds. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90977&r1=90976&r2=90977&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 12:13:28 2009 @@ -1151,14 +1151,15 @@ uint64_t StoreSize = TD.getTypeSizeInBits(SrcVal->getType())/8; uint64_t LoadSize = TD.getTypeSizeInBits(LoadTy)/8; + IRBuilder<> Builder(InsertPt->getParent(), InsertPt); // Compute which bits of the stored value are being used by the load. Convert // to an integer type to start with. if (isa(SrcVal->getType())) - SrcVal = new PtrToIntInst(SrcVal, TD.getIntPtrType(Ctx), "tmp", InsertPt); + SrcVal = Builder.CreatePtrToInt(SrcVal, TD.getIntPtrType(Ctx), "tmp"); if (!isa(SrcVal->getType())) - SrcVal = new BitCastInst(SrcVal, IntegerType::get(Ctx, StoreSize*8), - "tmp", InsertPt); + SrcVal = Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize*8), + "tmp"); // Shift the bits to the least significant depending on endianness. unsigned ShiftAmt; @@ -1168,12 +1169,11 @@ ShiftAmt = (StoreSize-LoadSize-Offset)*8; if (ShiftAmt) - SrcVal = BinaryOperator::CreateLShr(SrcVal, - ConstantInt::get(SrcVal->getType(), ShiftAmt), "tmp", InsertPt); + SrcVal = Builder.CreateLShr(SrcVal, ShiftAmt, "tmp"); if (LoadSize != StoreSize) - SrcVal = new TruncInst(SrcVal, IntegerType::get(Ctx, LoadSize*8), - "tmp", InsertPt); + SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize*8), + "tmp"); return CoerceAvailableValueToLoadType(SrcVal, LoadTy, InsertPt, TD); } From sabre at nondot.org Wed Dec 9 12:21:47 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 09 Dec 2009 18:21:47 -0000 Subject: [llvm-commits] [llvm] r90978 - in /llvm/trunk: lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/rle.ll Message-ID: <200912091821.nB9ILlfj022405@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 12:21:46 2009 New Revision: 90978 URL: http://llvm.org/viewvc/llvm-project?rev=90978&view=rev Log: fix hte last remaining known (by me) phi translation bug. When we reanalyze clobbers to forward pieces of large stores to small loads, we need to consider the properly phi translated pointer in the store block. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/test/Transforms/GVN/rle.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90978&r1=90977&r2=90978&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 12:21:46 2009 @@ -1384,15 +1384,19 @@ MemDepResult DepInfo = Deps[i].getResult(); if (DepInfo.isClobber()) { + // The address being loaded in this non-local block may not be the same as + // the pointer operand of the load if PHI translation occurs. Make sure + // to consider the right address. + Value *Address = Deps[i].getAddress(); + // If the dependence is to a store that writes to a superset of the bits // read by the load, we can extract the bits we need for the load from the // stored value. if (StoreInst *DepSI = dyn_cast(DepInfo.getInst())) { if (TD == 0) TD = getAnalysisIfAvailable(); - if (TD) { - int Offset = AnalyzeLoadFromClobberingStore(LI->getType(), - LI->getPointerOperand(), + if (TD && Address) { + int Offset = AnalyzeLoadFromClobberingStore(LI->getType(), Address, DepSI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, @@ -1408,9 +1412,8 @@ if (MemIntrinsic *DepMI = dyn_cast(DepInfo.getInst())) { if (TD == 0) TD = getAnalysisIfAvailable(); - if (TD) { - int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), - LI->getPointerOperand(), + if (TD && Address) { + int Offset = AnalyzeLoadFromClobberingMemInst(LI->getType(), Address, DepMI, *TD); if (Offset != -1) { ValuesPerBlock.push_back(AvailableValueInBlock::getMI(DepBB, DepMI, Modified: llvm/trunk/test/Transforms/GVN/rle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/rle.ll?rev=90978&r1=90977&r2=90978&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/rle.ll (original) +++ llvm/trunk/test/Transforms/GVN/rle.ll Wed Dec 9 12:21:46 2009 @@ -469,6 +469,9 @@ define i8 @phi_trans4(i8* %p) { ; CHECK: @phi_trans4 entry: + %X3 = getelementptr i8* %p, i32 192 + store i8 192, i8* %X3 + %X = getelementptr i8* %p, i32 4 %Y = load i8* %X br label %loop @@ -476,11 +479,15 @@ loop: %i = phi i32 [4, %entry], [192, %loop] %X2 = getelementptr i8* %p, i32 %i - %Y2 = load i8* %X + %Y2 = load i8* %X2 + +; CHECK: loop: +; CHECK-NEXT: %Y2 = phi i8 [ %Y, %entry ], [ 0, %loop ] +; CHECK-NOT: load i8 %cond = call i1 @cond2() - %Z = bitcast i8 *%X2 to i32* + %Z = bitcast i8 *%X3 to i32* store i32 0, i32* %Z br i1 %cond, label %loop, label %out @@ -492,6 +499,7 @@ define i8 @phi_trans5(i8* %p) { ; CHECK: @phi_trans5 entry: + %X4 = getelementptr i8* %p, i32 2 store i8 19, i8* %X4 @@ -502,8 +510,7 @@ loop: %i = phi i32 [4, %entry], [3, %cont] %X2 = getelementptr i8* %p, i32 %i - %Y2 = load i8* %X2 - ;; FIXME: This load is being incorrectly replaced! + %Y2 = load i8* %X2 ; Ensure this load is not being incorrectly replaced. %cond = call i1 @cond2() br i1 %cond, label %cont, label %out @@ -511,6 +518,11 @@ %Z = getelementptr i8* %X2, i32 -1 %Z2 = bitcast i8 *%Z to i32* store i32 50462976, i32* %Z2 ;; (1 << 8) | (2 << 16) | (3 << 24) + + +; CHECK: store i32 +; CHECK-NEXT: getelementptr i8* %p, i32 3 +; CHECK-NEXT: load i8* br label %loop out: From dpatel at apple.com Wed Dec 9 12:24:21 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 09 Dec 2009 18:24:21 -0000 Subject: [llvm-commits] [llvm] r90979 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200912091824.nB9IOLhR022483@zion.cs.uiuc.edu> Author: dpatel Date: Wed Dec 9 12:24:21 2009 New Revision: 90979 URL: http://llvm.org/viewvc/llvm-project?rev=90979&view=rev Log: Reapply r90858, a cleanup patch. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90979&r1=90978&r2=90979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Dec 9 12:24:21 2009 @@ -739,12 +739,12 @@ } /// addType - Add a new type attribute to the specified entity. -void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { +void DwarfDebug::addType(DIE *Entity, DIType Ty) { if (Ty.isNull()) return; // Check for pre-existence. - DIEEntry *Entry = DW_Unit->getDIEEntry(Ty.getNode()); + DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode()); // If it exists then use the existing value. if (Entry) { @@ -754,37 +754,36 @@ // Set up proxy. Entry = createDIEEntry(); - DW_Unit->insertDIEEntry(Ty.getNode(), Entry); + ModuleCU->insertDIEEntry(Ty.getNode(), Entry); // Construct type. DIE *Buffer = new DIE(dwarf::DW_TAG_base_type); ModuleCU->insertDIE(Ty.getNode(), Buffer); if (Ty.isBasicType()) - constructTypeDIE(DW_Unit, *Buffer, DIBasicType(Ty.getNode())); + constructTypeDIE(*Buffer, DIBasicType(Ty.getNode())); else if (Ty.isCompositeType()) - constructTypeDIE(DW_Unit, *Buffer, DICompositeType(Ty.getNode())); + constructTypeDIE(*Buffer, DICompositeType(Ty.getNode())); else { assert(Ty.isDerivedType() && "Unknown kind of DIType"); - constructTypeDIE(DW_Unit, *Buffer, DIDerivedType(Ty.getNode())); + constructTypeDIE(*Buffer, DIDerivedType(Ty.getNode())); } // Add debug information entry to entity and appropriate context. DIE *Die = NULL; DIDescriptor Context = Ty.getContext(); if (!Context.isNull()) - Die = DW_Unit->getDIE(Context.getNode()); + Die = ModuleCU->getDIE(Context.getNode()); if (Die) Die->addChild(Buffer); else - DW_Unit->addDie(Buffer); + ModuleCU->addDie(Buffer); Entry->setEntry(Buffer); Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); } /// constructTypeDIE - Construct basic type die from DIBasicType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DIBasicType BTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { // Get core information. StringRef Name = BTy.getName(); Buffer.setTag(dwarf::DW_TAG_base_type); @@ -799,8 +798,7 @@ } /// constructTypeDIE - Construct derived type die from DIDerivedType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DIDerivedType DTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { // Get core information. StringRef Name = DTy.getName(); uint64_t Size = DTy.getSizeInBits() >> 3; @@ -813,7 +811,7 @@ // Map to main type, void will not have a type. DIType FromTy = DTy.getTypeDerivedFrom(); - addType(DW_Unit, &Buffer, FromTy); + addType(&Buffer, FromTy); // Add name if not anonymous or intermediate type. if (!Name.empty()) @@ -829,8 +827,7 @@ } /// constructTypeDIE - Construct type DIE from DICompositeType. -void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, - DICompositeType CTy) { +void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { // Get core information. StringRef Name = CTy.getName(); @@ -841,7 +838,7 @@ switch (Tag) { case dwarf::DW_TAG_vector_type: case dwarf::DW_TAG_array_type: - constructArrayTypeDIE(DW_Unit, Buffer, &CTy); + constructArrayTypeDIE(Buffer, &CTy); break; case dwarf::DW_TAG_enumeration_type: { DIArray Elements = CTy.getTypeArray(); @@ -851,7 +848,7 @@ DIE *ElemDie = NULL; DIEnumerator Enum(Elements.getElement(i).getNode()); if (!Enum.isNull()) { - ElemDie = constructEnumTypeDIE(DW_Unit, &Enum); + ElemDie = constructEnumTypeDIE(&Enum); Buffer.addChild(ElemDie); } } @@ -861,7 +858,7 @@ // Add return type. DIArray Elements = CTy.getTypeArray(); DIDescriptor RTy = Elements.getElement(0); - addType(DW_Unit, &Buffer, DIType(RTy.getNode())); + addType(&Buffer, DIType(RTy.getNode())); // Add prototype flag. addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); @@ -870,7 +867,7 @@ for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); DIDescriptor Ty = Elements.getElement(i); - addType(DW_Unit, Arg, DIType(Ty.getNode())); + addType(Arg, DIType(Ty.getNode())); Buffer.addChild(Arg); } } @@ -892,11 +889,9 @@ continue; DIE *ElemDie = NULL; if (Element.getTag() == dwarf::DW_TAG_subprogram) - ElemDie = createMemberSubprogramDIE(DW_Unit, - DISubprogram(Element.getNode())); + ElemDie = createMemberSubprogramDIE(DISubprogram(Element.getNode())); else - ElemDie = createMemberDIE(DW_Unit, - DIDerivedType(Element.getNode())); + ElemDie = createMemberDIE(DIDerivedType(Element.getNode())); Buffer.addChild(ElemDie); } @@ -951,26 +946,26 @@ } /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. -void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, +void DwarfDebug::constructArrayTypeDIE(DIE &Buffer, DICompositeType *CTy) { Buffer.setTag(dwarf::DW_TAG_array_type); if (CTy->getTag() == dwarf::DW_TAG_vector_type) addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); // Emit derived type. - addType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom()); + addType(&Buffer, CTy->getTypeDerivedFrom()); DIArray Elements = CTy->getTypeArray(); // Get an anonymous type for index type. - DIE *IdxTy = DW_Unit->getIndexTyDie(); + DIE *IdxTy = ModuleCU->getIndexTyDie(); if (!IdxTy) { // Construct an anonymous type for index type. IdxTy = new DIE(dwarf::DW_TAG_base_type); addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, dwarf::DW_ATE_signed); - DW_Unit->addDie(IdxTy); - DW_Unit->setIndexTyDie(IdxTy); + ModuleCU->addDie(IdxTy); + ModuleCU->setIndexTyDie(IdxTy); } // Add subranges to array type. @@ -982,7 +977,7 @@ } /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. -DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) { +DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) { DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); StringRef Name = ETy->getName(); addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); @@ -992,8 +987,7 @@ } /// createGlobalVariableDIE - Create new DIE using GV. -DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit, - const DIGlobalVariable &GV) { +DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) { // If the global variable was optmized out then no need to create debug info // entry. if (!GV.getGlobal()) return NULL; @@ -1014,7 +1008,7 @@ addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, LinkageName); } - addType(DW_Unit, GVDie, GV.getType()); + addType(GVDie, GV.getType()); if (!GV.isLocalToUnit()) addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); addSourceLine(GVDie, &GV); @@ -1030,13 +1024,13 @@ } /// createMemberDIE - Create new member DIE. -DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){ +DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) { DIE *MemberDie = new DIE(DT.getTag()); StringRef Name = DT.getName(); if (!Name.empty()) addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - addType(DW_Unit, MemberDie, DT.getTypeDerivedFrom()); + addType(MemberDie, DT.getTypeDerivedFrom()); addSourceLine(MemberDie, &DT); @@ -1090,8 +1084,7 @@ /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. -DIE *DwarfDebug::createRawSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createRawSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram); addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); @@ -1120,9 +1113,9 @@ unsigned SPTag = SPTy.getTag(); if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type) - addType(DW_Unit, SPDie, SPTy); + addType(SPDie, SPTy); else - addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode())); + addType(SPDie, DIType(Args.getElement(0).getNode())); unsigned VK = SP.getVirtuality(); if (VK) { @@ -1139,11 +1132,10 @@ /// createMemberSubprogramDIE - Create new member DIE using SP. This routine /// always returns a die with DW_AT_declaration attribute. -DIE *DwarfDebug::createMemberSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createMemberSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (!SPDie) - SPDie = createSubprogramDIE(DW_Unit, SP); + SPDie = createSubprogramDIE(SP); // If SPDie has DW_AT_declaration then reuse it. if (!SP.isDefinition()) @@ -1154,7 +1146,7 @@ if (TopLevelDIEs.insert(SPDie)) TopLevelDIEsVector.push_back(SPDie); - SPDie = createRawSubprogramDIE(DW_Unit, SP); + SPDie = createRawSubprogramDIE(SP); // Add arguments. DICompositeType SPTy = SP.getType(); @@ -1163,7 +1155,7 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); + addType(Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } @@ -1173,13 +1165,12 @@ } /// createSubprogramDIE - Create new DIE using SP. -DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit, - const DISubprogram &SP) { +DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP) { DIE *SPDie = ModuleCU->getDIE(SP.getNode()); if (SPDie) return SPDie; - SPDie = createRawSubprogramDIE(DW_Unit, SP); + SPDie = createRawSubprogramDIE(SP); if (!SP.isDefinition()) { addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); @@ -1193,14 +1184,14 @@ if (SPTag == dwarf::DW_TAG_subroutine_type) for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); - addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode())); + addType(Arg, DIType(Args.getElement(i).getNode())); addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ?? SPDie->addChild(Arg); } } // DW_TAG_inlined_subroutine may refer to this DIE. - DW_Unit->insertDIE(SP.getNode(), SPDie); + ModuleCU->insertDIE(SP.getNode(), SPDie); return SPDie; } @@ -1213,64 +1204,6 @@ return *I->second; } -/// createDbgScopeVariable - Create a new scope variable. -/// -DIE *DwarfDebug::createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { - // Get the descriptor. - const DIVariable &VD = DV->getVariable(); - StringRef Name = VD.getName(); - if (Name.empty()) - return NULL; - - // Translate tag to proper Dwarf tag. The result variable is dropped for - // now. - unsigned Tag; - switch (VD.getTag()) { - case dwarf::DW_TAG_return_variable: - return NULL; - case dwarf::DW_TAG_arg_variable: - Tag = dwarf::DW_TAG_formal_parameter; - break; - case dwarf::DW_TAG_auto_variable: // fall thru - default: - Tag = dwarf::DW_TAG_variable; - break; - } - - // Define variable debug information entry. - DIE *VariableDie = new DIE(Tag); - addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - - // Add source line info if available. - addSourceLine(VariableDie, &VD); - - // Add variable type. - // FIXME: isBlockByrefVariable should be reformulated in terms of complex - // addresses instead. - if (VD.isBlockByrefVariable()) - addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); - else - addType(Unit, VariableDie, VD.getType()); - - // Add variable address. - // Variables for abstract instances of inlined functions don't get a - // location. - MachineLocation Location; - unsigned FrameReg; - int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); - Location.set(FrameReg, Offset); - - - if (VD.hasComplexAddress()) - addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else if (VD.isBlockByrefVariable()) - addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else - addAddress(VariableDie, dwarf::DW_AT_location, Location); - - return VariableDie; -} - /// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. /// Initialize scope and update scope hierarchy. DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, @@ -1376,7 +1309,7 @@ if (!N) continue; DIGlobalVariable GV(N); if (GV.getContext().getNode() == SPNode) { - DIE *ScopedGVDie = createGlobalVariableDIE(ModuleCU, GV); + DIE *ScopedGVDie = createGlobalVariableDIE(GV); if (ScopedGVDie) SPDie->addChild(ScopedGVDie); } @@ -1465,8 +1398,7 @@ /// constructVariableDIE - Construct a DIE for the given DbgVariable. -DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, - DbgScope *Scope, CompileUnit *Unit) { +DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { // Get the descriptor. const DIVariable &VD = DV->getVariable(); StringRef Name = VD.getName(); @@ -1515,9 +1447,9 @@ // FIXME: isBlockByrefVariable should be reformulated in terms of complex // addresses instead. if (VD.isBlockByrefVariable()) - addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name)); + addType(VariableDie, getBlockByrefType(VD.getType(), Name)); else - addType(Unit, VariableDie, VD.getType()); + addType(VariableDie, VD.getType()); } // Add variable address. @@ -1586,7 +1518,7 @@ // Add variables to scope. SmallVector &Variables = Scope->getVariables(); for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDIE = constructVariableDIE(Variables[i], Scope, ModuleCU); + DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); if (VariableDIE) ScopeDIE->addChild(VariableDIE); } @@ -1695,7 +1627,7 @@ if (ModuleCU->getDIE(DI_GV.getNode())) return; - DIE *VariableDie = createGlobalVariableDIE(ModuleCU, DI_GV); + DIE *VariableDie = createGlobalVariableDIE(DI_GV); // Add to map. ModuleCU->insertDIE(N, VariableDie); @@ -1728,7 +1660,7 @@ // class type. return; - DIE *SubprogramDie = createSubprogramDIE(ModuleCU, SP); + DIE *SubprogramDie = createSubprogramDIE(SP); // Add to map. ModuleCU->insertDIE(N, SubprogramDie); @@ -2419,13 +2351,16 @@ } } -/// emitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. +/// emitDebugInfo - Emit the debug info section. /// -void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) { - DIE *Die = Unit->getCUDie(); +void DwarfDebug::emitDebugInfo() { + // Start debug info section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfInfoSection()); + DIE *Die = ModuleCU->getCUDie(); // Emit the compile units header. - EmitLabel("info_begin", Unit->getID()); + EmitLabel("info_begin", ModuleCU->getID()); // Emit size of content not including length itself unsigned ContentSize = Die->getSize() + @@ -2446,17 +2381,10 @@ Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - EmitLabel("info_end", Unit->getID()); + EmitLabel("info_end", ModuleCU->getID()); Asm->EOL(); -} - -void DwarfDebug::emitDebugInfo() { - // Start debug info section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfInfoSection()); - emitDebugInfoPerCU(ModuleCU); } /// emitAbbreviations - Emit the abbreviation section. @@ -2754,24 +2682,30 @@ Asm->EOL(); } -void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) { - EmitDifference("pubnames_end", Unit->getID(), - "pubnames_begin", Unit->getID(), true); +/// emitDebugPubNames - Emit visible names into a debug pubnames section. +/// +void DwarfDebug::emitDebugPubNames() { + // Start the dwarf pubnames section. + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfPubNamesSection()); + + EmitDifference("pubnames_end", ModuleCU->getID(), + "pubnames_begin", ModuleCU->getID(), true); Asm->EOL("Length of Public Names Info"); - EmitLabel("pubnames_begin", Unit->getID()); + EmitLabel("pubnames_begin", ModuleCU->getID()); Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); EmitSectionOffset("info_begin", "section_info", - Unit->getID(), 0, true, false); + ModuleCU->getID(), 0, true, false); Asm->EOL("Offset of Compilation Unit Info"); - EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(), + EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), true); Asm->EOL("Compilation Unit Length"); - const StringMap &Globals = Unit->getGlobals(); + const StringMap &Globals = ModuleCU->getGlobals(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); @@ -2782,21 +2716,11 @@ } Asm->EmitInt32(0); Asm->EOL("End Mark"); - EmitLabel("pubnames_end", Unit->getID()); + EmitLabel("pubnames_end", ModuleCU->getID()); Asm->EOL(); } -/// emitDebugPubNames - Emit visible names into a debug pubnames section. -/// -void DwarfDebug::emitDebugPubNames() { - // Start the dwarf pubnames section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfPubNamesSection()); - - emitDebugPubNamesPerCU(ModuleCU); -} - void DwarfDebug::emitDebugPubTypes() { // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection( Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=90979&r1=90978&r2=90979&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Wed Dec 9 12:24:21 2009 @@ -314,60 +314,55 @@ const MachineLocation &Location); /// addType - Add a new type attribute to the specified entity. - void addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty); + void addType(DIE *Entity, DIType Ty); void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DIBasicType BTy); /// constructTypeDIE - Construct derived type die from DIDerivedType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DIDerivedType DTy); /// constructTypeDIE - Construct type DIE from DICompositeType. - void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructTypeDIE(DIE &Buffer, DICompositeType CTy); /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy); /// constructArrayTypeDIE - Construct array type DIE from DICompositeType. - void constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer, + void constructArrayTypeDIE(DIE &Buffer, DICompositeType *CTy); /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. - DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy); + DIE *constructEnumTypeDIE(DIEnumerator *ETy); /// createGlobalVariableDIE - Create new DIE using GV. - DIE *createGlobalVariableDIE(CompileUnit *DW_Unit, - const DIGlobalVariable &GV); + DIE *createGlobalVariableDIE(const DIGlobalVariable &GV); /// createMemberDIE - Create new member DIE. - DIE *createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT); + DIE *createMemberDIE(const DIDerivedType &DT); /// createSubprogramDIE - Create new DIE using SP. - DIE *createSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createSubprogramDIE(const DISubprogram &SP); /// createMemberSubprogramDIE - Create new member DIE using SP. This /// routine always returns a die with DW_AT_declaration attribute. - DIE *createMemberSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createMemberSubprogramDIE(const DISubprogram &SP); /// createRawSubprogramDIE - Create new partially incomplete DIE. This is /// a helper routine used by createMemberSubprogramDIE and /// createSubprogramDIE. - DIE *createRawSubprogramDIE(CompileUnit *DW_Unit, const DISubprogram &SP); + DIE *createRawSubprogramDIE(const DISubprogram &SP); /// findCompileUnit - Get the compile unit for the given descriptor. /// CompileUnit &findCompileUnit(DICompileUnit Unit) const; - /// createDbgScopeVariable - Create a new scope variable. - /// - DIE *createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit); - /// getUpdatedDbgScope - Find or create DbgScope assicated with /// the instruction. Initialize scope and update scope hierarchy. DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); @@ -397,7 +392,7 @@ DIE *constructInlinedScopeDIE(DbgScope *Scope); /// constructVariableDIE - Construct a DIE for the given DbgVariable. - DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit); + DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S); /// constructScopeDIE - Construct a DIE for this scope. DIE *constructScopeDIE(DbgScope *Scope); @@ -418,10 +413,8 @@ /// void computeSizeAndOffsets(); - /// EmitDebugInfo / emitDebugInfoPerCU - Emit the debug info section. + /// EmitDebugInfo - Emit the debug info section. /// - void emitDebugInfoPerCU(CompileUnit *Unit); - void emitDebugInfo(); /// emitAbbreviations - Emit the abbreviation section. @@ -445,8 +438,6 @@ /// section. void emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo); - void emitDebugPubNamesPerCU(CompileUnit *Unit); - /// emitDebugPubNames - Emit visible names into a debug pubnames section. /// void emitDebugPubNames(); From gohman at apple.com Wed Dec 9 12:48:54 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 09 Dec 2009 18:48:54 -0000 Subject: [llvm-commits] [llvm] r90980 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp Message-ID: <200912091848.nB9ImsUK023340@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 9 12:48:53 2009 New Revision: 90980 URL: http://llvm.org/viewvc/llvm-project?rev=90980&view=rev Log: Reuse the Threshold value to size these containers because it's currently somewhat convenient for them to have the same value. Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=90980&r1=90979&r2=90980&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Wed Dec 9 12:48:53 2009 @@ -45,8 +45,8 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures) { assert(isa(V->getType()) && "Capture is for pointers only!"); - SmallVector Worklist; - SmallSet Visited; + SmallVector Worklist; + SmallSet Visited; int Count = 0; for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end(); From gohman at apple.com Wed Dec 9 12:56:49 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 9 Dec 2009 10:56:49 -0800 Subject: [llvm-commits] [llvm] r90910 - /llvm/trunk/lib/Analysis/CaptureTracking.cpp In-Reply-To: <4B1F67D0.6000704@free.fr> References: <200912090028.nB90Sinv030745@zion.cs.uiuc.edu> <4B1F67D0.6000704@free.fr> Message-ID: <56A0B737-CB35-421A-9BD3-2D2EB8BBD8D5@apple.com> On Dec 9, 2009, at 1:03 AM, Duncan Sands wrote: > Hi Dan, > >> - SmallVector Worklist; >> - SmallSet Visited; >> + SmallVector Worklist; >> + SmallSet Visited; > > maybe better to use Threshold here rather than 20. Ok. Dan From baldrick at free.fr Wed Dec 9 13:54:40 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 09 Dec 2009 20:54:40 +0100 Subject: [llvm-commits] [PATCH] fix compiling llvm-gcc against installed llvm, tested with rev 89457 In-Reply-To: References: <825CF204-986A-492F-8AE9-4B5B0473CF3E@tut.fi> Message-ID: <4B200080.4060608@free.fr> > So, someone from Apple should confirm that this is ok as well. Since no-one has, how about applying it and seeing if it breaks anything? Ciao, Duncan. From evan.cheng at apple.com Wed Dec 9 15:00:30 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 21:00:30 -0000 Subject: [llvm-commits] [llvm] r90984 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/splat-scalar-load.ll Message-ID: <200912092100.nB9L0VR1027926@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 9 15:00:30 2009 New Revision: 90984 URL: http://llvm.org/viewvc/llvm-project?rev=90984&view=rev Log: Optimize splat of a scalar load into a shuffle of a vector load when it's legal. e.g. vector_shuffle (scalar_to_vector (i32 load (ptr + 4))), undef, <0, 0, 0, 0> => vector_shuffle (v4i32 load ptr), undef, <1, 1, 1, 1> iff ptr is 16-byte aligned (or can be made into 16-byte aligned). Added: llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=90984&r1=90983&r2=90984&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 9 15:00:30 2009 @@ -3344,6 +3344,82 @@ } SDValue +X86TargetLowering::LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl, + SelectionDAG &DAG) { + + // Check if the scalar load can be widened into a vector load. And if + // the address is "base + cst" see if the cst can be "absorbed" into + // the shuffle mask. + if (LoadSDNode *LD = dyn_cast(SrcOp)) { + SDValue Ptr = LD->getBasePtr(); + if (!ISD::isNormalLoad(LD) || LD->isVolatile()) + return SDValue(); + EVT PVT = LD->getValueType(0); + if (PVT != MVT::i32 && PVT != MVT::f32) + return SDValue(); + + int FI = -1; + int64_t Offset = 0; + if (FrameIndexSDNode *FINode = dyn_cast(Ptr)) { + FI = FINode->getIndex(); + Offset = 0; + } else if (Ptr.getOpcode() == ISD::ADD && + isa(Ptr.getOperand(1)) && + isa(Ptr.getOperand(0))) { + FI = cast(Ptr.getOperand(0))->getIndex(); + Offset = Ptr.getConstantOperandVal(1); + Ptr = Ptr.getOperand(0); + } else { + return SDValue(); + } + + SDValue Chain = LD->getChain(); + // Make sure the stack object alignment is at least 16. + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + if (DAG.InferPtrAlignment(Ptr) < 16) { + if (MFI->isFixedObjectIndex(FI)) { + // Can't change the alignment. Reference stack + offset explicitly + // if stack pointer is at least 16-byte aligned. + unsigned StackAlign = Subtarget->getStackAlignment(); + if (StackAlign < 16) + return SDValue(); + Offset = MFI->getObjectOffset(FI) + Offset; + SDValue StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr, + getPointerTy()); + Ptr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, + DAG.getConstant(Offset & ~15, getPointerTy())); + Offset %= 16; + } else { + MFI->setObjectAlignment(FI, 16); + } + } + + // (Offset % 16) must be multiple of 4. Then address is then + // Ptr + (Offset & ~15). + if (Offset < 0) + return SDValue(); + if ((Offset % 16) & 3) + return SDValue(); + int64_t StartOffset = Offset & ~15; + if (StartOffset) + Ptr = DAG.getNode(ISD::ADD, Ptr.getDebugLoc(), Ptr.getValueType(), + Ptr,DAG.getConstant(StartOffset, Ptr.getValueType())); + + int EltNo = (Offset - StartOffset) >> 2; + int Mask[4] = { EltNo, EltNo, EltNo, EltNo }; + EVT VT = (PVT == MVT::i32) ? MVT::v4i32 : MVT::v4f32; + SDValue V1 = DAG.getLoad(VT, dl, Chain, Ptr,LD->getSrcValue(),0); + // Canonicalize it to a v4i32 shuffle. + V1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, V1); + return DAG.getNode(ISD::BIT_CONVERT, dl, VT, + DAG.getVectorShuffle(MVT::v4i32, dl, V1, + DAG.getUNDEF(MVT::v4i32), &Mask[0])); + } + + return SDValue(); +} + +SDValue X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); // All zero's are handled with pxor, all one's are handled with pcmpeqd. @@ -3486,8 +3562,19 @@ } // Splat is obviously ok. Let legalizer expand it to a shuffle. - if (Values.size() == 1) + if (Values.size() == 1) { + if (EVTBits == 32) { + // Instead of a shuffle like this: + // shuffle (scalar_to_vector (load (ptr + 4))), undef, <0, 0, 0, 0> + // Check if it's possible to issue this instead. + // shuffle (vload ptr)), undef, <1, 1, 1, 1> + unsigned Idx = CountTrailingZeros_32(NonZeros); + SDValue Item = Op.getOperand(Idx); + if (Op.getNode()->isOnlyUserOf(Item.getNode())) + return LowerAsSplatVectorLoad(Item, VT, dl, DAG); + } return SDValue(); + } // A vector full of immediates; various special cases are already // handled, so this is best done with a single constant-pool load. @@ -4278,7 +4365,7 @@ unsigned ShAmt = 0; SDValue ShVal; bool isShift = getSubtarget()->hasSSE2() && - isVectorShift(SVOp, DAG, isLeft, ShVal, ShAmt); + isVectorShift(SVOp, DAG, isLeft, ShVal, ShAmt); if (isShift && ShVal.hasOneUse()) { // If the shifted value has multiple uses, it may be cheaper to use // v_set0 + movlhps or movhlps, etc. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=90984&r1=90983&r2=90984&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Dec 9 15:00:30 2009 @@ -626,7 +626,9 @@ std::pair FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool isSigned); - + + SDValue LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl, + SelectionDAG &DAG); SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG); SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG); SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=90984&r1=90983&r2=90984&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Dec 9 15:00:30 2009 @@ -2083,7 +2083,7 @@ (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2), "pshufd\t{$src2, $src1, $dst|$dst, $src1, $src2}", [(set VR128:$dst, (v4i32 (pshufd:$src2 - (bc_v4i32(memopv2i64 addr:$src1)), + (bc_v4i32 (memopv2i64 addr:$src1)), (undef))))]>; } Added: llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll?rev=90984&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll (added) +++ llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll Wed Dec 9 15:00:30 2009 @@ -0,0 +1,43 @@ +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; rdar://7434544 + +define <2 x i64> @t1() nounwind ssp { +entry: +; CHECK: t1: +; CHECK: pshufd $0, (%esp), %xmm0 + %array = alloca [8 x float], align 16 + %arrayidx = getelementptr inbounds [8 x float]* %array, i32 0, i32 0 + %tmp2 = load float* %arrayidx + %vecinit = insertelement <4 x float> undef, float %tmp2, i32 0 + %vecinit5 = insertelement <4 x float> %vecinit, float %tmp2, i32 1 + %vecinit7 = insertelement <4 x float> %vecinit5, float %tmp2, i32 2 + %vecinit9 = insertelement <4 x float> %vecinit7, float %tmp2, i32 3 + %0 = bitcast <4 x float> %vecinit9 to <2 x i64> + ret <2 x i64> %0 +} + +define <2 x i64> @t2() nounwind ssp { +entry: +; CHECK: t2: +; CHECK: pshufd $85, (%esp), %xmm0 + %array = alloca [8 x float], align 4 + %arrayidx = getelementptr inbounds [8 x float]* %array, i32 0, i32 1 + %tmp2 = load float* %arrayidx + %vecinit = insertelement <4 x float> undef, float %tmp2, i32 0 + %vecinit5 = insertelement <4 x float> %vecinit, float %tmp2, i32 1 + %vecinit7 = insertelement <4 x float> %vecinit5, float %tmp2, i32 2 + %vecinit9 = insertelement <4 x float> %vecinit7, float %tmp2, i32 3 + %0 = bitcast <4 x float> %vecinit9 to <2 x i64> + ret <2 x i64> %0 +} + +define <4 x float> @t3(float %tmp1, float %tmp2, float %tmp3) nounwind readnone ssp { +entry: +; CHECK: t3: +; CHECK: pshufd $-86, (%esp), %xmm0 + %0 = insertelement <4 x float> undef, float %tmp3, i32 0 + %1 = insertelement <4 x float> %0, float %tmp3, i32 1 + %2 = insertelement <4 x float> %1, float %tmp3, i32 2 + %3 = insertelement <4 x float> %2, float %tmp3, i32 3 + ret <4 x float> %3 +} From evan.cheng at apple.com Wed Dec 9 16:24:42 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 09 Dec 2009 22:24:42 -0000 Subject: [llvm-commits] [llvm] r90988 - /llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll Message-ID: <200912092224.nB9MOgJd030828@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 9 16:24:42 2009 New Revision: 90988 URL: http://llvm.org/viewvc/llvm-project?rev=90988&view=rev Log: Fix test. Modified: llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll Modified: llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll?rev=90988&r1=90987&r2=90988&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll (original) +++ llvm/trunk/test/CodeGen/X86/splat-scalar-load.ll Wed Dec 9 16:24:42 2009 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+sse2 | FileCheck %s ; rdar://7434544 define <2 x i64> @t1() nounwind ssp { From gohman at apple.com Wed Dec 9 16:55:02 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 09 Dec 2009 22:55:02 -0000 Subject: [llvm-commits] [llvm] r90990 - /llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Message-ID: <200912092255.nB9Mt2RK032154@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 9 16:55:01 2009 New Revision: 90990 URL: http://llvm.org/viewvc/llvm-project?rev=90990&view=rev Log: Dereference loopHeader after checking for null rather than before. Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=90990&r1=90989&r2=90990&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Wed Dec 9 16:55:01 2009 @@ -404,12 +404,13 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val){ initLoopData(); - Function *F = loopHeader->getParent(); // If LoopSimplify was unable to form a preheader, don't do any unswitching. if (!loopPreheader) return false; + Function *F = loopHeader->getParent(); + // If the condition is trivial, always unswitch. There is no code growth for // this case. if (!IsTrivialUnswitchCondition(LoopCond)) { From daniel at zuster.org Wed Dec 9 17:14:22 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 9 Dec 2009 15:14:22 -0800 Subject: [llvm-commits] [PATCH] Add RunToolSafely.sh Message-ID: <6a8523d60912091514n7132c022n7357297e4bc935a0@mail.gmail.com> The attached patch adds a RunToolSafely.sh which is used to make sure we still get nightly test results when tools like llvm-gcc, llc, opt, etc. crash. It also runs them under ulimit to protect against infinite loops. WFM, but sending in case someone else can think of potential problems. - Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Add-RunToolSafely.sh-and-use-it-when-running-LLVM-t.patch Type: application/octet-stream Size: 10205 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091209/559aae64/attachment.obj From clattner at apple.com Wed Dec 9 17:29:48 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Dec 2009 15:29:48 -0800 Subject: [llvm-commits] [PATCH] Add RunToolSafely.sh In-Reply-To: <6a8523d60912091514n7132c022n7357297e4bc935a0@mail.gmail.com> References: <6a8523d60912091514n7132c022n7357297e4bc935a0@mail.gmail.com> Message-ID: looks reasonable to me, -Chris On Dec 9, 2009, at 3:14 PM, Daniel Dunbar wrote: > The attached patch adds a RunToolSafely.sh which is used to make sure > we still get nightly test results when tools like llvm-gcc, llc, opt, > etc. crash. It also runs them under ulimit to protect against infinite > loops. > > WFM, but sending in case someone else can think of potential problems. > > - Daniel > <0001-Add-RunToolSafely.sh-and-use-it-when-running-LLVM-t.patch> From sabre at nondot.org Wed Dec 9 18:04:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Dec 2009 00:04:46 -0000 Subject: [llvm-commits] [llvm] r90999 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200912100004.nBA04k1R002382@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 18:04:46 2009 New Revision: 90999 URL: http://llvm.org/viewvc/llvm-project?rev=90999&view=rev Log: allow this to build when the #if 0's are enabled. No functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=90999&r1=90998&r2=90999&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 18:04:46 2009 @@ -1023,8 +1023,7 @@ << "Base = " << *StoreBase << "\n" << "Store Ptr = " << *WritePtr << "\n" << "Store Offs = " << StoreOffset << "\n" - << "Load Ptr = " << *LoadPtr << "\n" - << "Load Offs = " << LoadOffset << " - " << *L << "\n\n"; + << "Load Ptr = " << *LoadPtr << "\n"; abort(); #endif return -1; @@ -1055,10 +1054,7 @@ << "Base = " << *StoreBase << "\n" << "Store Ptr = " << *WritePtr << "\n" << "Store Offs = " << StoreOffset << "\n" - << "Load Ptr = " << *L->getPointerOperand() << "\n" - << "Load Offs = " << LoadOffset << " - " << *L << "\n\n"; - errs() << "'" << L->getParent()->getParent()->getName() << "'" - << *L->getParent(); + << "Load Ptr = " << *LoadPtr << "\n"; abort(); #endif return -1; From grosbach at apple.com Wed Dec 9 18:11:09 2009 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 10 Dec 2009 00:11:09 -0000 Subject: [llvm-commits] [llvm] r91003 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h ARMInstrInfo.td Message-ID: <200912100011.nBA0B9e8002663@zion.cs.uiuc.edu> Author: grosbach Date: Wed Dec 9 18:11:09 2009 New Revision: 91003 URL: http://llvm.org/viewvc/llvm-project?rev=91003&view=rev Log: Add memory barrier intrinsic support for ARM. Moving towards adding the atomic operations intrinsics. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=91003&r1=91002&r2=91003&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Dec 9 18:11:09 2009 @@ -377,7 +377,7 @@ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); else setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); - setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); + setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); if (!Subtarget->hasV6Ops() && !Subtarget->isThumb2()) { setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); @@ -500,6 +500,9 @@ case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC"; + case ARMISD::MEMBARRIER: return "ARMISD::MEMBARRIER"; + case ARMISD::SYNCBARRIER: return "ARMISD::SYNCBARRIER"; + case ARMISD::VCEQ: return "ARMISD::VCEQ"; case ARMISD::VCGE: return "ARMISD::VCGE"; case ARMISD::VCGEU: return "ARMISD::VCGEU"; @@ -1470,6 +1473,21 @@ } } +static SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG &DAG) { + DebugLoc dl = Op.getDebugLoc(); + SDValue Op5 = Op.getOperand(5); + SDValue Res; + unsigned isDeviceBarrier = cast(Op5)->getZExtValue(); + if (isDeviceBarrier) { + Res = DAG.getNode(ARMISD::SYNCBARRIER, dl, MVT::Other, + Op.getOperand(0)); + } else { + Res = DAG.getNode(ARMISD::MEMBARRIER, dl, MVT::Other, + Op.getOperand(0)); + } + return Res; +} + static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, unsigned VarArgsFrameIndex) { // vastart just stores the address of the VarArgsFrameIndex slot into the @@ -2972,6 +2990,7 @@ case ISD::BR_JT: return LowerBR_JT(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); + case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG); case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); case ISD::FP_TO_SINT: Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=91003&r1=91002&r2=91003&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed Dec 9 18:11:09 2009 @@ -72,6 +72,9 @@ DYN_ALLOC, // Dynamic allocation on the stack. + MEMBARRIER, // Memory barrier + SYNCBARRIER, // Memory sync barrier + VCEQ, // Vector compare equal. VCGE, // Vector compare greater than or equal. VCGEU, // Vector compare unsigned greater than or equal. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91003&r1=91002&r2=91003&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Dec 9 18:11:09 2009 @@ -46,6 +46,9 @@ def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>; +def SDT_ARMMEMBARRIER : SDTypeProfile<0, 0, []>; +def SDT_ARMSYNCBARRIER : SDTypeProfile<0, 0, []>; + // Node definitions. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; @@ -93,6 +96,11 @@ def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>; +def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, + [SDNPHasChain]>; +def ARMSyncBarrier : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIER, + [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // ARM Instruction Predicate Definitions. // @@ -1561,6 +1569,24 @@ let Inst{25} = 1; } +//===----------------------------------------------------------------------===// +// Atomic operations intrinsics +// + +// memory barriers protect the atomic sequences +let isBarrier = 1 in { +def Int_MemBarrierV7 : AI<(outs), (ins), + Pseudo, NoItinerary, + "dmb", "", + [(ARMMemBarrier)]>, + Requires<[HasV7]>; + +def Int_SyncBarrierV7 : AI<(outs), (ins), + Pseudo, NoItinerary, + "dsb", "", + [(ARMSyncBarrier)]>, + Requires<[HasV7]>; +} //===----------------------------------------------------------------------===// // TLS Instructions From sabre at nondot.org Wed Dec 9 18:11:45 2009 From: sabre at nondot.org (Chris Lattner) Date: Thu, 10 Dec 2009 00:11:45 -0000 Subject: [llvm-commits] [llvm] r91004 - in /llvm/trunk: lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/crash-no-aa.ll Message-ID: <200912100011.nBA0BjAs002692@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 9 18:11:45 2009 New Revision: 91004 URL: http://llvm.org/viewvc/llvm-project?rev=91004&view=rev Log: Fix PR5744, a case where we were getting the pointer size instead of the value size. This only manifested when memdep inprecisely returns clobber, which is do to a caching issue in the PR5744 testcase. We can 'efficiently emulate' this by using '-no-aa' Added: llvm/trunk/test/Transforms/GVN/crash-no-aa.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=91004&r1=91003&r2=91004&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Dec 9 18:11:45 2009 @@ -1084,7 +1084,7 @@ return -1; Value *StorePtr = DepSI->getPointerOperand(); - uint64_t StoreSize = TD.getTypeSizeInBits(StorePtr->getType()); + uint64_t StoreSize = TD.getTypeSizeInBits(DepSI->getOperand(0)->getType()); return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr, StorePtr, StoreSize, TD); } Added: llvm/trunk/test/Transforms/GVN/crash-no-aa.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/crash-no-aa.ll?rev=91004&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/crash-no-aa.ll (added) +++ llvm/trunk/test/Transforms/GVN/crash-no-aa.ll Wed Dec 9 18:11:45 2009 @@ -0,0 +1,16 @@ +; RUN: opt -no-aa -gvn -S %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v1 +28:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-freebsd8.0" + +; PR5744 +define i32 @test1({i16, i32} *%P) { + %P2 = getelementptr {i16, i32} *%P, i32 0, i32 0 + store i16 42, i16* %P2 + + %P3 = getelementptr {i16, i32} *%P, i32 0, i32 1 + %V = load i32* %P3 + ret i32 %V +} + From echristo at apple.com Wed Dec 9 18:25:41 2009 From: echristo at apple.com (Eric Christopher) Date: Thu, 10 Dec 2009 00:25:41 -0000 Subject: [llvm-commits] [llvm] r91009 - /llvm/trunk/lib/Transforms/Scalar/LICM.cpp Message-ID: <200912100025.nBA0PfvH003424@zion.cs.uiuc.edu> Author: echristo Date: Wed Dec 9 18:25:41 2009 New Revision: 91009 URL: http://llvm.org/viewvc/llvm-project?rev=91009&view=rev Log: Make sure the immediate dominator isn't NULL through iterations of the loop. We could get to this condition via indirect branches. Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=91009&r1=91008&r2=91009&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Wed Dec 9 18:25:41 2009 @@ -160,16 +160,17 @@ // Because the exit block is not in the loop, we know we have to get _at // least_ its immediate dominator. - do { - // Get next Immediate Dominator. - IDom = IDom->getIDom(); - + IDom = IDom->getIDom(); + + while (IDom && IDom != BlockInLoopNode) { // If we have got to the header of the loop, then the instructions block // did not dominate the exit node, so we can't hoist it. if (IDom->getBlock() == LoopHeader) return false; - } while (IDom != BlockInLoopNode); + // Get next Immediate Dominator. + IDom = IDom->getIDom(); + }; return true; } From daniel at zuster.org Wed Dec 9 18:30:03 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 00:30:03 -0000 Subject: [llvm-commits] [test-suite] r91011 - in /test-suite/trunk: Makefile.programs Makefile.tests RunToolSafely.sh Message-ID: <200912100030.nBA0U3Ua003564@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 18:30:03 2009 New Revision: 91011 URL: http://llvm.org/viewvc/llvm-project?rev=91011&view=rev Log: Add RunToolSafely.sh, and use it when running LLVM-tools-under-test. This helps preserve test suite results when the tools fail or crash, and protects us against infinite looping processes. Added: test-suite/trunk/RunToolSafely.sh (with props) Modified: test-suite/trunk/Makefile.programs test-suite/trunk/Makefile.tests Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91011&r1=91010&r2=91011&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 9 18:30:03 2009 @@ -107,6 +107,8 @@ endif endif +RUNTOOLSAFELY := $(PROGDIR)/RunToolSafely.sh $(RUNTIMELIMIT) + ifndef STDIN_FILENAME STDIN_FILENAME := /dev/null endif @@ -264,16 +266,16 @@ $(PROGRAMS_TO_TEST:%=Output/%.linked.bc): \ Output/%.linked.bc: Output/%.linked.rbc $(LOPT) $(VERB) $(RM) -f $(CURDIR)/$@.info - -$(LOPT) -std-compile-opts -info-output-file=$(CURDIR)/$@.info $(STATS) $(EXTRA_LOPT_OPTIONS) $< -o $@ + $(RUNTOOLSAFELY) $(LOPT) -std-compile-opts -info-output-file=$(CURDIR)/$@.info $(STATS) $(EXTRA_LOPT_OPTIONS) $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.llvm.stripped.bc): \ Output/%.llvm.stripped.bc: Output/%.llvm.bc $(LOPT) - -$(LOPT) -mstrip $< -o $@ + $(RUNTOOLSAFELY) $(LOPT) -mstrip $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.linked.optbeta.bc): \ Output/%.linked.optbeta.bc: Output/%.linked.rbc $(LOPT) $(VERB) $(RM) -f $(CURDIR)/$@.info - -$(LOPT) $(OPTBETAOPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) $< -o $@ + $(RUNTOOLSAFELY) $(LOPT) $(OPTBETAOPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) $< -o $@ ifndef DISABLE_FOR_LLVM_PROGRAMS @@ -283,51 +285,51 @@ $(PROGRAMS_TO_TEST:%=Output/%.llvm.bc): \ Output/%.llvm.bc: Output/%.linked.bc $(LLVM_LDDPROG) - -$(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(EXTRA_LINKTIME_OPT_FLAGS) $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.llvm ifneq ($(OPTPASSES),) - -$(LOPT) -q $(OPTPASSES) $@ -o $@.tmp + $(RUNTOOLSAFELY) $(LOPT) -q $(OPTPASSES) $@ -o $@.tmp $(MV) -f $@.tmp $@ endif $(PROGRAMS_TO_TEST:%=Output/%.llvm): \ Output/%.llvm: Output/%.linked.bc $(LLVMLDPROG) - -$(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(EXTRA_LINKTIME_OPT_FLAGS) $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.llvm ifneq ($(OPTPASSES),) - -$(LOPT) -q $(OPTPASSES) $@ -o $@.tmp + $(RUNTOOLSAFELY) $(LOPT) -q $(OPTPASSES) $@ -o $@.tmp $(MV) -f $@.tmp $@ endif $(PROGRAMS_TO_TEST:%=Output/%.llvm.optbeta.bc): \ Output/%.llvm.optbeta.bc: Output/%.linked.optbeta.bc $(LLVMLDPROG) - -$(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(EXTRA_LINKTIME_OPT_FLAGS) $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.llvm.optbeta $(PROGRAMS_TO_TEST:%=Output/%.llvm.optbeta): \ Output/%.llvm.optbeta: Output/%.linked.optbeta.bc $(LLVMLDPROG) - -$(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(EXTRA_LINKTIME_OPT_FLAGS) $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.llvm.optbeta $(PROGRAMS_TO_TEST:%=Output/%.noopt-llvm.bc): \ Output/%.noopt-llvm.bc: Output/%.linked.rbc $(LLVMLDPROG) - -$(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.noopt-llvm $(PROGRAMS_TO_TEST:%=Output/%.noopt-llvm): \ Output/%.noopt-llvm: Output/%.linked.rbc $(LLVMLDPROG) - -$(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.noopt-llvm $(PROGRAMS_TO_TEST:%=Output/%.nollvm-ldopt-llvm.bc): \ Output/%.nollvm-ldopt-llvm.bc: Output/%.linked.bc $(LLVMLDPROG) - -$(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.nollvm-ldopt-llvm $(PROGRAMS_TO_TEST:%=Output/%.nollvm-ldopt-llvm): \ Output/%.nollvm-ldopt-llvm: Output/%.linked.rbc $(LLVMLDPROG) - -$(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ + $(RUNTOOLSAFELY) $(LLVMLD) -disable-opt -info-output-file=$(CURDIR)/$@.info $(STATS) $< \ $(LLVMLD_FLAGS) -lc $(LIBS) -o Output/$*.nollvm-ldopt-llvm endif # ifndef DISABLE_FOR_LLVM_PROGRAMS @@ -379,7 +381,7 @@ # $(PROGRAMS_TO_TEST:%=Output/%.cbe.c): \ Output/%.cbe.c: Output/%.llvm.bc $(LLC) - -$(LLC) $(LLCFLAGS) -march=c $< -o $@ + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) -march=c $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ Output/%.cbe: Output/%.cbe.c @@ -390,15 +392,15 @@ # $(PROGRAMS_TO_TEST:%=Output/%.llc.s): \ Output/%.llc.s: Output/%.llvm.bc $(LLC) - -$(LLC) $(LLCFLAGS) $< -o $@ + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.llc-beta.s): \ Output/%.llc-beta.s: Output/%.llvm.bc $(LLC) - -$(LLC) $(LLCFLAGS) $(LLCBETAOPTION) $< -o $@ + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $(LLCBETAOPTION) $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.opt-beta.s): \ Output/%.opt-beta.s: Output/%.llvm.optbeta.bc $(LLC) - -$(LLC) $(LLCFLAGS) $< -o $@ + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ # On darwin, pass -force_cpusubtype_ALL to allow all ppc instructions. ifeq ($(ARCH),PowerPC) @@ -612,11 +614,11 @@ # $(PROGRAMS_TO_TEST:%=Output/%.llvm-prof.bc): \ Output/%.llvm-prof.bc: Output/%.llvm.bc - $(LOPT) -insert-edge-profiling $< -o $@ + $(RUNTOOLSAFELY) $(LOPT) -insert-edge-profiling $< -o $@ $(PROGRAMS_TO_TEST:%=Output/%.printprof): \ Output/%.printprof: Output/%.llvm.bc Output/%.prof $(LPROF) - $(LPROF) $< Output/$*.prof + $(RUNTOOLSAFELY) $(LPROF) $< Output/$*.prof # Modified: test-suite/trunk/Makefile.tests URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.tests?rev=91011&r1=91010&r2=91011&view=diff ============================================================================== --- test-suite/trunk/Makefile.tests (original) +++ test-suite/trunk/Makefile.tests Wed Dec 9 18:30:03 2009 @@ -39,27 +39,27 @@ # Compile from X.c to Output/X.bc Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) - $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cpp to Output/X.bc Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cc to Output/X.bc Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.C to Output/X.bc Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.m to Output/X.bc Output/%.bc: %.m $(LCC1) Output/.dir $(INCLUDES) - $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.mm to Output/X.bc Output/%.bc: %.mm $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # LLVM Assemble from X.ll to Output/X.bc. Because we are coming directly from # LLVM source, use the non-transforming assembler. Added: test-suite/trunk/RunToolSafely.sh URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/RunToolSafely.sh?rev=91011&view=auto ============================================================================== --- test-suite/trunk/RunToolSafely.sh (added) +++ test-suite/trunk/RunToolSafely.sh Wed Dec 9 18:30:03 2009 @@ -0,0 +1,53 @@ +#!/bin/sh + +set -eu + +if [ $# -lt 2 ]; then + echo "usage: $0 " + echo + echo " This script simply runs another program under ulimit and always" + echo " returns true. It is used for invoking tools from the LLVM test suite" + echo " Makefiles, where we need them to always return true so that we don't" + echo " abort the test run." + exit 1 +fi + +# Save a copy of the original arguments in a string before we +# clobber them with the shift command. +TIMEOUT=$1 +shift +PROGRAM=$1 +shift + +SYSTEM=`uname -s` + +ULIMITCMD="" +case $SYSTEM in + CYGWIN*) + ;; + Darwin*) + # Disable core file emission, the script doesn't find it anyway because it + # is put into /cores. + ULIMITCMD="$ULIMITCMD ulimit -c 0;" + ULIMITCMD="$ULIMITCMD ulimit -t $TIMEOUT;" + # To prevent infinite loops which fill up the disk, specify a limit on size + # of files being output by the tests. 10 MB should be enough for anybody. ;) + ULIMITCMD="$ULIMITCMD ulimit -f 10485760;" + ;; + *) + ULIMITCMD="$ULIMITCMD ulimit -t $TIMEOUT;" + ULIMITCMD="$ULIMITCMD ulimit -c unlimited;" + # To prevent infinite loops which fill up the disk, specify a limit on size + # of files being output by the tests. 10 MB should be enough for anybody. ;) + ULIMITCMD="$ULIMITCMD ulimit -f 10485760;" + + # virtual memory: 300 MB should be enough for anybody. ;) + ULIMITCMD="$ULIMITCMD ulimit -v 300000;" +esac + +if ( ! sh -c "$ULIMITCMD sh -c '$PROGRAM $*'" ); then + echo "warning: command failed: '$PROGRAM $*'" +fi + +# Always return "successful" so that tests will continue to be run. +exit 0 Propchange: test-suite/trunk/RunToolSafely.sh ------------------------------------------------------------------------------ svn:executable = * From daniel at zuster.org Wed Dec 9 18:30:10 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 00:30:10 -0000 Subject: [llvm-commits] [test-suite] r91013 - in /test-suite/trunk: Makefile.programs TEST.nightly.Makefile TEST.nightly2.Makefile Message-ID: <200912100030.nBA0UA9M003595@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 18:30:10 2009 New Revision: 91013 URL: http://llvm.org/viewvc/llvm-project?rev=91013&view=rev Log: Fix llc and lli to always produce .info files. - This is analogous to what we do for opt, and means we don't need to run LLC twice in a nightlytest. This makes a nightlytest run 10% faster! - This also eliminates the dynamic-variable-substitution use of EXTRA_LLIFLAGS, simple is good. Modified: test-suite/trunk/Makefile.programs test-suite/trunk/TEST.nightly.Makefile test-suite/trunk/TEST.nightly2.Makefile Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91013&r1=91012&r2=91013&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 9 18:30:10 2009 @@ -381,7 +381,8 @@ # $(PROGRAMS_TO_TEST:%=Output/%.cbe.c): \ Output/%.cbe.c: Output/%.llvm.bc $(LLC) - $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) -march=c $< -o $@ + $(VERB) $(RM) -f $(CURDIR)/$@.info + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) -march=c $< -o $@ -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ Output/%.cbe: Output/%.cbe.c @@ -392,15 +393,18 @@ # $(PROGRAMS_TO_TEST:%=Output/%.llc.s): \ Output/%.llc.s: Output/%.llvm.bc $(LLC) - $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ + $(VERB) $(RM) -f $(CURDIR)/$@.info + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.llc-beta.s): \ Output/%.llc-beta.s: Output/%.llvm.bc $(LLC) - $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $(LLCBETAOPTION) $< -o $@ + $(VERB) $(RM) -f $(CURDIR)/$@.info + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $(LLCBETAOPTION) $< -o $@ -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.opt-beta.s): \ Output/%.opt-beta.s: Output/%.llvm.optbeta.bc $(LLC) - $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ + $(VERB) $(RM) -f $(CURDIR)/$@.info + $(RUNTOOLSAFELY) $(LLC) $(LLCFLAGS) $< -o $@ -info-output-file=$(CURDIR)/$@.info $(STATS) # On darwin, pass -force_cpusubtype_ALL to allow all ppc instructions. ifeq ($(ARCH),PowerPC) @@ -477,15 +481,15 @@ $(PROGRAMS_TO_TEST:%=Output/%.out-lli): \ Output/%.out-lli: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLI_OPTS) $< $(RUN_OPTIONS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLI_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.out-jit): \ Output/%.out-jit: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(JIT_OPTS) $< $(RUN_OPTIONS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(JIT_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.out-jit-beta): \ Output/%.out-jit-beta: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLCBETAOPTION) $(JIT_OPTS) $< $(RUN_OPTIONS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLCBETAOPTION) $(JIT_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) $(PROGRAMS_TO_TEST:%=Output/%.out-llc): \ Output/%.out-llc: Output/%.llc Modified: test-suite/trunk/TEST.nightly.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly.Makefile?rev=91013&r1=91012&r2=91013&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly.Makefile (original) +++ test-suite/trunk/TEST.nightly.Makefile Wed Dec 9 18:30:10 2009 @@ -33,13 +33,9 @@ endif REPORTS_SUFFIX := $(addsuffix .report.txt, $(REPORTS_TO_GEN)) - -TIMEOPT = -time-passes -stats -info-output-file=$(CURDIR)/$@.info -EXTRA_LLIFLAGS = $(TIMEOPT) - # Compilation tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.compile.report.txt): \ -Output/%.nightly.compile.report.txt: Output/%.llvm.bc $(LOPT) +Output/%.nightly.compile.report.txt: Output/%.llvm.bc @echo > $@ @-if test -f Output/$*.linked.bc.info; then \ echo "TEST-PASS: compile $(RELDIR)/$*" >> $@;\ @@ -62,14 +58,13 @@ # LLC tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.llc.report.txt): \ -Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc $(LLC) +Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc @echo > $@ -head -n 100 Output/$*.exe-llc >> $@ @-if test -f Output/$*.exe-llc; then \ echo "TEST-PASS: llc $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-llc: " >> $@;\ - grep "Total Execution Time" $@.info | tail -n 1 >> $@;\ + grep "Total Execution Time" Output/$*.llc.s.info | tail -n 1 >> $@;\ printf "TEST-RESULT-llc-time: " >> $@;\ grep "^program" Output/$*.out-llc.time >> $@;\ echo >> $@;\ @@ -79,14 +74,13 @@ # LLC experimental tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.llc-beta.report.txt): \ -Output/%.nightly.llc-beta.report.txt: Output/%.llvm.bc Output/%.exe-llc-beta $(LLC) +Output/%.nightly.llc-beta.report.txt: Output/%.llvm.bc Output/%.exe-llc-beta @echo > $@ -head -n 100 Output/$*.exe-llc-beta >> $@ @-if test -f Output/$*.exe-llc-beta; then \ echo "TEST-PASS: llc-beta $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) $(LLCBETAOPTION) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-llc-beta: " >> $@;\ - grep "Total Execution Time" $@.info | tail -n 1 >> $@;\ + grep "Total Execution Time" Output/$*.llc-beta.s.info | tail -n 1 >> $@;\ printf "TEST-RESULT-llc-beta-time: " >> $@;\ grep "^program" Output/$*.out-llc-beta.time >> $@;\ echo >> $@;\ @@ -96,14 +90,13 @@ # OPT experimental tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.opt-beta.report.txt): \ -Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta $(LOPT) +Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta @echo > $@ -head -n 100 Output/$*.exe-opt-beta >> $@ @-if test -f Output/$*.exe-opt-beta; then \ echo "TEST-PASS: opt-beta $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-opt-beta: " >> $@;\ - grep "Total Execution Time" $@.info | tail -n 1 >> $@;\ + grep "Total Execution Time" Output/$*.opt-beta.s.info | tail -n 1 >> $@;\ printf "TEST-RESULT-opt-beta-time: " >> $@;\ grep "^program" Output/$*.out-opt-beta.time >> $@;\ echo >> $@;\ @@ -113,7 +106,7 @@ # CBE tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.cbe.report.txt): \ -Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe $(LLC) +Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe @echo > $@ -head -n 100 Output/$*.exe-cbe >> $@ @-if test -f Output/$*.exe-cbe; then \ @@ -127,7 +120,7 @@ # JIT tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.jit.report.txt): \ -Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit $(LLI) +Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit @echo > $@ -head -n 100 Output/$*.exe-jit >> $@ @-if test -f Output/$*.exe-jit; then \ Modified: test-suite/trunk/TEST.nightly2.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly2.Makefile?rev=91013&r1=91012&r2=91013&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly2.Makefile (original) +++ test-suite/trunk/TEST.nightly2.Makefile Wed Dec 9 18:30:10 2009 @@ -33,13 +33,9 @@ endif REPORTS_SUFFIX := $(addsuffix .report.txt, $(REPORTS_TO_GEN)) - -TIMEOPT = -time-passes -stats -info-output-file=$(CURDIR)/$@.info -EXTRA_LLIFLAGS = $(TIMEOPT) - # Compilation tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.compile.report.txt): \ -Output/%.nightly.compile.report.txt: Output/%.llvm.bc $(LOPT) +Output/%.nightly.compile.report.txt: Output/%.llvm.bc @echo > $@ @-if test -f Output/$*.linked.bc.info; then \ echo "TEST-PASS: compile $(RELDIR)/$*" >> $@;\ @@ -62,14 +58,13 @@ # LLC tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.llc.report.txt): \ -Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc $(LLC) +Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc @echo > $@ -head -n 100 Output/$*.exe-llc >> $@ @-if test -f Output/$*.exe-llc; then \ echo "TEST-PASS: llc $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-llc: " >> $@;\ - grep "Total Execution Time" $@.info >> $@;\ + grep "Total Execution Time" Output/$*.llc.s.info >> $@;\ printf "TEST-RESULT-llc-time: " >> $@;\ grep "^program" Output/$*.out-llc.time >> $@;\ echo >> $@;\ @@ -79,14 +74,13 @@ # LLC experimental tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.llc-beta.report.txt): \ -Output/%.nightly.llc-beta.report.txt: Output/%.llvm.bc Output/%.exe-llc-beta $(LLC) +Output/%.nightly.llc-beta.report.txt: Output/%.llvm.bc Output/%.exe-llc-beta @echo > $@ -head -n 100 Output/$*.exe-llc-beta >> $@ @-if test -f Output/$*.exe-llc-beta; then \ echo "TEST-PASS: llc-beta $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) $(LLCBETAOPTION) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-llc-beta: " >> $@;\ - grep "Total Execution Time" $@.info >> $@;\ + grep "Total Execution Time" Output/$*.llc-beta.s.info >> $@;\ printf "TEST-RESULT-llc-beta-time: " >> $@;\ grep "^program" Output/$*.out-llc-beta.time >> $@;\ echo >> $@;\ @@ -96,12 +90,11 @@ # OPT experimental tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.opt-beta.report.txt): \ -Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta $(LOPT) +Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta @echo > $@ -head -n 100 Output/$*.exe-opt-beta >> $@ @-if test -f Output/$*.exe-opt-beta; then \ echo "TEST-PASS: opt-beta $(RELDIR)/$*" >> $@;\ - $(LLC) $< $(LLCFLAGS) -o /dev/null -f $(TIMEOPT) >> $@ 2>&1; \ printf "TEST-RESULT-opt-beta: " >> $@;\ grep "Total Execution Time" $@.info >> $@;\ printf "TEST-RESULT-opt-beta-time: " >> $@;\ @@ -113,7 +106,7 @@ # CBE tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.cbe.report.txt): \ -Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe $(LLC) +Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe @echo > $@ -head -n 100 Output/$*.exe-cbe >> $@ @-if test -f Output/$*.exe-cbe; then \ @@ -127,7 +120,7 @@ # JIT tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.jit.report.txt): \ -Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit $(LLI) +Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit @echo > $@ -head -n 100 Output/$*.exe-jit >> $@ @-if test -f Output/$*.exe-jit; then \ From clattner at apple.com Wed Dec 9 18:48:44 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 9 Dec 2009 16:48:44 -0800 Subject: [llvm-commits] [llvm] r91009 - /llvm/trunk/lib/Transforms/Scalar/LICM.cpp In-Reply-To: <200912100025.nBA0PfvH003424@zion.cs.uiuc.edu> References: <200912100025.nBA0PfvH003424@zion.cs.uiuc.edu> Message-ID: <13A28EC7-458A-465A-96EC-A9EF3C1A7EDC@apple.com> testcase? On Dec 9, 2009, at 4:25 PM, Eric Christopher wrote: > Author: echristo > Date: Wed Dec 9 18:25:41 2009 > New Revision: 91009 > > URL: http://llvm.org/viewvc/llvm-project?rev=91009&view=rev > Log: > Make sure the immediate dominator isn't NULL through iterations > of the loop. We could get to this condition via indirect > branches. > > Modified: > llvm/trunk/lib/Transforms/Scalar/LICM.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=91009&r1=91008&r2=91009&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Wed Dec 9 18:25:41 2009 > @@ -160,16 +160,17 @@ > > // Because the exit block is not in the loop, we know we have > to get _at > // least_ its immediate dominator. > - do { > - // Get next Immediate Dominator. > - IDom = IDom->getIDom(); > - > + IDom = IDom->getIDom(); > + > + while (IDom && IDom != BlockInLoopNode) { > // If we have got to the header of the loop, then the > instructions block > // did not dominate the exit node, so we can't hoist it. > if (IDom->getBlock() == LoopHeader) > return false; > > - } while (IDom != BlockInLoopNode); > + // Get next Immediate Dominator. > + IDom = IDom->getIDom(); > + }; > > return true; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From daniel at zuster.org Wed Dec 9 19:14:34 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:14:34 -0000 Subject: [llvm-commits] [test-suite] r91028 - in /test-suite/trunk: TEST.nightly2.Makefile TEST.nightly2.report Message-ID: <200912100114.nBA1EY8n005645@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:14:34 2009 New Revision: 91028 URL: http://llvm.org/viewvc/llvm-project?rev=91028&view=rev Log: DCE TEST.nightly2. Removed: test-suite/trunk/TEST.nightly2.Makefile test-suite/trunk/TEST.nightly2.report Removed: test-suite/trunk/TEST.nightly2.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly2.Makefile?rev=91027&view=auto ============================================================================== --- test-suite/trunk/TEST.nightly2.Makefile (original) +++ test-suite/trunk/TEST.nightly2.Makefile (removed) @@ -1,150 +0,0 @@ -##===- TEST.nightly.Makefile ------------------------------*- Makefile -*--===## -# -# This test is used in conjunction with the llvm/utils/NightlyTest* stuff to -# generate information about program status for the nightly report. -# -##===----------------------------------------------------------------------===## - -CURDIR := $(shell cd .; pwd) -PROGDIR := $(PROJ_SRC_ROOT) -RELDIR := $(subst $(PROGDIR),,$(CURDIR)) - -REPORTS_TO_GEN := nat -REPORT_DEPENDENCIES := -ifndef DISABLE_LLC -REPORTS_TO_GEN += llc compile -REPORT_DEPENDENCIES += $(LLC) $(LOPT) -endif -ifndef DISABLE_JIT -REPORTS_TO_GEN += jit compile -REPORT_DEPENDENCIES += $(LLI) $(LOPT) -endif -ifndef DISABLE_CBE -REPORTS_TO_GEN += cbe compile -REPORT_DEPENDENCIES += $(CBE) $(LOPT) -endif -ifdef ENABLE_LLCBETA -REPORTS_TO_GEN += llc-beta compile -REPORT_DEPENDENCIES += $(LLC) $(LOPT) -endif -ifdef ENABLE_OPTBETA -REPORTS_TO_GEN += opt-beta compile -REPORT_DEPENDENCIES += $(LOPT) -endif -REPORTS_SUFFIX := $(addsuffix .report.txt, $(REPORTS_TO_GEN)) - -# Compilation tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.compile.report.txt): \ -Output/%.nightly.compile.report.txt: Output/%.llvm.bc - @echo > $@ - @-if test -f Output/$*.linked.bc.info; then \ - echo "TEST-PASS: compile $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-compile: " >> $@;\ - grep "Total Execution Time" Output/$*.linked.bc.info >> $@;\ - echo >> $@;\ - printf "TEST-RESULT-compile: " >> $@;\ - wc -c $< >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: compile $(RELDIR)/$*" >> $@;\ - fi - -# NAT tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.nat.report.txt): \ -Output/%.nightly.nat.report.txt: Output/%.out-nat - @echo > $@ - @printf "TEST-RESULT-nat-time: " >> $@ - -grep "^program" Output/$*.out-nat.time >> $@ - -# LLC tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.llc.report.txt): \ -Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc - @echo > $@ - -head -n 100 Output/$*.exe-llc >> $@ - @-if test -f Output/$*.exe-llc; then \ - echo "TEST-PASS: llc $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-llc: " >> $@;\ - grep "Total Execution Time" Output/$*.llc.s.info >> $@;\ - printf "TEST-RESULT-llc-time: " >> $@;\ - grep "^program" Output/$*.out-llc.time >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: llc $(RELDIR)/$*" >> $@;\ - fi - -# LLC experimental tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.llc-beta.report.txt): \ -Output/%.nightly.llc-beta.report.txt: Output/%.llvm.bc Output/%.exe-llc-beta - @echo > $@ - -head -n 100 Output/$*.exe-llc-beta >> $@ - @-if test -f Output/$*.exe-llc-beta; then \ - echo "TEST-PASS: llc-beta $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-llc-beta: " >> $@;\ - grep "Total Execution Time" Output/$*.llc-beta.s.info >> $@;\ - printf "TEST-RESULT-llc-beta-time: " >> $@;\ - grep "^program" Output/$*.out-llc-beta.time >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: llc-beta $(RELDIR)/$*" >> $@;\ - fi - -# OPT experimental tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.opt-beta.report.txt): \ -Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta - @echo > $@ - -head -n 100 Output/$*.exe-opt-beta >> $@ - @-if test -f Output/$*.exe-opt-beta; then \ - echo "TEST-PASS: opt-beta $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-opt-beta: " >> $@;\ - grep "Total Execution Time" $@.info >> $@;\ - printf "TEST-RESULT-opt-beta-time: " >> $@;\ - grep "^program" Output/$*.out-opt-beta.time >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: opt-beta $(RELDIR)/$*" >> $@;\ - fi - -# CBE tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.cbe.report.txt): \ -Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe - @echo > $@ - -head -n 100 Output/$*.exe-cbe >> $@ - @-if test -f Output/$*.exe-cbe; then \ - echo "TEST-PASS: cbe $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-cbe-time: " >> $@;\ - grep "^program" Output/$*.out-cbe.time >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: cbe $(RELDIR)/$*" >> $@;\ - fi - -# JIT tests -$(PROGRAMS_TO_TEST:%=Output/%.nightly.jit.report.txt): \ -Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit - @echo > $@ - -head -n 100 Output/$*.exe-jit >> $@ - @-if test -f Output/$*.exe-jit; then \ - echo "TEST-PASS: jit $(RELDIR)/$*" >> $@;\ - printf "TEST-RESULT-jit-time: " >> $@;\ - grep "^program" Output/$*.out-jit.time >> $@;\ - echo >> $@;\ - printf "TEST-RESULT-jit-comptime: " >> $@;\ - grep "Total Execution Time" Output/$*.out-jit.info >> $@;\ - echo >> $@;\ - else \ - echo "TEST-FAIL: jit $(RELDIR)/$*" >> $@;\ - fi - -# Overall tests: just run subordinate tests -$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ -Output/%.$(TEST).report.txt: $(addprefix Output/%.nightly., $(REPORTS_SUFFIX)) - -cat $(addprefix Output/$*.nightly., $(REPORTS_SUFFIX)) > $@ - - - -$(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ -test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" - @-cat $< Removed: test-suite/trunk/TEST.nightly2.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly2.report?rev=91027&view=auto ============================================================================== --- test-suite/trunk/TEST.nightly2.report (original) +++ test-suite/trunk/TEST.nightly2.report (removed) @@ -1,103 +0,0 @@ -##=== TEST.nightly.report - Report description for nightly -----*- perl -*-===## -# -# This file defines a report to be generated for the nightly tests. -# -##===----------------------------------------------------------------------===## - -# Sort by program name -$SortCol = 0; -$TrimRepeatedPrefix = 1; - -my $WallTimeRE = "Time: ([0-9.]+) seconds \\([0-9.]+ wall clock"; - -# FormatTime - Convert a time from 1m23.45 into 83.45 -sub FormatTime { - my $Time = shift; - if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { - return sprintf("%7.3f", $1*60.0+$2); - } - - return sprintf("%7.2f", $Time); -} - -sub GCCCBERatio { - my ($Cols, $Col) = @_; - my $GCC = $Cols->[$Col-7]; - my $CBE = $Cols->[$Col-6]; - return "n/a" if ($GCC eq "*" or $CBE eq "*"); - return sprintf("%3.2f", $GCC/$CBE) if ($GCC >= 0.1 and $CBE >= 0.1); - return "-"; -} - -sub GCCLLCRatio { - my ($Cols, $Col) = @_; - my $GCC = $Cols->[$Col-8]; - my $LLC = $Cols->[$Col-6]; - return "n/a" if ($GCC eq "*" or $LLC eq "*"); - return sprintf("%3.2f", $GCC/$LLC) if ($GCC >= 0.1 and $LLC >= 0.1); - return "-"; -} - -sub GCCLLC_BETARatio { - my ($Cols, $Col) = @_; - my $GCC = $Cols->[$Col-9]; - my $LLC_BETA = $Cols->[$Col-6]; - return "n/a" if ($GCC eq "*" or $LLC_BETA eq "*"); - return sprintf("%3.2f", $GCC/$LLC_BETA) if ($GCC >= 0.1 and $LLC_BETA >= 0.1); - return "-"; -} - -sub LLCLLC_BETARatio { # LLC/LLC-BETA - my ($Cols, $Col) = @_; - my $LLC = $Cols->[$Col-8]; - my $LLC_BETA = $Cols->[$Col-7]; - return "n/a" if ($LLC eq "*" or $LLC_BETA eq "*"); - return sprintf("%3.2f", $LLC/$LLC_BETA) if ($LLC >= 0.1 and $LLC_BETA >= 0.1); - return "-"; -} - -sub OPTOPT_BETARatio { # OPT/OPT-BETA - my ($Cols, $Col) = @_; - my $LLC = $Cols->[$Col-9]; - my $OPT_BETA = $Cols->[$Col-7]; - return "n/allc" if ($LLC eq "*"); - return "n/aopt" if ($OPT_BETA eq "*"); - return "n/a" if ($LLC eq "*" or $OPT_BETA eq "*"); - return sprintf("%3.2f", $LLC/$OPT_BETA) if ($LLC >= 0.1 and $OPT_BETA >= 0.1); - return "-"; -} - -# highlight the RATIO columns with green/red. -$HilightColumns{14} = 1; -$HilightColumns{15} = 1; -$HilightColumns{16} = 1; -$HilightColumns{17} = 1; - -# These are the columns for the report. The first entry is the header for the -# column, the second is the regex to use to match the value. Empty list create -# separators, and closures may be put in for custom processing. -( -# Name - ["Program" , '\'([^\']+)\' Program'], - [], -# Times - ["GCCAS" , "TEST-RESULT-compile: .*$WallTimeRE"], - ["Bytecode" , 'TEST-RESULT-compile: *([0-9]+)'], - ["LLC compile" , "TEST-RESULT-llc: .*$WallTimeRE"], - ["LLC-BETA compile" , "TEST-RESULT-llc-beta: .*$WallTimeRE"], - ["OPT-BETA compile" , "TEST-RESULT-opt-beta: .*$WallTimeRE"], - ["JIT codegen" , "TEST-RESULT-jit-comptime: .*$WallTimeRE"], - [], - ["GCC" , 'TEST-RESULT-nat-time: program\s*([.0-9m:]+)', \&FormatTime], - ["CBE" , 'TEST-RESULT-cbe-time: program\s*([.0-9m:]+)', \&FormatTime], - ["LLC" , 'TEST-RESULT-llc-time: program\s*([.0-9m:]+)', \&FormatTime], - ["LLC-BETA" , 'TEST-RESULT-llc-beta-time: program\s*([.0-9m:]+)',\&FormatTime], - ["OPT-BETA" , 'TEST-RESULT-opt-beta-time: program\s*([.0-9m:]+)',\&FormatTime], - ["JIT" , 'TEST-RESULT-jit-time: program\s*([.0-9m:]+)', \&FormatTime], - [], - ["GCC/CBE" , \&GCCCBERatio], - ["GCC/LLC" , \&GCCLLCRatio], - ["GCC/LLC-BETA" , \&GCCLLC_BETARatio], - ["LLC/LLC-BETA" , \&LLCLLC_BETARatio], - ["OPT/OPT-BETA" , \&OPTOPT_BETARatio] -); From daniel at zuster.org Wed Dec 9 19:14:39 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:14:39 -0000 Subject: [llvm-commits] [test-suite] r91029 - /test-suite/trunk/TEST.nightly.report Message-ID: <200912100114.nBA1EdPr005657@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:14:38 2009 New Revision: 91029 URL: http://llvm.org/viewvc/llvm-project?rev=91029&view=rev Log: NightlyTest: Print more digits of precision, truncating significant digits is a crime. Modified: test-suite/trunk/TEST.nightly.report Modified: test-suite/trunk/TEST.nightly.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly.report?rev=91029&r1=91028&r2=91029&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly.report (original) +++ test-suite/trunk/TEST.nightly.report Wed Dec 9 19:14:38 2009 @@ -14,10 +14,10 @@ sub FormatTime { my $Time = shift; if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { - return sprintf("%7.3f", $1*60.0+$2); + return sprintf("%7.4f", $1*60.0+$2); } - return sprintf("%7.2f", $Time); + return sprintf("%7.4f", $Time); } sub GCCCBERatio { From daniel at zuster.org Wed Dec 9 19:14:43 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:14:43 -0000 Subject: [llvm-commits] [test-suite] r91030 - /test-suite/trunk/TEST.nightly.Makefile Message-ID: <200912100114.nBA1EhfD005674@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:14:43 2009 New Revision: 91030 URL: http://llvm.org/viewvc/llvm-project?rev=91030&view=rev Log: Remove some unnecessary dependencies. Modified: test-suite/trunk/TEST.nightly.Makefile Modified: test-suite/trunk/TEST.nightly.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly.Makefile?rev=91030&r1=91029&r2=91030&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly.Makefile (original) +++ test-suite/trunk/TEST.nightly.Makefile Wed Dec 9 19:14:43 2009 @@ -58,7 +58,7 @@ # LLC tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.llc.report.txt): \ -Output/%.nightly.llc.report.txt: Output/%.llvm.bc Output/%.exe-llc +Output/%.nightly.llc.report.txt: Output/%.exe-llc @echo > $@ -head -n 100 Output/$*.exe-llc >> $@ @-if test -f Output/$*.exe-llc; then \ @@ -90,7 +90,7 @@ # OPT experimental tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.opt-beta.report.txt): \ -Output/%.nightly.opt-beta.report.txt: Output/%.llvm.optbeta.bc Output/%.exe-opt-beta +Output/%.nightly.opt-beta.report.txt: Output/%.exe-opt-beta @echo > $@ -head -n 100 Output/$*.exe-opt-beta >> $@ @-if test -f Output/$*.exe-opt-beta; then \ @@ -106,7 +106,7 @@ # CBE tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.cbe.report.txt): \ -Output/%.nightly.cbe.report.txt: Output/%.llvm.bc Output/%.exe-cbe +Output/%.nightly.cbe.report.txt: Output/%.exe-cbe @echo > $@ -head -n 100 Output/$*.exe-cbe >> $@ @-if test -f Output/$*.exe-cbe; then \ @@ -120,7 +120,7 @@ # JIT tests $(PROGRAMS_TO_TEST:%=Output/%.nightly.jit.report.txt): \ -Output/%.nightly.jit.report.txt: Output/%.llvm.bc Output/%.exe-jit +Output/%.nightly.jit.report.txt: Output/%.exe-jit @echo > $@ -head -n 100 Output/$*.exe-jit >> $@ @-if test -f Output/$*.exe-jit; then \ From daniel at zuster.org Wed Dec 9 19:14:48 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:14:48 -0000 Subject: [llvm-commits] [test-suite] r91031 - in /test-suite/trunk: Makefile.programs TEST.buildrepo.Makefile Message-ID: <200912100114.nBA1EmIt005690@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:14:48 2009 New Revision: 91031 URL: http://llvm.org/viewvc/llvm-project?rev=91031&view=rev Log: NighlytTest: Eliminate test-set and test-finish phony targets, relying on dependency declaration order is bogus. Modified: test-suite/trunk/Makefile.programs test-suite/trunk/TEST.buildrepo.Makefile Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91031&r1=91030&r2=91031&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 9 19:14:48 2009 @@ -738,10 +738,7 @@ # the default target is the test target. Here we dispatch to a specific set of # tests. # -.PHONY: test-setup test-finish -test-setup:: -test-finish:: -test:: test-setup $(PROGRAMS_TO_TEST:%=test.$(TEST).%) test-finish +test:: $(PROGRAMS_TO_TEST:%=test.$(TEST).%) # AVAILABLE_TESTS - Compute the set of tests available for user help # Modified: test-suite/trunk/TEST.buildrepo.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.buildrepo.Makefile?rev=91031&r1=91030&r2=91031&view=diff ============================================================================== --- test-suite/trunk/TEST.buildrepo.Makefile (original) +++ test-suite/trunk/TEST.buildrepo.Makefile Wed Dec 9 19:14:48 2009 @@ -17,8 +17,6 @@ .PRECIOUS: $(DESTDIR)/.dir $(DESTDIR)/%.bc -test-setup:: $(DESTDIR)/.dir - # To Make a file up-to-date, just copy it over. $(PROGRAMS_TO_TEST:%=$(DESTDIR)/%.bc): \ $(DESTDIR)/%.bc: Output/%.llvm.bc From daniel at zuster.org Wed Dec 9 19:39:42 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:39:42 -0000 Subject: [llvm-commits] [test-suite] r91034 - /test-suite/trunk/Makefile.programs Message-ID: <200912100139.nBA1dgB4006585@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:39:42 2009 New Revision: 91034 URL: http://llvm.org/viewvc/llvm-project?rev=91034&view=rev Log: NightlyTest: Instead of logging all data to the report.foo.raw.out file, only concatenate the individual test reports in an atomic step. - This unbreaks ENABLE_PARALLEL_REPORT with 'make report', without this the output would be garbled which breaks GenerateReport.pl. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91034&r1=91033&r2=91034&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 9 19:39:42 2009 @@ -798,7 +798,8 @@ endif report.$(TEST).raw.out: $(REPORT_DEPENDENCIES) $(TestMakefile) - $(MAKE) $(FORCE_SERIAL_ARG) TEST=$(TEST) 2>&1 | tee $@ + $(MAKE) $(FORCE_SERIAL_ARG) TEST=$(TEST) + cat Output/*.$(TEST).report.txt | tee $@ ifneq ($(TestReport),) report.$(TEST).txt: report.$(TEST).raw.out $(TestReport) $(GENERATEREPORT) From daniel at zuster.org Wed Dec 9 19:39:37 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 01:39:37 -0000 Subject: [llvm-commits] [test-suite] r91033 - in /test-suite/trunk: TEST.aa.Makefile TEST.beta-compare.Makefile TEST.jit.Makefile TEST.libcalls.Makefile TEST.llc.Makefile TEST.nightly.Makefile Message-ID: <200912100139.nBA1db8M006573@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 19:39:37 2009 New Revision: 91033 URL: http://llvm.org/viewvc/llvm-project?rev=91033&view=rev Log: NightlyTest: Include the individual program report header in the .report.txt files. Modified: test-suite/trunk/TEST.aa.Makefile test-suite/trunk/TEST.beta-compare.Makefile test-suite/trunk/TEST.jit.Makefile test-suite/trunk/TEST.libcalls.Makefile test-suite/trunk/TEST.llc.Makefile test-suite/trunk/TEST.nightly.Makefile Modified: test-suite/trunk/TEST.aa.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.aa.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.aa.Makefile (original) +++ test-suite/trunk/TEST.aa.Makefile Wed Dec 9 19:39:37 2009 @@ -38,7 +38,11 @@ # Overall tests: just run subordinate tests $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: $(addprefix Output/%.aa., $(AA_OUTPUTS)) - -$(LDIS) < Output/$*.lib.bc | grep ^declare > $@ + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ + -$(LDIS) < Output/$*.lib.bc | grep ^declare >> $@ @-for output in $(addprefix Output/$*.aa., $(AA_OUTPUTS)); do \ echo -n "$$output:" >> $@; \ grep Summary $$output >> $@; \ @@ -50,9 +54,6 @@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$*' Program" - @echo "---------------------------------------------------------------" @cat $< # Define REPORT_DEPENDENCIES so that the report is regenerated if analyze or Modified: test-suite/trunk/TEST.beta-compare.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.beta-compare.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.beta-compare.Makefile (original) +++ test-suite/trunk/TEST.beta-compare.Makefile Wed Dec 9 19:39:37 2009 @@ -21,16 +21,17 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.$(TEST).llc-info.txt Output/%.$(TEST).llc-beta-info.txt - - at printf "LLC: " > $@ + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ + - at printf "LLC: " >> $@ -grep 'Number of machine instrs printed' Output/$*.$(TEST).llc-info.txt >> $@ - at printf "LLCBETA: " >> $@ -grep 'Number of machine instrs printed' Output/$*.$(TEST).llc-beta-info.txt >> $@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" @cat $< # Define REPORT_DEPENDENCIES so that the report is regenerated if llc changes Modified: test-suite/trunk/TEST.jit.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.jit.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.jit.Makefile (original) +++ test-suite/trunk/TEST.jit.Makefile Wed Dec 9 19:39:37 2009 @@ -13,14 +13,15 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.llvm.bc $(LLI) + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ -(time -p $(LLI) $(JIT_OPTS) $< $(RUN_OPTIONS) > /dev/null \ - < $(STDIN_FILENAME)) > $@ 2>&1 + < $(STDIN_FILENAME)) >> $@ 2>&1 $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" @cat $< # Define REPORT_DEPENDENCIES so that the report is regenerated if lli changes Modified: test-suite/trunk/TEST.libcalls.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.libcalls.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.libcalls.Makefile (original) +++ test-suite/trunk/TEST.libcalls.Makefile Wed Dec 9 19:39:37 2009 @@ -18,16 +18,17 @@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" @cat $< $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.linked.rbc $(LOPT) \ + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ $(PROJ_SRC_ROOT)/TEST.libcalls.Makefile @-$(LOPT) -simplify-libcalls -stats -debug-only=simplify-libcalls \ - -time-passes -disable-output $< 2>$@ + -time-passes -disable-output $< 2>>$@ summary: @$(MAKE) TEST=libcalls | egrep '======|simplify-libcalls -' Modified: test-suite/trunk/TEST.llc.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.llc.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.llc.Makefile (original) +++ test-suite/trunk/TEST.llc.Makefile Wed Dec 9 19:39:37 2009 @@ -13,13 +13,14 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.llvm.bc $(LLC) - -(time -p $(LLC) $(LLC_OPTS) $<) > $@ 2>&1 + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ + -(time -p $(LLC) $(LLC_OPTS) $<) >> $@ 2>&1 $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" @cat $< # Define REPORT_DEPENDENCIES so that the report is regenerated if llc changes Modified: test-suite/trunk/TEST.nightly.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.nightly.Makefile?rev=91033&r1=91032&r2=91033&view=diff ============================================================================== --- test-suite/trunk/TEST.nightly.Makefile (original) +++ test-suite/trunk/TEST.nightly.Makefile Wed Dec 9 19:39:37 2009 @@ -138,13 +138,14 @@ # Overall tests: just run subordinate tests $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: $(addprefix Output/%.nightly., $(REPORTS_SUFFIX)) - -cat $(addprefix Output/$*.nightly., $(REPORTS_SUFFIX)) > $@ + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ + -cat $(addprefix Output/$*.nightly., $(REPORTS_SUFFIX)) >> $@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "---------------------------------------------------------------" - @echo ">>> ========= '$(RELDIR)/$*' Program" - @echo "---------------------------------------------------------------" @-cat $< From daniel at zuster.org Wed Dec 9 20:02:51 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 02:02:51 -0000 Subject: [llvm-commits] [test-suite] r91038 - /test-suite/trunk/Makefile.programs Message-ID: <200912100202.nBA22pYC007542@zion.cs.uiuc.edu> Author: ddunbar Date: Wed Dec 9 20:02:51 2009 New Revision: 91038 URL: http://llvm.org/viewvc/llvm-project?rev=91038&view=rev Log: NightlyTest: Fix a {think,test}o, need to try a bit harder to find all the foo.report.txt files, this part of the makefile is only run at the top-level. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91038&r1=91037&r2=91038&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 9 20:02:51 2009 @@ -799,7 +799,7 @@ report.$(TEST).raw.out: $(REPORT_DEPENDENCIES) $(TestMakefile) $(MAKE) $(FORCE_SERIAL_ARG) TEST=$(TEST) - cat Output/*.$(TEST).report.txt | tee $@ + find . -name \*.$(TEST).report.txt -exec cat {} \; | tee $@ ifneq ($(TestReport),) report.$(TEST).txt: report.$(TEST).raw.out $(TestReport) $(GENERATEREPORT) From edwintorok at gmail.com Thu Dec 10 04:01:47 2009 From: edwintorok at gmail.com (Torok Edwin) Date: Thu, 10 Dec 2009 10:01:47 -0000 Subject: [llvm-commits] [llvm] r91046 - /llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Message-ID: <200912101001.nBAA1mtO005031@zion.cs.uiuc.edu> Author: edwin Date: Thu Dec 10 04:01:47 2009 New Revision: 91046 URL: http://llvm.org/viewvc/llvm-project?rev=91046&view=rev Log: Comparing std::string with NULL is a bad idea, so just check whether its empty. This code was crashing always with oprofile enabled, since it tried to create a StringRef out of NULL, which run strlen on NULL. Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=91046&r1=91045&r2=91046&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Thu Dec 10 04:01:47 2009 @@ -76,7 +76,7 @@ public: const char *getFilename(MDNode *Scope) { std::string &Filename = Filenames[Scope]; - if (Filename == NULL) { + if (Filename.empty()) { DIScope S(Scope); Filename = S.getFilename(); } From daniel at zuster.org Thu Dec 10 04:49:55 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 10:49:55 -0000 Subject: [llvm-commits] [test-suite] r91047 - /test-suite/trunk/Makefile.programs Message-ID: <200912101049.nBAAntEs007297@zion.cs.uiuc.edu> Author: ddunbar Date: Thu Dec 10 04:49:53 2009 New Revision: 91047 URL: http://llvm.org/viewvc/llvm-project?rev=91047&view=rev Log: Fix placement of -info-output-file and -stats when calling LLI, so that they aren't interepreted as program arguments. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=91047&r1=91046&r2=91047&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Thu Dec 10 04:49:53 2009 @@ -481,15 +481,15 @@ $(PROGRAMS_TO_TEST:%=Output/%.out-lli): \ Output/%.out-lli: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLI_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) -info-output-file=$(CURDIR)/$@.info $(STATS) $(LLI_OPTS) $< $(RUN_OPTIONS) $(PROGRAMS_TO_TEST:%=Output/%.out-jit): \ Output/%.out-jit: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(JIT_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) -info-output-file=$(CURDIR)/$@.info $(STATS) $(JIT_OPTS) $< $(RUN_OPTIONS) $(PROGRAMS_TO_TEST:%=Output/%.out-jit-beta): \ Output/%.out-jit-beta: Output/%.llvm.bc $(LLI) - $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) $(LLCBETAOPTION) $(JIT_OPTS) $< $(RUN_OPTIONS) -info-output-file=$(CURDIR)/$@.info $(STATS) + $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) -info-output-file=$(CURDIR)/$@.info $(STATS) $(LLCBETAOPTION) $(JIT_OPTS) $< $(RUN_OPTIONS) $(PROGRAMS_TO_TEST:%=Output/%.out-llc): \ Output/%.out-llc: Output/%.llc From daniel at zuster.org Thu Dec 10 05:23:51 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 10 Dec 2009 11:23:51 -0000 Subject: [llvm-commits] [test-suite] r91048 - /test-suite/trunk/Makefile.tests Message-ID: <200912101123.nBABNpMU008447@zion.cs.uiuc.edu> Author: ddunbar Date: Thu Dec 10 05:23:51 2009 New Revision: 91048 URL: http://llvm.org/viewvc/llvm-project?rev=91048&view=rev Log: NightlyTest: Don't run $(LLVMGCC) using RUNTOOLSAFELY for now, this is failing due to shell quoting issues (we use -D\"FOO\" in some places). Unfortunately, this is the one tool I most wanted to use it for... - sh: 1, ddunbar: 0. Modified: test-suite/trunk/Makefile.tests Modified: test-suite/trunk/Makefile.tests URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.tests?rev=91048&r1=91047&r2=91048&view=diff ============================================================================== --- test-suite/trunk/Makefile.tests (original) +++ test-suite/trunk/Makefile.tests Thu Dec 10 05:23:51 2009 @@ -39,27 +39,27 @@ # Compile from X.c to Output/X.bc Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cpp to Output/X.bc Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cc to Output/X.bc Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.C to Output/X.bc Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.m to Output/X.bc Output/%.bc: %.m $(LCC1) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.mm to Output/X.bc Output/%.bc: %.mm $(LCC1XX) Output/.dir $(INCLUDES) - $(RUNTOOLSAFELY) $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # LLVM Assemble from X.ll to Output/X.bc. Because we are coming directly from # LLVM source, use the non-transforming assembler. From jyasskin at google.com Thu Dec 10 10:47:34 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Thu, 10 Dec 2009 08:47:34 -0800 Subject: [llvm-commits] [llvm] r91046 - /llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp In-Reply-To: <200912101001.nBAA1mtO005031@zion.cs.uiuc.edu> References: <200912101001.nBAA1mtO005031@zion.cs.uiuc.edu> Message-ID: Oops, sorry, thanks. On Thu, Dec 10, 2009 at 2:01 AM, Torok Edwin wrote: > Author: edwin > Date: Thu Dec 10 04:01:47 2009 > New Revision: 91046 > > URL: http://llvm.org/viewvc/llvm-project?rev=91046&view=rev > Log: > Comparing std::string with NULL is a bad idea, so just check whether its empty. > > This code was crashing always with oprofile enabled, since it tried to create a StringRef > out of NULL, which run strlen on NULL. > > Modified: > ? ?llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=91046&r1=91045&r2=91046&view=diff > > ============================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Thu Dec 10 04:01:47 2009 > @@ -76,7 +76,7 @@ > ?public: > ? const char *getFilename(MDNode *Scope) { > ? ? std::string &Filename = Filenames[Scope]; > - ? ?if (Filename == NULL) { > + ? ?if (Filename.empty()) { > ? ? ? DIScope S(Scope); > ? ? ? Filename = S.getFilename(); > ? ? } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From stoklund at 2pi.dk Thu Dec 10 11:48:33 2009 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 10 Dec 2009 17:48:33 -0000 Subject: [llvm-commits] [llvm] r91049 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200912101748.nBAHmXN2022100@zion.cs.uiuc.edu> Author: stoklund Date: Thu Dec 10 11:48:32 2009 New Revision: 91049 URL: http://llvm.org/viewvc/llvm-project?rev=91049&view=rev Log: Also attempt trivial coalescing for live intervals that end in a copy. The coalescer is supposed to clean these up, but when setting up parameters for a function call, there may be copies to physregs. If the defining instruction has been LICM'ed far away, the coalescer won't touch it. The register allocation hint does not always work - when the register allocator is backtracking, it clears the hints. This patch is more conservative than r90502, and does not break 483.xalancbmk/i686. It still breaks the PowerPC bootstrap, so it is disabled by default, and can be enabled with the -trivial-coalesce-ends option. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=91049&r1=91048&r2=91049&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Dec 10 11:48:32 2009 @@ -112,10 +112,13 @@ return (unsigned)(IntervalPercentage * indexes_->getFunctionSize()); } - /// conflictsWithPhysRegDef - Returns true if the specified register - /// is defined during the duration of the specified interval. - bool conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm, - unsigned reg); + /// conflictsWithPhysReg - Returns true if the specified register is used or + /// defined during the duration of the specified interval. Copies to and + /// from li.reg are allowed. This method is only able to analyze simple + /// ranges that stay within a single basic block. Anything else is + /// considered a conflict. + bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm, + unsigned reg); /// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except /// it can check use as well. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=91049&r1=91048&r2=91049&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Dec 10 11:48:32 2009 @@ -149,42 +149,69 @@ printInstrs(errs()); } -/// conflictsWithPhysRegDef - Returns true if the specified register -/// is defined during the duration of the specified interval. -bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li, - VirtRegMap &vrm, unsigned reg) { - for (LiveInterval::Ranges::const_iterator - I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { - for (SlotIndex index = I->start.getBaseIndex(), - end = I->end.getPrevSlot().getBaseIndex().getNextIndex(); - index != end; - index = index.getNextIndex()) { - MachineInstr *MI = getInstructionFromIndex(index); - if (!MI) - continue; // skip deleted instructions +bool LiveIntervals::conflictsWithPhysReg(const LiveInterval &li, + VirtRegMap &vrm, unsigned reg) { + // We don't handle fancy stuff crossing basic block boundaries + if (li.ranges.size() != 1) + return true; + const LiveRange &range = li.ranges.front(); + SlotIndex idx = range.start.getBaseIndex(); + SlotIndex end = range.end.getPrevSlot().getBaseIndex().getNextIndex(); + + // Skip deleted instructions + MachineInstr *firstMI = getInstructionFromIndex(idx); + while (!firstMI && idx != end) { + idx = idx.getNextIndex(); + firstMI = getInstructionFromIndex(idx); + } + if (!firstMI) + return false; - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) - if (SrcReg == li.reg || DstReg == li.reg) - continue; - for (unsigned i = 0; i != MI->getNumOperands(); ++i) { - MachineOperand& mop = MI->getOperand(i); - if (!mop.isReg()) - continue; - unsigned PhysReg = mop.getReg(); - if (PhysReg == 0 || PhysReg == li.reg) + // Find last instruction in range + SlotIndex lastIdx = end.getPrevIndex(); + MachineInstr *lastMI = getInstructionFromIndex(lastIdx); + while (!lastMI && lastIdx != idx) { + lastIdx = lastIdx.getPrevIndex(); + lastMI = getInstructionFromIndex(lastIdx); + } + if (!lastMI) + return false; + + // Range cannot cross basic block boundaries or terminators + MachineBasicBlock *MBB = firstMI->getParent(); + if (MBB != lastMI->getParent() || lastMI->getDesc().isTerminator()) + return true; + + MachineBasicBlock::const_iterator E = lastMI; + ++E; + for (MachineBasicBlock::const_iterator I = firstMI; I != E; ++I) { + const MachineInstr &MI = *I; + + // Allow copies to and from li.reg + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (tii_->isMoveInstr(MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) + if (SrcReg == li.reg || DstReg == li.reg) + continue; + + // Check for operands using reg + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + const MachineOperand& mop = MI.getOperand(i); + if (!mop.isReg()) + continue; + unsigned PhysReg = mop.getReg(); + if (PhysReg == 0 || PhysReg == li.reg) + continue; + if (TargetRegisterInfo::isVirtualRegister(PhysReg)) { + if (!vrm.hasPhys(PhysReg)) continue; - if (TargetRegisterInfo::isVirtualRegister(PhysReg)) { - if (!vrm.hasPhys(PhysReg)) - continue; - PhysReg = vrm.getPhys(PhysReg); - } - if (PhysReg && tri_->regsOverlap(PhysReg, reg)) - return true; + PhysReg = vrm.getPhys(PhysReg); } + if (PhysReg && tri_->regsOverlap(PhysReg, reg)) + return true; } } + // No conflicts found. return false; } Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=91049&r1=91048&r2=91049&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Thu Dec 10 11:48:32 2009 @@ -59,6 +59,11 @@ cl::desc("Pre-register allocation live interval splitting"), cl::init(false), cl::Hidden); +static cl::opt +TrivCoalesceEnds("trivial-coalesce-ends", + cl::desc("Attempt trivial coalescing of interval ends"), + cl::init(false), cl::Hidden); + static RegisterRegAlloc linearscanRegAlloc("linearscan", "linear scan register allocator", createLinearScanRegisterAllocator); @@ -390,66 +395,71 @@ RelatedRegClasses.unionSets(I->second, OneClassForEachPhysReg[*AS]); } -/// attemptTrivialCoalescing - If a simple interval is defined by a copy, -/// try allocate the definition the same register as the source register -/// if the register is not defined during live time of the interval. This -/// eliminate a copy. This is used to coalesce copies which were not -/// coalesced away before allocation either due to dest and src being in -/// different register classes or because the coalescer was overly -/// conservative. +/// attemptTrivialCoalescing - If a simple interval is defined by a copy, try +/// allocate the definition the same register as the source register if the +/// register is not defined during live time of the interval. If the interval is +/// killed by a copy, try to use the destination register. This eliminates a +/// copy. This is used to coalesce copies which were not coalesced away before +/// allocation either due to dest and src being in different register classes or +/// because the coalescer was overly conservative. unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) { unsigned Preference = vrm_->getRegAllocPref(cur.reg); if ((Preference && Preference == Reg) || !cur.containsOneValue()) return Reg; - VNInfo *vni = cur.begin()->valno; - if ((vni->def == SlotIndex()) || - vni->isUnused() || !vni->isDefAccurate()) + // We cannot handle complicated live ranges. Simple linear stuff only. + if (cur.ranges.size() != 1) return Reg; - MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def); - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg; - if (!CopyMI || - !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg)) + + const LiveRange &range = cur.ranges.front(); + + VNInfo *vni = range.valno; + if (vni->isUnused()) return Reg; - PhysReg = SrcReg; - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) { - if (!vrm_->isAssignedReg(SrcReg)) + + unsigned CandReg; + { + MachineInstr *CopyMI; + unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; + if (vni->def != SlotIndex() && vni->isDefAccurate() && + (CopyMI = li_->getInstructionFromIndex(vni->def)) && + tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg)) + // Defined by a copy, try to extend SrcReg forward + CandReg = SrcReg; + else if (TrivCoalesceEnds && + (CopyMI = + li_->getInstructionFromIndex(range.end.getBaseIndex())) && + tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && + cur.reg == SrcReg) + // Only used by a copy, try to extend DstReg backwards + CandReg = DstReg; + else + return Reg; + } + + if (TargetRegisterInfo::isVirtualRegister(CandReg)) { + if (!vrm_->isAssignedReg(CandReg)) return Reg; - PhysReg = vrm_->getPhys(SrcReg); + CandReg = vrm_->getPhys(CandReg); } - if (Reg == PhysReg) + if (Reg == CandReg) return Reg; const TargetRegisterClass *RC = mri_->getRegClass(cur.reg); - if (!RC->contains(PhysReg)) + if (!RC->contains(CandReg)) return Reg; - // Try to coalesce. - if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) { - DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg) - << '\n'); - vrm_->clearVirt(cur.reg); - vrm_->assignVirt2Phys(cur.reg, PhysReg); - - // Remove unnecessary kills since a copy does not clobber the register. - if (li_->hasInterval(SrcReg)) { - LiveInterval &SrcLI = li_->getInterval(SrcReg); - for (MachineRegisterInfo::use_iterator I = mri_->use_begin(cur.reg), - E = mri_->use_end(); I != E; ++I) { - MachineOperand &O = I.getOperand(); - if (!O.isKill()) - continue; - MachineInstr *MI = &*I; - if (SrcLI.liveAt(li_->getInstructionIndex(MI).getDefIndex())) - O.setIsKill(false); - } - } + if (li_->conflictsWithPhysReg(cur, *vrm_, CandReg)) + return Reg; - ++NumCoalesce; - return PhysReg; - } + // Try to coalesce. + DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(CandReg) + << '\n'); + vrm_->clearVirt(cur.reg); + vrm_->assignVirt2Phys(cur.reg, CandReg); - return Reg; + ++NumCoalesce; + return CandReg; } bool RALinScan::runOnMachineFunction(MachineFunction &fn) { From dpatel at apple.com Thu Dec 10 12:05:33 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 10 Dec 2009 18:05:33 -0000 Subject: [llvm-commits] [llvm] r91051 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200912101805.nBAI5XLo022644@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 10 12:05:33 2009 New Revision: 91051 URL: http://llvm.org/viewvc/llvm-project?rev=91051&view=rev Log: Refactor. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=91051&r1=91050&r2=91051&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Dec 10 12:05:33 2009 @@ -738,6 +738,40 @@ addBlock(Die, Attribute, 0, Block); } +/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the +/// given DIType. +DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) { + DIE *TyDIE = ModuleCU->getDIE(Ty.getNode()); + if (TyDIE) + return TyDIE; + + // Create new type. + TyDIE = new DIE(dwarf::DW_TAG_base_type); + ModuleCU->insertDIE(Ty.getNode(), TyDIE); + if (Ty.isBasicType()) + constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode())); + else if (Ty.isCompositeType()) + constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode())); + else { + assert(Ty.isDerivedType() && "Unknown kind of DIType"); + constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode())); + } + + DIDescriptor Context = Ty.getContext(); + if (Context.isNull()) + // Add this type into the module cu. + ModuleCU->addDie(TyDIE); + else if (Context.isType()) { + DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode())); + ContextDIE->addChild(TyDIE); + } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode())) + ContextDIE->addChild(TyDIE); + else + ModuleCU->addDie(TyDIE); + + return TyDIE; +} + /// addType - Add a new type attribute to the specified entity. void DwarfDebug::addType(DIE *Entity, DIType Ty) { if (Ty.isNull()) @@ -757,27 +791,8 @@ ModuleCU->insertDIEEntry(Ty.getNode(), Entry); // Construct type. - DIE *Buffer = new DIE(dwarf::DW_TAG_base_type); - ModuleCU->insertDIE(Ty.getNode(), Buffer); - if (Ty.isBasicType()) - constructTypeDIE(*Buffer, DIBasicType(Ty.getNode())); - else if (Ty.isCompositeType()) - constructTypeDIE(*Buffer, DICompositeType(Ty.getNode())); - else { - assert(Ty.isDerivedType() && "Unknown kind of DIType"); - constructTypeDIE(*Buffer, DIDerivedType(Ty.getNode())); - } - - // Add debug information entry to entity and appropriate context. - DIE *Die = NULL; - DIDescriptor Context = Ty.getContext(); - if (!Context.isNull()) - Die = ModuleCU->getDIE(Context.getNode()); + DIE *Buffer = getOrCreateTypeDIE(Ty); - if (Die) - Die->addChild(Buffer); - else - ModuleCU->addDie(Buffer); Entry->setEntry(Buffer); Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=91051&r1=91050&r2=91051&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Dec 10 12:05:33 2009 @@ -316,6 +316,10 @@ /// addType - Add a new type attribute to the specified entity. void addType(DIE *Entity, DIType Ty); + /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the + /// given DIType. + DIE *getOrCreateTypeDIE(DIType Ty); + void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType. From grosbach at apple.com Thu Dec 10 12:35:32 2009 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 10 Dec 2009 18:35:32 -0000 Subject: [llvm-commits] [llvm] r91053 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200912101835.nBAIZWFw023620@zion.cs.uiuc.edu> Author: grosbach Date: Thu Dec 10 12:35:32 2009 New Revision: 91053 URL: http://llvm.org/viewvc/llvm-project?rev=91053&view=rev Log: Add instruction encoding for DMB/DSB Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91053&r1=91052&r2=91053&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Dec 10 12:35:32 2009 @@ -1574,18 +1574,26 @@ // // memory barriers protect the atomic sequences -let isBarrier = 1 in { +let isBarrier = 1, isPredicable = 0 in { def Int_MemBarrierV7 : AI<(outs), (ins), Pseudo, NoItinerary, "dmb", "", [(ARMMemBarrier)]>, - Requires<[HasV7]>; + Requires<[HasV7]> { + let Inst{31-4} = 0xf57ff05; + // FIXME: add support for options other than a full system DMB + let Inst{3-0} = 0b1111; +} def Int_SyncBarrierV7 : AI<(outs), (ins), Pseudo, NoItinerary, "dsb", "", [(ARMSyncBarrier)]>, - Requires<[HasV7]>; + Requires<[HasV7]> { + let Inst{31-4} = 0xf57ff04; + // FIXME: add support for options other than a full system DSB + let Inst{3-0} = 0b1111; +} } //===----------------------------------------------------------------------===// From dpatel at apple.com Thu Dec 10 13:14:49 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 10 Dec 2009 19:14:49 -0000 Subject: [llvm-commits] [llvm] r91055 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200912101914.nBAJEnXN025003@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 10 13:14:49 2009 New Revision: 91055 URL: http://llvm.org/viewvc/llvm-project?rev=91055&view=rev Log: Refactor code that finds context for a given die. Create global variable DIEs after creating subprogram DIEs. This allows function level static variable's to find their context at the time of DIE creation. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=91055&r1=91054&r2=91055&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Dec 10 13:14:49 2009 @@ -738,6 +738,19 @@ addBlock(Die, Attribute, 0, Block); } +/// addToContextOwner - Add Die into the list of its context owner's children. +void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) { + if (Context.isNull()) + ModuleCU->addDie(Die); + else if (Context.isType()) { + DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode())); + ContextDIE->addChild(Die); + } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode())) + ContextDIE->addChild(Die); + else + ModuleCU->addDie(Die); +} + /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) { @@ -757,18 +770,7 @@ constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode())); } - DIDescriptor Context = Ty.getContext(); - if (Context.isNull()) - // Add this type into the module cu. - ModuleCU->addDie(TyDIE); - else if (Context.isType()) { - DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode())); - ContextDIE->addChild(TyDIE); - } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode())) - ContextDIE->addChild(TyDIE); - else - ModuleCU->addDie(TyDIE); - + addToContextOwner(TyDIE, Ty.getContext()); return TyDIE; } @@ -1317,19 +1319,6 @@ if (!DISubprogram(SPNode).isLocalToUnit()) addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); - // If there are global variables at this scope then add their dies. - for (SmallVector::iterator SGI = ScopedGVs.begin(), - SGE = ScopedGVs.end(); SGI != SGE; ++SGI) { - MDNode *N = dyn_cast_or_null(*SGI); - if (!N) continue; - DIGlobalVariable GV(N); - if (GV.getContext().getNode() == SPNode) { - DIE *ScopedGVDie = createGlobalVariableDIE(GV); - if (ScopedGVDie) - SPDie->addChild(ScopedGVDie); - } - } - return SPDie; } @@ -1648,9 +1637,8 @@ ModuleCU->insertDIE(N, VariableDie); // Add to context owner. - if (TopLevelDIEs.insert(VariableDie)) - TopLevelDIEsVector.push_back(VariableDie); - + addToContextOwner(VariableDie, DI_GV.getContext()); + // Expose as global. FIXME - need to check external flag. ModuleCU->addGlobal(DI_GV.getName(), VariableDie); @@ -1723,21 +1711,16 @@ if (!ModuleCU) ModuleCU = CompileUnits[0]; - // Create DIEs for each of the externally visible global variables. - for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), - E = DbgFinder.global_variable_end(); I != E; ++I) { - DIGlobalVariable GV(*I); - if (GV.getContext().getNode() != GV.getCompileUnit().getNode()) - ScopedGVs.push_back(*I); - else - constructGlobalVariableDIE(*I); - } - // Create DIEs for each subprogram. for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), E = DbgFinder.subprogram_end(); I != E; ++I) constructSubprogramDIE(*I); + // Create DIEs for each global variable. + for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), + E = DbgFinder.global_variable_end(); I != E; ++I) + constructGlobalVariableDIE(*I); + MMI = mmi; shouldEmit = true; MMI->setDebugInfoAvailability(true); Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=91055&r1=91054&r2=91055&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Dec 10 13:14:49 2009 @@ -163,10 +163,6 @@ SmallPtrSet TopLevelDIEs; SmallVector TopLevelDIEsVector; - /// ScopedGVs - Tracks global variables that are not at file scope. - /// For example void f() { static int b = 42; } - SmallVector ScopedGVs; - typedef SmallVector ScopeVector; typedef DenseMap InsnToDbgScopeMapTy; @@ -313,6 +309,9 @@ void addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute, const MachineLocation &Location); + /// addToContextOwner - Add Die into the list of its context owner's children. + void addToContextOwner(DIE *Die, DIDescriptor Context); + /// addType - Add a new type attribute to the specified entity. void addType(DIE *Entity, DIType Ty); From dgregor at apple.com Thu Dec 10 13:52:23 2009 From: dgregor at apple.com (Douglas Gregor) Date: Thu, 10 Dec 2009 19:52:23 -0000 Subject: [llvm-commits] [llvm] r91058 - /llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h Message-ID: <200912101952.nBAJqNU7026254@zion.cs.uiuc.edu> Author: dgregor Date: Thu Dec 10 13:52:22 2009 New Revision: 91058 URL: http://llvm.org/viewvc/llvm-project?rev=91058&view=rev Log: Remove a broken, unused header Removed: llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h Removed: llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h?rev=91057&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h (original) +++ llvm/trunk/include/llvm/CodeGen/BreakCriticalMachineEdge.h (removed) @@ -1,108 +0,0 @@ -//===--------- BreakCriticalMachineEdge.h - Break critical edges ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// -// -// Helper function to break a critical machine edge. -// -//===---------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H -#define LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H - -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -MachineBasicBlock* SplitCriticalMachineEdge(MachineBasicBlock* src, - MachineBasicBlock* dst) { - MachineFunction &MF = *src->getParent(); - const BasicBlock* srcBB = src->getBasicBlock(); - - MachineBasicBlock* crit_mbb = MF.CreateMachineBasicBlock(srcBB); - - // modify the llvm control flow graph - src->removeSuccessor(dst); - src->addSuccessor(crit_mbb); - crit_mbb->addSuccessor(dst); - - // insert the new block into the machine function. - MF.push_back(crit_mbb); - - // insert a unconditional branch linking the new block to dst - const TargetMachine& TM = MF.getTarget(); - const TargetInstrInfo* TII = TM.getInstrInfo(); - std::vector emptyConditions; - TII->InsertBranch(*crit_mbb, dst, (MachineBasicBlock*)0, - emptyConditions); - - // modify every branch in src that points to dst to point to the new - // machine basic block instead: - MachineBasicBlock::iterator mii = src->end(); - bool found_branch = false; - while (mii != src->begin()) { - mii--; - // if there are no more branches, finish the loop - if (!mii->getDesc().isTerminator()) { - break; - } - - // Scan the operands of this branch, replacing any uses of dst with - // crit_mbb. - for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { - MachineOperand & mo = mii->getOperand(i); - if (mo.isMBB() && mo.getMBB() == dst) { - found_branch = true; - mo.setMBB(crit_mbb); - } - } - } - - // TODO: This is tentative. It may be necessary to fix this code. Maybe - // I am inserting too many gotos, but I am trusting that the asm printer - // will optimize the unnecessary gotos. - if(!found_branch) { - TII->InsertBranch(*src, crit_mbb, (MachineBasicBlock*)0, - emptyConditions); - } - - /// Change all the phi functions in dst, so that the incoming block be - /// crit_mbb, instead of src - for(mii = dst->begin(); mii != dst->end(); mii++) { - /// the first instructions are always phi functions. - if(mii->getOpcode() != TargetInstrInfo::PHI) - break; - - // Find the operands corresponding to the source block - std::vector toRemove; - unsigned reg = 0; - for (unsigned u = 0; u != mii->getNumOperands(); ++u) - if (mii->getOperand(u).isMBB() && - mii->getOperand(u).getMBB() == src) { - reg = mii->getOperand(u-1).getReg(); - toRemove.push_back(u-1); - } - // Remove all uses of this MBB - for (std::vector::reverse_iterator I = toRemove.rbegin(), - E = toRemove.rend(); I != E; ++I) { - mii->RemoveOperand(*I+1); - mii->RemoveOperand(*I); - } - - // Add a single use corresponding to the new MBB - mii->addOperand(MachineOperand::CreateReg(reg, false)); - mii->addOperand(MachineOperand::CreateMBB(crit_mbb)); - } - - return crit_mbb; -} - -} - -#endif From evan.cheng at apple.com Thu Dec 10 14:59:46 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 10 Dec 2009 20:59:46 -0000 Subject: [llvm-commits] [llvm] r91061 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2009-12-12-CoalescerBug.ll Message-ID: <200912102059.nBAKxkt9028649@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 10 14:59:45 2009 New Revision: 91061 URL: http://llvm.org/viewvc/llvm-project?rev=91061&view=rev Log: It's not safe to coalesce a move where src and dst registers have different subregister indices. e.g.: %reg16404:1 = MOV8rr %reg16412:2 Added: llvm/trunk/test/CodeGen/X86/2009-12-12-CoalescerBug.ll Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=91061&r1=91060&r2=91061&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Dec 10 14:59:45 2009 @@ -1317,7 +1317,13 @@ "coalesced to another register.\n"); return false; // Not coalescable. } - } else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){ + } else if (tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) { + if (SrcSubIdx && DstSubIdx && SrcSubIdx != DstSubIdx) { + // e.g. %reg16404:1 = MOV8rr %reg16412:2 + Again = true; + return false; // Not coalescable. + } + } else { llvm_unreachable("Unrecognized copy instruction!"); } Added: llvm/trunk/test/CodeGen/X86/2009-12-12-CoalescerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-12-12-CoalescerBug.ll?rev=91061&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-12-12-CoalescerBug.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-12-12-CoalescerBug.ll Thu Dec 10 14:59:45 2009 @@ -0,0 +1,40 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s + +define i32 @do_loop(i32* nocapture %sdp, i32* nocapture %ddp, i8* %mdp, i8* nocapture %cdp, i32 %w) nounwind readonly optsize ssp { +entry: + br label %bb + +bb: ; preds = %bb5, %entry + %mask.1.in = load i8* undef, align 1 ; [#uses=3] + %0 = icmp eq i8 %mask.1.in, 0 ; [#uses=1] + br i1 %0, label %bb5, label %bb1 + +bb1: ; preds = %bb + br i1 undef, label %bb2, label %bb3 + +bb2: ; preds = %bb1 +; CHECK: %bb2 +; CHECK: movb %ch, %al + %1 = zext i8 %mask.1.in to i32 ; [#uses=1] + %2 = zext i8 undef to i32 ; [#uses=1] + %3 = mul i32 %2, %1 ; [#uses=1] + %4 = add i32 %3, 1 ; [#uses=1] + %5 = add i32 %4, 0 ; [#uses=1] + %6 = lshr i32 %5, 8 ; [#uses=1] + %retval12.i = trunc i32 %6 to i8 ; [#uses=1] + br label %bb3 + +bb3: ; preds = %bb2, %bb1 + %mask.0.in = phi i8 [ %retval12.i, %bb2 ], [ %mask.1.in, %bb1 ] ; [#uses=1] + %7 = icmp eq i8 %mask.0.in, 0 ; [#uses=1] + br i1 %7, label %bb5, label %bb4 + +bb4: ; preds = %bb3 + br label %bb5 + +bb5: ; preds = %bb4, %bb3, %bb + br i1 undef, label %bb6, label %bb + +bb6: ; preds = %bb5 + ret i32 undef +} From echristo at apple.com Thu Dec 10 15:11:40 2009 From: echristo at apple.com (Eric Christopher) Date: Thu, 10 Dec 2009 21:11:40 -0000 Subject: [llvm-commits] [llvm] r91062 - /llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll Message-ID: <200912102111.nBALBeuI029223@zion.cs.uiuc.edu> Author: echristo Date: Thu Dec 10 15:11:40 2009 New Revision: 91062 URL: http://llvm.org/viewvc/llvm-project?rev=91062&view=rev Log: Add a test for the fix in revision 91009. Added: llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll Added: llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll?rev=91062&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll (added) +++ llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll Thu Dec 10 15:11:40 2009 @@ -0,0 +1,20 @@ +; RUN: opt < %s -licm -disable-output +define void @foo (i8* %v) +{ + entry: + br i1 undef, label %preheader, label %return + + preheader: + br i1 undef, label %loop, label %return + + loop: + indirectbr i8* undef, [label %preheader, label %stuff] + + stuff: + %0 = load i8* undef, align 1 + br label %loop + + return: + ret void + +} \ No newline at end of file From dpatel at apple.com Thu Dec 10 17:10:37 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 10 Dec 2009 23:10:37 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r91074 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200912102310.nBANAbgn000947@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 10 17:10:37 2009 New Revision: 91074 URL: http://llvm.org/viewvc/llvm-project?rev=91074&view=rev Log: Simplify code that finds region descriptor. Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=91074&r1=91073&r2=91074&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Thu Dec 10 17:10:37 2009 @@ -264,7 +264,7 @@ ContainingType = getOrCreateType(DECL_CONTEXT (FnDecl)); } DISubprogram SP = - DebugFactory.CreateSubprogram(findRegion(FnDecl), + DebugFactory.CreateSubprogram(findRegion(DECL_CONTEXT(FnDecl)), lang_hooks.dwarf_name(FnDecl, 0), lang_hooks.dwarf_name(FnDecl, 0), LinkageName, @@ -293,20 +293,10 @@ return DIDescriptor(R); if (TYPE_P (Node)) { - if (TYPE_CONTEXT (Node)) - return findRegion (TYPE_CONTEXT(Node)); - } else if (DECL_P (Node)) { - tree decl = Node; - tree context = NULL_TREE; - if (TREE_CODE (decl) != FUNCTION_DECL || ! DECL_VINDEX (decl)) - context = DECL_CONTEXT (decl); - else - context = TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); - - if (context != NULL_TREE) - return findRegion(context); - } + DIType Ty = getOrCreateType(Node); + return DIDescriptor(Ty.getNode()); + } else if (DECL_P (Node)) + return findRegion (DECL_CONTEXT (Node)); // Otherwise main compile unit covers everything. return getOrCreateCompileUnit(main_input_filename); @@ -422,6 +412,8 @@ /// EmitGlobalVariable - Emit information about a global variable. /// void DebugInfo::EmitGlobalVariable(GlobalVariable *GV, tree decl) { + if (DECL_ARTIFICIAL(decl)) + return; // Gather location information. expanded_location Loc = expand_location(DECL_SOURCE_LOCATION(decl)); DIType TyD = getOrCreateType(TREE_TYPE(decl)); @@ -431,7 +423,7 @@ DispName = IDENTIFIER_POINTER(DECL_NAME(decl)); } - DebugFactory.CreateGlobalVariable(findRegion(decl), + DebugFactory.CreateGlobalVariable(findRegion(DECL_CONTEXT(decl)), DispName, DispName, getLinkageName(decl), getOrCreateCompileUnit(Loc.file), Loc.line, @@ -507,7 +499,8 @@ DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size()); return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - findRegion(type), StringRef(), + findRegion(TYPE_CONTEXT(type)), + StringRef(), getOrCreateCompileUnit(NULL), 0, 0, 0, 0, 0, llvm::DIType(), EltTypeArray); @@ -533,28 +526,30 @@ if (tree TyName = TYPE_NAME(type)) if (TREE_CODE(TyName) == TYPE_DECL && !DECL_ORIGINAL_TYPE(TyName)) { expanded_location TypeNameLoc = GetNodeLocation(TyName); - DIType Ty = DebugFactory.CreateDerivedType(Tag, findRegion(TyName), - GetNodeName(TyName), - getOrCreateCompileUnit(TypeNameLoc.file), - TypeNameLoc.line, - 0 /*size*/, - 0 /*align*/, - 0 /*offset */, - 0 /*flags*/, - FromTy); + DIType Ty = + DebugFactory.CreateDerivedType(Tag, findRegion(DECL_CONTEXT(TyName)), + GetNodeName(TyName), + getOrCreateCompileUnit(TypeNameLoc.file), + TypeNameLoc.line, + 0 /*size*/, + 0 /*align*/, + 0 /*offset */, + 0 /*flags*/, + FromTy); TypeCache[TyName] = WeakVH(Ty.getNode()); return Ty; } StringRef PName = FromTy.getName(); - DIType PTy = DebugFactory.CreateDerivedType(Tag, findRegion(type), PName, - getOrCreateCompileUnit(NULL), - 0 /*line no*/, - NodeSizeInBits(type), - NodeAlignInBits(type), - 0 /*offset */, - Flags, - FromTy); + DIType PTy = + DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), PName, + getOrCreateCompileUnit(NULL), + 0 /*line no*/, + NodeSizeInBits(type), + NodeAlignInBits(type), + 0 /*offset */, + Flags, + FromTy); return PTy; } @@ -604,7 +599,8 @@ DebugFactory.GetOrCreateArray(Subscripts.data(), Subscripts.size()); expanded_location Loc = GetNodeLocation(type); return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type, - findRegion(type), StringRef(), + findRegion(TYPE_CONTEXT(type)), + StringRef(), getOrCreateCompileUnit(Loc.file), 0, NodeSizeInBits(type), NodeAlignInBits(type), 0, 0, @@ -635,7 +631,8 @@ Loc = GetNodeLocation(TREE_CHAIN(type), false); return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type, - findRegion(type), GetNodeName(type), + findRegion(TYPE_CONTEXT(type)), + GetNodeName(type), getOrCreateCompileUnit(Loc.file), Loc.line, NodeSizeInBits(type), @@ -692,18 +689,18 @@ StringRef TypeName = GetNodeName(type); if (!TypeName.empty()) FwdName = FwdName + TypeName.data(); - unsigned Flags = llvm::DIType::FlagFwdDecl; + unsigned SFlags = 0; if (TYPE_BLOCK_IMPL_STRUCT(type)) - Flags |= llvm::DIType::FlagAppleBlock; + SFlags |= llvm::DIType::FlagAppleBlock; if (type_is_block_byref_struct(type)) - Flags |= llvm::DIType::FlagBlockByrefStruct; + SFlags |= llvm::DIType::FlagBlockByrefStruct; llvm::DICompositeType FwdDecl = DebugFactory.CreateCompositeType(Tag, - findRegion(type), + findRegion(TYPE_CONTEXT(type)), FwdName.c_str(), getOrCreateCompileUnit(Loc.file), Loc.line, - 0, 0, 0, Flags, + 0, 0, 0, SFlags | llvm::DIType::FlagFwdDecl, llvm::DIType(), llvm::DIArray(), RunTimeLang); @@ -729,24 +726,24 @@ tree BInfo = BINFO_BASE_BINFO(binfo, i); tree BInfoType = BINFO_TYPE (BInfo); DIType BaseClass = getOrCreateType(BInfoType); - unsigned Flags = 0; + unsigned BFlags = 0; if (BINFO_VIRTUAL_P (BInfo)) - Flags = llvm::DIType::FlagVirtual; + BFlags = llvm::DIType::FlagVirtual; if (accesses) { tree access = VEC_index (tree, accesses, i); if (access == access_protected_node) - Flags |= llvm::DIType::FlagProtected; + BFlags |= llvm::DIType::FlagProtected; else if (access == access_private_node) - Flags |= llvm::DIType::FlagPrivate; + BFlags |= llvm::DIType::FlagPrivate; } // FIXME : name, size, align etc... DIType DTy = DebugFactory.CreateDerivedType(DW_TAG_inheritance, - findRegion(type), StringRef(), + findRegion(TYPE_CONTEXT(type)), StringRef(), llvm::DICompileUnit(), 0,0,0, getINTEGER_CSTVal(BINFO_OFFSET(BInfo))*8, - Flags, BaseClass); + BFlags, BaseClass); EltTys.push_back(DTy); } } @@ -777,20 +774,21 @@ tree FieldNodeType = FieldType(Member); DIType MemberType = getOrCreateType(FieldNodeType); StringRef MemberName = GetNodeName(Member); - unsigned Flags = 0; + unsigned MFlags = 0; if (TREE_PROTECTED(Member)) - Flags = llvm::DIType::FlagProtected; + MFlags = llvm::DIType::FlagProtected; else if (TREE_PRIVATE(Member)) - Flags = llvm::DIType::FlagPrivate; + MFlags = llvm::DIType::FlagPrivate; DIType DTy = - DebugFactory.CreateDerivedType(DW_TAG_member, findRegion(Member), + DebugFactory.CreateDerivedType(DW_TAG_member, + findRegion(DECL_CONTEXT(Member)), MemberName, getOrCreateCompileUnit(MemLoc.file), MemLoc.line, NodeSizeInBits(Member), NodeAlignInBits(FieldNodeType), int_bit_position(Member), - Flags, MemberType); + MFlags, MemberType); EltTys.push_back(DTy); } else { DEBUGASSERT(0 && "Unsupported member tree code!"); @@ -822,7 +820,8 @@ ContainingType = getOrCreateType(DECL_CONTEXT(Member)); } DISubprogram SP = - DebugFactory.CreateSubprogram(findRegion(Member), MemberName, MemberName, + DebugFactory.CreateSubprogram(findRegion(DECL_CONTEXT(Member)), + MemberName, MemberName, LinkageName, getOrCreateCompileUnit(MemLoc.file), MemLoc.line, SPTy, false, false, @@ -841,14 +840,15 @@ RegionMap.erase(RI); llvm::DICompositeType RealDecl = - DebugFactory.CreateCompositeType(Tag, findRegion(type), + DebugFactory.CreateCompositeType(Tag, findRegion(TYPE_CONTEXT(type)), GetNodeName(type), getOrCreateCompileUnit(Loc.file), Loc.line, NodeSizeInBits(type), NodeAlignInBits(type), - 0, Flags, llvm::DIType(), Elements, + 0, SFlags, llvm::DIType(), Elements, RunTimeLang); - + RegionMap[type] = WeakVH(RealDecl.getNode()); + // Now that we have a real decl for the struct, replace anything using the // old decl with the new one. This will recursively update the debug info. llvm::DIDerivedType(FwdDeclNode).replaceAllUsesWith(RealDecl); @@ -867,7 +867,8 @@ return DIType(cast(M)); if (TREE_CODE(TyDef) == TYPE_DECL && DECL_ORIGINAL_TYPE(TyDef)) { expanded_location TypeDefLoc = GetNodeLocation(TyDef); - Ty = DebugFactory.CreateDerivedType(DW_TAG_typedef, findRegion(TyDef), + Ty = DebugFactory.CreateDerivedType(DW_TAG_typedef, + findRegion(DECL_CONTEXT(TyDef)), GetNodeName(TyDef), getOrCreateCompileUnit(TypeDefLoc.file), TypeDefLoc.line, @@ -883,7 +884,8 @@ if (TYPE_VOLATILE(type)) { Ty = DebugFactory.CreateDerivedType(DW_TAG_volatile_type, - findRegion(type), StringRef(), + findRegion(TYPE_CONTEXT(type)), + StringRef(), getOrCreateCompileUnit(NULL), 0 /*line no*/, NodeSizeInBits(type), @@ -896,7 +898,8 @@ if (TYPE_READONLY(type)) Ty = DebugFactory.CreateDerivedType(DW_TAG_const_type, - findRegion(type), StringRef(), + findRegion(TYPE_CONTEXT(type)), + StringRef(), getOrCreateCompileUnit(NULL), 0 /*line no*/, NodeSizeInBits(type), From espindola at google.com Thu Dec 10 17:19:10 2009 From: espindola at google.com (Rafael Espindola) Date: Thu, 10 Dec 2009 18:19:10 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <860AC9D2-EA76-476F-9B1D-DA0E7BB0A651@apple.com> <35038F04-ED7A-4D60-ABD5-0CADD56536D2@apple.com> <38a0d8450911252018p3930f82cg43ebe9f6ded326c0@mail.gmail.com> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> Message-ID: <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> 2009/12/2 Rafael Espindola : >> I'm hoping Dale will weigh in on this soon, but I'm tentatively planning to add the byval support as soon as I get a chance (which may be a while). > > I have a small preference for expanding it early, but if most prefer > the byval solution I can give it a try. Not the highest priority item > for me right now, but might be able to help. Attached is a patch that makes llvm-gcc produce void @f(i32) and void @g(i32, i32, i32, i32, i16, i8) When given ----------------- struct foo { char[3] a; }; void f(struct foo x); void g(int a, int b, int c, int d, struct foo x); ---------------------- It is obviously wrong in that that it has the number of argument registers hardcoded. What is the best place to get that information in llvm-gcc? What gcc does is handle this in a target dependent location. I could also just add a #define to the different configs headers. arm.h already has a NUM_ARG_REGS... I think I would need the same information to implement the byval alternative. byval is normally used for things copied on the stack, so for function f above we would have to know that the struct would go in registers. In more complicated cases we have to split the structure. I will try to figure out how to run the testsuite with qemu this weekend. In a more long term note, I find the way we handle stacks very hard to understand :-( In the current way llvm-gcc is reverse engineering what llvm will do. It knows what will be in each register and the stack layout. It uses that information to map it to a llvm function signature that will be expanded again by the code generator. This is particularly bad for x86 that uses both byval and first class aggregates. What I would propose is making the argument placement explicit at the LLVM IL level. A case like struct foo {char a[5];}; void f(int a, int b, int c, foo d); would compile to %struct.f_stack_args = { i8 } declare arm_explicit void @f(i32, i32, i32, i32, %struct.f_stack_args) And a function like void g(void) { struct foo x = {5, 6, 7, 8, 9}; f(1, 2, 3, x); } would be compiled to define arm_explicit void @g() nounwind { entry: tail call arm_explicit void @g(i32 1, i32 2, i32 3, i32 134678021, {i8 9}) nounwind ret void } In this way almost all the lowering would be done in llvm-gcc/clang (preferably in a shared library). The backend would be a lot simpler since now every function would have at most 4 i32 args corresponding to each register and an argument representing the memory layout of the remaining C arguments. One thing I am not sure is where to put things like nocapture. Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: arm.patch Type: text/x-patch Size: 1762 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091210/d6f4068f/attachment.bin From dpatel at apple.com Thu Dec 10 17:25:41 2009 From: dpatel at apple.com (Devang Patel) Date: Thu, 10 Dec 2009 23:25:41 -0000 Subject: [llvm-commits] [llvm] r91077 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <200912102325.nBANPfXL001712@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 10 17:25:41 2009 New Revision: 91077 URL: http://llvm.org/viewvc/llvm-project?rev=91077&view=rev Log: If VariableDIe is not created (may be because global was optimzed away) then do not try to use the variable die. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=91077&r1=91076&r2=91077&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Dec 10 17:25:41 2009 @@ -1632,6 +1632,8 @@ return; DIE *VariableDie = createGlobalVariableDIE(DI_GV); + if (!VariableDie) + return; // Add to map. ModuleCU->insertDIE(N, VariableDie); From clattner at apple.com Thu Dec 10 17:56:12 2009 From: clattner at apple.com (Chris Lattner) Date: Thu, 10 Dec 2009 15:56:12 -0800 Subject: [llvm-commits] [llvm] r91062 - /llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll In-Reply-To: <200912102111.nBALBeuI029223@zion.cs.uiuc.edu> References: <200912102111.nBALBeuI029223@zion.cs.uiuc.edu> Message-ID: <98BD3549-2BD4-4153-A4FF-A165C69A1F1F@apple.com> Awesome, nice testcase! On Dec 10, 2009, at 1:11 PM, Eric Christopher wrote: > Author: echristo > Date: Thu Dec 10 15:11:40 2009 > New Revision: 91062 > > URL: http://llvm.org/viewvc/llvm-project?rev=91062&view=rev > Log: > Add a test for the fix in revision 91009. > > Added: > llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll > > Added: llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll?rev=91062&view=auto > > ============================================================================== > --- llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll (added) > +++ llvm/trunk/test/Transforms/LICM/2009-12-10-LICM-Indbr-Crash.ll Thu Dec 10 15:11:40 2009 > @@ -0,0 +1,20 @@ > +; RUN: opt < %s -licm -disable-output > +define void @foo (i8* %v) > +{ > + entry: > + br i1 undef, label %preheader, label %return > + > + preheader: > + br i1 undef, label %loop, label %return > + > + loop: > + indirectbr i8* undef, [label %preheader, label %stuff] > + > + stuff: > + %0 = load i8* undef, align 1 > + br label %loop > + > + return: > + ret void > + > +} > \ No newline at end of file > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Thu Dec 10 18:15:52 2009 From: dalej at apple.com (Dale Johannesen) Date: Thu, 10 Dec 2009 16:15:52 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <860AC9D2-EA76-476F-9B1D-DA0E7BB0A651@apple.com> <35038F04-ED7A-4D60-ABD5-0CADD56536D2@apple.com> <38a0d8450911252018p3930f82cg43ebe9f6ded326c0@mail.gmail.com> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> Message-ID: <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> On Dec 10, 2009, at 3:19 PMPST, Rafael Espindola wrote: > 2009/12/2 Rafael Espindola : >>> I'm hoping Dale will weigh in on this soon, but I'm tentatively >>> planning to add the byval support as soon as I get a chance (which >>> may be a while). All right, I'm back from vacation now. >> I have a small preference for expanding it early, but if most prefer >> the byval solution I can give it a try. Not the highest priority item >> for me right now, but might be able to help. > > Attached is a patch that makes llvm-gcc produce > void @f(i32) > and > void @g(i32, i32, i32, i32, i16, i8) > > When given > > ----------------- > struct foo { > char[3] a; > }; > > void f(struct foo x); > void g(int a, int b, int c, int d, struct foo x); I think it's a bad idea to try to do this in target-independent code. Whether the information goes in the high part or the low part of the register is target-dependent (there's some correlation with endianness), and just which structs need special treatment is also target-dependent. I think there's even a target where struct { char[3] a;} and struct { short a; char b; } are passed differently. I think most existing targets use byval, so I'd use that; there's lots of prior art to copy. > ---------------------- > > It is obviously wrong in that that it has the number of argument > registers hardcoded. What is the best place to get that information in > llvm-gcc? What gcc does is handle this in a target dependent location. > I could also just add a #define to the different configs headers. > arm.h already has a NUM_ARG_REGS... > > I think I would need the same information to implement the byval > alternative. byval is normally used for things copied on the stack, so > for function f above we would have to know that the struct would go in > registers. In more complicated cases we have to split the structure. > > I will try to figure out how to run the testsuite with qemu this > weekend. > > In a more long term note, I find the way we handle stacks very hard to > understand :-( > > In the current way llvm-gcc is reverse engineering what llvm will do. > It knows what will be in each register and the stack layout. It uses > that information to map it to a llvm function signature that will be > expanded again by the code generator. This is particularly bad for > x86 that uses both byval and first class aggregates. > > What I would propose is making the argument placement explicit at the > LLVM IL level. A case like > > struct foo {char a[5];}; > void f(int a, int b, int c, foo d); > > would compile to > %struct.f_stack_args = { i8 } > declare arm_explicit void @f(i32, i32, i32, i32, %struct.f_stack_args) > > And a function like > > void g(void) { > struct foo x = {5, 6, 7, 8, 9}; > f(1, 2, 3, x); > } > > would be compiled to > > define arm_explicit void @g() nounwind { > entry: > tail call arm_explicit void @g(i32 1, i32 2, i32 3, i32 134678021, > {i8 9}) nounwind > ret void > } > > In this way almost all the lowering would be done in llvm-gcc/clang > (preferably in a shared library). The backend would be a lot simpler > since now every function would have at most 4 i32 args corresponding > to each register and an argument representing the memory layout of the > remaining C arguments. > > One thing I am not sure is where to put things like nocapture. > > Cheers, > -- > Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: arm.patch Type: text/x-patch Size: 1763 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091210/a67c350d/attachment.bin -------------- next part -------------- From espindola at google.com Thu Dec 10 19:08:50 2009 From: espindola at google.com (Rafael Espindola) Date: Thu, 10 Dec 2009 20:08:50 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450911252018p3930f82cg43ebe9f6ded326c0@mail.gmail.com> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> Message-ID: <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> > I think it's a bad idea to try to do this in target-independent code. > ?Whether the information goes in the high part or the low part of the > register is target-dependent (there's some correlation with endianness), and > just which structs need special treatment is also target-dependent. ?I think > there's even a target where > ?struct { char[3] a;} > and > ?struct { short a; char b; } > are passed differently. > > I think most existing targets use byval, so I'd use that; there's lots of > prior art to copy. I think I failed to pass by point: How would you expand -------------------------- struct foo { char c[5]; }; void f(int a, int b, int c, struct foo d) { ... } ----------------------- Byval was created to force something to the stack (http://llvm.org/bugs/show_bug.cgi?id=1521). In this case the first 4 bytes have to go in a register. The last byte goes to the stack. I can use byval, but only for the last byte. I still need to know when the registers are over so that I can split the structure at that point. Cheers, -- Rafael ?vila de Esp?ndola From andersca at mac.com Thu Dec 10 19:04:42 2009 From: andersca at mac.com (Anders Carlsson) Date: Fri, 11 Dec 2009 01:04:42 -0000 Subject: [llvm-commits] [llvm] r91087 - /llvm/trunk/include/llvm/Support/CommandLine.h Message-ID: <200912110104.nBB14h0Y005026@zion.cs.uiuc.edu> Author: andersca Date: Thu Dec 10 19:04:42 2009 New Revision: 91087 URL: http://llvm.org/viewvc/llvm-project?rev=91087&view=rev Log: Add qualifiers for calls to member functions in dependent bases. Modified: llvm/trunk/include/llvm/Support/CommandLine.h Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=91087&r1=91086&r2=91087&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Thu Dec 10 19:04:42 2009 @@ -986,7 +986,7 @@ class list_storage : public std::vector { public: template - void addValue(const T &V) { push_back(V); } + void addValue(const T &V) { std::vector::push_back(V); } }; @@ -1011,7 +1011,7 @@ typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - addValue(Val); + list_storage::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; From grosbach at apple.com Thu Dec 10 19:42:04 2009 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 11 Dec 2009 01:42:04 -0000 Subject: [llvm-commits] [llvm] r91090 - in /llvm/trunk/lib/Target/ARM: ARMBaseInstrInfo.h ARMISelLowering.cpp ARMISelLowering.h ARMInstrFormats.td ARMInstrInfo.td Message-ID: <200912110142.nBB1g58o006336@zion.cs.uiuc.edu> Author: grosbach Date: Thu Dec 10 19:42:04 2009 New Revision: 91090 URL: http://llvm.org/viewvc/llvm-project?rev=91090&view=rev Log: Rough first pass at compare_and_swap atomic builtins for ARM mode. Work in progress. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=91090&r1=91089&r2=91090&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Dec 10 19:42:04 2009 @@ -92,6 +92,8 @@ StMiscFrm = 9 << FormShift, LdStMulFrm = 10 << FormShift, + LdStExFrm = 28 << FormShift, + // Miscellaneous arithmetic instructions ArithMiscFrm = 11 << FormShift, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=91090&r1=91089&r2=91090&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Dec 10 19:42:04 2009 @@ -3043,6 +3043,77 @@ //===----------------------------------------------------------------------===// MachineBasicBlock * +ARMTargetLowering::EmitAtomicCmpSwap(unsigned Size, MachineInstr *MI, + MachineBasicBlock *BB) const { + unsigned dest = MI->getOperand(0).getReg(); + unsigned ptr = MI->getOperand(1).getReg(); + unsigned oldval = MI->getOperand(2).getReg(); + unsigned newval = MI->getOperand(3).getReg(); + unsigned scratch = BB->getParent()->getRegInfo() + .createVirtualRegister(ARM::GPRRegisterClass); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + unsigned ldrOpc, strOpc; + switch (Size) { + default: llvm_unreachable("unsupported size for AtomicCmpSwap!"); + case 1: ldrOpc = ARM::LDREXB; strOpc = ARM::STREXB; break; + case 2: ldrOpc = ARM::LDREXH; strOpc = ARM::STREXH; break; + case 4: ldrOpc = ARM::LDREX; strOpc = ARM::STREX; break; + } + + MachineFunction *MF = BB->getParent(); + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator It = BB; + ++It; // insert the new blocks after the current block + + MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MF->insert(It, loop1MBB); + MF->insert(It, loop2MBB); + MF->insert(It, exitMBB); + exitMBB->transferSuccessors(BB); + + // thisMBB: + // ... + // fallthrough --> loop1MBB + BB->addSuccessor(loop1MBB); + + // loop1MBB: + // ldrex dest, [ptr] + // cmp dest, oldval + // bne exitMBB + BB = loop1MBB; + AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr)); + AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::CMPrr)) + .addReg(dest).addReg(oldval)); + BuildMI(BB, dl, TII->get(ARM::Bcc)).addMBB(exitMBB).addImm(ARMCC::NE) + .addReg(ARM::CPSR); + BB->addSuccessor(loop2MBB); + BB->addSuccessor(exitMBB); + + // loop2MBB: + // strex scratch, newval, [ptr] + // cmp scratch, #0 + // bne loop1MBB + BB = loop2MBB; + AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(newval) + .addReg(ptr)); + AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::CMPri)) + .addReg(scratch).addImm(0)); + BuildMI(BB, dl, TII->get(ARM::Bcc)).addMBB(loop1MBB).addImm(ARMCC::NE) + .addReg(ARM::CPSR); + BB->addSuccessor(loop1MBB); + BB->addSuccessor(exitMBB); + + // exitMBB: + // ... + BB = exitMBB; + return BB; +} + +MachineBasicBlock * ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB, DenseMap *EM) const { @@ -3050,7 +3121,16 @@ DebugLoc dl = MI->getDebugLoc(); switch (MI->getOpcode()) { default: + MI->dump(); llvm_unreachable("Unexpected instr type to insert"); + + + + + case ARM::ATOMIC_CMP_SWAP_I8: return EmitAtomicCmpSwap(1, MI, BB); + case ARM::ATOMIC_CMP_SWAP_I16: return EmitAtomicCmpSwap(2, MI, BB); + case ARM::ATOMIC_CMP_SWAP_I32: return EmitAtomicCmpSwap(4, MI, BB); + case ARM::tMOVCCr_pseudo: { // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=91090&r1=91089&r2=91090&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Thu Dec 10 19:42:04 2009 @@ -331,6 +331,10 @@ SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMCC, SelectionDAG &DAG, DebugLoc dl); + + MachineBasicBlock *EmitAtomicCmpSwap(unsigned Size, MachineInstr *MI, + MachineBasicBlock *BB) const; + }; } Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=91090&r1=91089&r2=91090&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Dec 10 19:42:04 2009 @@ -33,6 +33,8 @@ def StMiscFrm : Format<9>; def LdStMulFrm : Format<10>; +def LdStExFrm : Format<28>; + def ArithMiscFrm : Format<11>; def ExtFrm : Format<12>; @@ -264,6 +266,28 @@ : XI; + +// Atomic load/store instructions + +class AIldrex opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { + let Inst{27-23} = 0b00011; + let Inst{22-21} = opcod; + let Inst{20} = 1; + let Inst{11-0} = 0b111110011111; +} +class AIstrex opcod, dag oops, dag iops, InstrItinClass itin, + string opc, string asm, list pattern> + : I { + let Inst{27-23} = 0b00011; + let Inst{22-21} = opcod; + let Inst{20} = 0; + let Inst{11-0} = 0b111110011111; +} + // addrmode1 instructions class AI1 opcod, dag oops, dag iops, Format f, InstrItinClass itin, string opc, string asm, list pattern> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91090&r1=91089&r2=91090&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Dec 10 19:42:04 2009 @@ -1596,6 +1596,48 @@ } } +let usesCustomInserter = 1, mayLoad = 1, mayStore = 1 in { + def ATOMIC_CMP_SWAP_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; + def ATOMIC_CMP_SWAP_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; + def ATOMIC_CMP_SWAP_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; +} + +let mayLoad = 1 in { +def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, + "ldrexb", "\t$dest, [$ptr]", + []>; +def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, + "ldrexh", "\t$dest, [$ptr]", + []>; +def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, + "ldrex", "\t$dest, [$ptr]", + []>; +} + +let mayStore = 1 in { +def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), + NoItinerary, + "strexb", "\t$success, $src, [$ptr]", + []>; +def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), + NoItinerary, + "strexh", "\t$success, $src, [$ptr]", + []>; +def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), + NoItinerary, + "strex", "\t$success, $src, [$ptr]", + []>; +} + //===----------------------------------------------------------------------===// // TLS Instructions // From isanbard at gmail.com Thu Dec 10 19:49:14 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Dec 2009 01:49:14 -0000 Subject: [llvm-commits] [llvm] r91092 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/MachineBasicBlock.cpp Message-ID: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> Author: void Date: Thu Dec 10 19:49:14 2009 New Revision: 91092 URL: http://llvm.org/viewvc/llvm-project?rev=91092&view=rev Log: A machine basic block may end in an unconditional branch, however it may have more than one successor. Normally, these extra successors are dead. However, some of them may branch to exception handling landing pads. If we remove those successors, then the landing pads could go away if all predecessors to it are removed. Before, it was checking if the direct successor was the landing pad. But it could be the result of jumping through multiple basic blocks to get to it. If we were to only check for the existence of an EH_LABEL in the basic block and not remove successors if it's in there, then it could stop actually dead basic blocks from being removed. Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=91092&r1=91091&r2=91092&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Dec 10 19:49:14 2009 @@ -327,6 +327,11 @@ /// 'Old', change the code and CFG so that it branches to 'New' instead. void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); + /// BranchesToLandingPad - The basic block branches only to a landing pad or + /// to another basic block which branches only to a landing pad. No other + /// instructions are present other than the unconditional branch. + bool BranchesToLandingPad(const MachineBasicBlock *MBB) const; + /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in /// the CFG to be inserted. If we have proven that MBB can only branch to /// DestA and DestB, remove any other MBB successors from the CFG. DestA and Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91092&r1=91091&r2=91092&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Dec 10 19:49:14 2009 @@ -13,15 +13,16 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/BasicBlock.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrDesc.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Assembly/Writer.h" #include using namespace llvm; @@ -448,10 +449,35 @@ addSuccessor(New); } +/// BranchesToLandingPad - The basic block branches only to a landing pad or to +/// another basic block which branches only to a landing pad. No other +/// instructions are present other than the unconditional branch. +bool +MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock *MBB) const { + SmallSet Visited; + const MachineBasicBlock *CurMBB = MBB; + + while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { + if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) + break; + + const TargetInstrInfo *TII = + CurMBB->getParent()->getTarget().getInstrInfo(); + if (!TII->isUnpredicatedTerminator(CurMBB->begin())) + break; + + Visited.insert(CurMBB); + CurMBB = *CurMBB->succ_begin(); + } + + return CurMBB->isLandingPad(); +} + /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the /// CFG to be inserted. If we have proven that MBB can only branch to DestA and /// DestB, remove any other MBB successors from the CFG. DestA and DestB can /// be null. +/// /// Besides DestA and DestB, retain other edges leading to LandingPads /// (currently there can be only one; we don't check or require that here). /// Note it is possible that DestA and/or DestB are LandingPads. @@ -481,16 +507,17 @@ } MachineBasicBlock::succ_iterator SI = succ_begin(); - MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; + const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; while (SI != succ_end()) { - if (*SI == DestA) { + const MachineBasicBlock *MBB = *SI; + if (MBB == DestA) { DestA = 0; ++SI; - } else if (*SI == DestB) { + } else if (MBB == DestB) { DestB = 0; ++SI; - } else if ((*SI)->isLandingPad() && - *SI!=OrigDestA && *SI!=OrigDestB) { + } else if (BranchesToLandingPad(MBB) && + MBB != OrigDestA && MBB != OrigDestB) { ++SI; } else { // Otherwise, this is a superfluous edge, remove it. @@ -498,12 +525,14 @@ MadeChange = true; } } + if (!AddedFallThrough) { assert(DestA == 0 && DestB == 0 && "MachineCFG is missing edges!"); } else if (isCond) { assert(DestA == 0 && "MachineCFG is missing edges!"); } + return MadeChange; } From gohman at apple.com Thu Dec 10 21:01:49 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 10 Dec 2009 19:01:49 -0800 Subject: [llvm-commits] [llvm] r91092 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/MachineBasicBlock.cpp In-Reply-To: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> References: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> Message-ID: <6311BCFE-EFAF-443E-9AF7-2CE210D47822@apple.com> Hi Bill, See below for a few comments. On Dec 10, 2009, at 5:49 PM, Bill Wendling wrote: > Author: void > Date: Thu Dec 10 19:49:14 2009 > New Revision: 91092 > > URL: http://llvm.org/viewvc/llvm-project?rev=91092&view=rev > Log: > A machine basic block may end in an unconditional branch, however it may have > more than one successor. Normally, these extra successors are dead. However, > some of them may branch to exception handling landing pads. If we remove those > successors, then the landing pads could go away if all predecessors to it are > removed. Before, it was checking if the direct successor was the landing > pad. But it could be the result of jumping through multiple basic blocks to get > to it. If we were to only check for the existence of an EH_LABEL in the basic > block and not remove successors if it's in there, then it could stop actually > dead basic blocks from being removed. > > Modified: > llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h > llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp > > Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=91092&r1=91091&r2=91092&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) > +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Dec 10 19:49:14 2009 > @@ -327,6 +327,11 @@ > /// 'Old', change the code and CFG so that it branches to 'New' instead. > void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); > > + /// BranchesToLandingPad - The basic block branches only to a landing pad or > + /// to another basic block which branches only to a landing pad. No other > + /// instructions are present other than the unconditional branch. > + bool BranchesToLandingPad(const MachineBasicBlock *MBB) const; > + > /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in > /// the CFG to be inserted. If we have proven that MBB can only branch to > /// DestA and DestB, remove any other MBB successors from the CFG. DestA and > > Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91092&r1=91091&r2=91092&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Dec 10 19:49:14 2009 > @@ -13,15 +13,16 @@ > > #include "llvm/CodeGen/MachineBasicBlock.h" > #include "llvm/BasicBlock.h" > +#include "llvm/ADT/SmallSet.h" > +#include "llvm/Assembly/Writer.h" > #include "llvm/CodeGen/MachineFunction.h" > -#include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/Target/TargetData.h" > #include "llvm/Target/TargetInstrDesc.h" > #include "llvm/Target/TargetInstrInfo.h" > #include "llvm/Target/TargetMachine.h" > +#include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/Support/LeakDetector.h" > #include "llvm/Support/raw_ostream.h" > -#include "llvm/Assembly/Writer.h" > #include > using namespace llvm; > > @@ -448,10 +449,35 @@ > addSuccessor(New); > } > > +/// BranchesToLandingPad - The basic block branches only to a landing pad or to > +/// another basic block which branches only to a landing pad. No other > +/// instructions are present other than the unconditional branch. Looking at the code, this function returns true if the given MBB itself is a landing pad, not just if it branches to one; please mention this in the comment. > +bool > +MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock *MBB) const { > + SmallSet Visited; > + const MachineBasicBlock *CurMBB = MBB; > + > + while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { > + if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) Since you're checking for succ_size() != 1, the succ_empty() check is redundant. > + break; > + > + const TargetInstrInfo *TII = > + CurMBB->getParent()->getTarget().getInstrInfo(); > + if (!TII->isUnpredicatedTerminator(CurMBB->begin())) > + break; This check seems over-specific. > + > + Visited.insert(CurMBB); insert returns false if the element was already present, so if you want you can use that to avoid needing to do another lookup (the count call) each iteration. > + CurMBB = *CurMBB->succ_begin(); > + } > + > + return CurMBB->isLandingPad(); > +} > + > /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the > /// CFG to be inserted. If we have proven that MBB can only branch to DestA and > /// DestB, remove any other MBB successors from the CFG. DestA and DestB can > /// be null. > +/// > /// Besides DestA and DestB, retain other edges leading to LandingPads > /// (currently there can be only one; we don't check or require that here). > /// Note it is possible that DestA and/or DestB are LandingPads. > @@ -481,16 +507,17 @@ > } > > MachineBasicBlock::succ_iterator SI = succ_begin(); > - MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; > + const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; > while (SI != succ_end()) { > - if (*SI == DestA) { > + const MachineBasicBlock *MBB = *SI; > + if (MBB == DestA) { > DestA = 0; > ++SI; > - } else if (*SI == DestB) { > + } else if (MBB == DestB) { > DestB = 0; > ++SI; > - } else if ((*SI)->isLandingPad() && > - *SI!=OrigDestA && *SI!=OrigDestB) { > + } else if (BranchesToLandingPad(MBB) && > + MBB != OrigDestA && MBB != OrigDestB) { The != tests here are relatively cheap compared to the BranchesToLandingPad call, so it would be good to check them first. Dan > ++SI; > } else { > // Otherwise, this is a superfluous edge, remove it. > @@ -498,12 +525,14 @@ > MadeChange = true; > } > } > + > if (!AddedFallThrough) { > assert(DestA == 0 && DestB == 0 && > "MachineCFG is missing edges!"); > } else if (isCond) { > assert(DestA == 0 && "MachineCFG is missing edges!"); > } > + > return MadeChange; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Thu Dec 10 21:04:19 2009 From: gohman at apple.com (Dan Gohman) Date: Thu, 10 Dec 2009 19:04:19 -0800 Subject: [llvm-commits] [llvm] r91092 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/MachineBasicBlock.cpp In-Reply-To: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> References: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> Message-ID: Hi Bill, See below for a few comments. On Dec 10, 2009, at 5:49 PM, Bill Wendling wrote: > Author: void > Date: Thu Dec 10 19:49:14 2009 > New Revision: 91092 > > URL: http://llvm.org/viewvc/llvm-project?rev=91092&view=rev > Log: > A machine basic block may end in an unconditional branch, however it may have > more than one successor. Normally, these extra successors are dead. However, > some of them may branch to exception handling landing pads. If we remove those > successors, then the landing pads could go away if all predecessors to it are > removed. Before, it was checking if the direct successor was the landing > pad. But it could be the result of jumping through multiple basic blocks to get > to it. If we were to only check for the existence of an EH_LABEL in the basic > block and not remove successors if it's in there, then it could stop actually > dead basic blocks from being removed. > > Modified: > llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h > llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp > > Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=91092&r1=91091&r2=91092&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) > +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Dec 10 19:49:14 2009 > @@ -327,6 +327,11 @@ > /// 'Old', change the code and CFG so that it branches to 'New' instead. > void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); > > + /// BranchesToLandingPad - The basic block branches only to a landing pad or > + /// to another basic block which branches only to a landing pad. No other > + /// instructions are present other than the unconditional branch. > + bool BranchesToLandingPad(const MachineBasicBlock *MBB) const; > + > /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in > /// the CFG to be inserted. If we have proven that MBB can only branch to > /// DestA and DestB, remove any other MBB successors from the CFG. DestA and > > Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91092&r1=91091&r2=91092&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) > +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Dec 10 19:49:14 2009 > @@ -13,15 +13,16 @@ > > #include "llvm/CodeGen/MachineBasicBlock.h" > #include "llvm/BasicBlock.h" > +#include "llvm/ADT/SmallSet.h" > +#include "llvm/Assembly/Writer.h" > #include "llvm/CodeGen/MachineFunction.h" > -#include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/Target/TargetData.h" > #include "llvm/Target/TargetInstrDesc.h" > #include "llvm/Target/TargetInstrInfo.h" > #include "llvm/Target/TargetMachine.h" > +#include "llvm/Target/TargetRegisterInfo.h" > #include "llvm/Support/LeakDetector.h" > #include "llvm/Support/raw_ostream.h" > -#include "llvm/Assembly/Writer.h" > #include > using namespace llvm; > > @@ -448,10 +449,35 @@ > addSuccessor(New); > } > > +/// BranchesToLandingPad - The basic block branches only to a landing pad or to > +/// another basic block which branches only to a landing pad. No other > +/// instructions are present other than the unconditional branch. Looking at the code, this function returns true if the given MBB itself is a landing pad, not just if it branches to one; please mention this in the comment. > +bool > +MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock *MBB) const { > + SmallSet Visited; > + const MachineBasicBlock *CurMBB = MBB; > + > + while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { > + if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) Since you're checking for succ_size() != 1, the succ_empty() check is redundant. > + break; > + > + const TargetInstrInfo *TII = > + CurMBB->getParent()->getTarget().getInstrInfo(); > + if (!TII->isUnpredicatedTerminator(CurMBB->begin())) > + break; This check seems over-specific. > + > + Visited.insert(CurMBB); insert returns false if the element was already present, so if you want you can reorganize things to avoid needing to do another lookup (the count call) each iteration. > + CurMBB = *CurMBB->succ_begin(); > + } > + > + return CurMBB->isLandingPad(); > +} > + > /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the > /// CFG to be inserted. If we have proven that MBB can only branch to DestA and > /// DestB, remove any other MBB successors from the CFG. DestA and DestB can > /// be null. > +/// > /// Besides DestA and DestB, retain other edges leading to LandingPads > /// (currently there can be only one; we don't check or require that here). > /// Note it is possible that DestA and/or DestB are LandingPads. > @@ -481,16 +507,17 @@ > } > > MachineBasicBlock::succ_iterator SI = succ_begin(); > - MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; > + const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; > while (SI != succ_end()) { > - if (*SI == DestA) { > + const MachineBasicBlock *MBB = *SI; > + if (MBB == DestA) { > DestA = 0; > ++SI; > - } else if (*SI == DestB) { > + } else if (MBB == DestB) { > DestB = 0; > ++SI; > - } else if ((*SI)->isLandingPad() && > - *SI!=OrigDestA && *SI!=OrigDestB) { > + } else if (BranchesToLandingPad(MBB) && > + MBB != OrigDestA && MBB != OrigDestB) { The != tests here are relatively cheap compared to the BranchesToLandingPad call, so it would be good to check them first. Dan > ++SI; > } else { > // Otherwise, this is a superfluous edge, remove it. > @@ -498,12 +525,14 @@ > MadeChange = true; > } > } > + > if (!AddedFallThrough) { > assert(DestA == 0 && DestB == 0 && > "MachineCFG is missing edges!"); > } else if (isCond) { > assert(DestA == 0 && "MachineCFG is missing edges!"); > } > + > return MadeChange; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Thu Dec 10 21:14:18 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Dec 2009 03:14:18 -0000 Subject: [llvm-commits] [llvm] r91101 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/MachineBasicBlock.cpp Message-ID: <200912110314.nBB3EI1N009630@zion.cs.uiuc.edu> Author: void Date: Thu Dec 10 21:14:18 2009 New Revision: 91101 URL: http://llvm.org/viewvc/llvm-project?rev=91101&view=rev Log: Address comments on last patch: - Loosen the restrictions when checking of it branches to a landing pad. - Make the loop more efficient by checking the '.insert' return value. - Do cheaper checks first. Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=91101&r1=91100&r2=91101&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Dec 10 21:14:18 2009 @@ -327,9 +327,9 @@ /// 'Old', change the code and CFG so that it branches to 'New' instead. void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); - /// BranchesToLandingPad - The basic block branches only to a landing pad or - /// to another basic block which branches only to a landing pad. No other - /// instructions are present other than the unconditional branch. + /// BranchesToLandingPad - The basic block is a landing pad or branches only + /// to a landing pad. No other instructions are present other than the + /// unconditional branch. bool BranchesToLandingPad(const MachineBasicBlock *MBB) const; /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91101&r1=91100&r2=91101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Dec 10 21:14:18 2009 @@ -449,24 +449,19 @@ addSuccessor(New); } -/// BranchesToLandingPad - The basic block branches only to a landing pad or to -/// another basic block which branches only to a landing pad. No other -/// instructions are present other than the unconditional branch. +/// BranchesToLandingPad - The basic block is a landing pad or branches only to +/// a landing pad. No other instructions are present other than the +/// unconditional branch. bool MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock *MBB) const { SmallSet Visited; const MachineBasicBlock *CurMBB = MBB; - while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { - if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) + while (!CurMBB->isLandingPad()) { + if (CurMBB->succ_size() != 1) break; - const TargetInstrInfo *TII = - CurMBB->getParent()->getTarget().getInstrInfo(); - if (!TII->isUnpredicatedTerminator(CurMBB->begin())) - break; - - Visited.insert(CurMBB); + if (!Visited.insert(CurMBB)) break; CurMBB = *CurMBB->succ_begin(); } @@ -516,8 +511,8 @@ } else if (MBB == DestB) { DestB = 0; ++SI; - } else if (BranchesToLandingPad(MBB) && - MBB != OrigDestA && MBB != OrigDestB) { + } else if (MBB != OrigDestA && MBB != OrigDestB && + BranchesToLandingPad(MBB)) { ++SI; } else { // Otherwise, this is a superfluous edge, remove it. From isanbard at gmail.com Thu Dec 10 21:16:45 2009 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 10 Dec 2009 19:16:45 -0800 Subject: [llvm-commits] [llvm] r91092 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/MachineBasicBlock.cpp In-Reply-To: <6311BCFE-EFAF-443E-9AF7-2CE210D47822@apple.com> References: <200912110149.nBB1nEv4006566@zion.cs.uiuc.edu> <6311BCFE-EFAF-443E-9AF7-2CE210D47822@apple.com> Message-ID: <16A3B3D1-7479-4F00-BC3D-625EEFEF1925@gmail.com> Done here r91101. Thanks, Dan! -bw On Dec 10, 2009, at 7:01 PM, Dan Gohman wrote: > Hi Bill, > > See below for a few comments. > > On Dec 10, 2009, at 5:49 PM, Bill Wendling wrote: > >> Author: void >> Date: Thu Dec 10 19:49:14 2009 >> New Revision: 91092 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=91092&view=rev >> Log: >> A machine basic block may end in an unconditional branch, however >> it may have >> more than one successor. Normally, these extra successors are dead. >> However, >> some of them may branch to exception handling landing pads. If we >> remove those >> successors, then the landing pads could go away if all predecessors >> to it are >> removed. Before, it was checking if the direct successor was the >> landing >> pad. But it could be the result of jumping through multiple basic >> blocks to get >> to it. If we were to only check for the existence of an EH_LABEL in >> the basic >> block and not remove successors if it's in there, then it could >> stop actually >> dead basic blocks from being removed. >> >> Modified: >> llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h >> llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp >> >> Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=91092&r1=91091&r2=91092&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original) >> +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Dec 10 >> 19:49:14 2009 >> @@ -327,6 +327,11 @@ >> /// 'Old', change the code and CFG so that it branches to 'New' >> instead. >> void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, >> MachineBasicBlock *New); >> >> + /// BranchesToLandingPad - The basic block branches only to a >> landing pad or >> + /// to another basic block which branches only to a landing pad. >> No other >> + /// instructions are present other than the unconditional branch. >> + bool BranchesToLandingPad(const MachineBasicBlock *MBB) const; >> + >> /// CorrectExtraCFGEdges - Various pieces of code can cause excess >> edges in >> /// the CFG to be inserted. If we have proven that MBB can only >> branch to >> /// DestA and DestB, remove any other MBB successors from the CFG. >> DestA and >> >> Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91092&r1=91091&r2=91092&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) >> +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Dec 10 >> 19:49:14 2009 >> @@ -13,15 +13,16 @@ >> >> #include "llvm/CodeGen/MachineBasicBlock.h" >> #include "llvm/BasicBlock.h" >> +#include "llvm/ADT/SmallSet.h" >> +#include "llvm/Assembly/Writer.h" >> #include "llvm/CodeGen/MachineFunction.h" >> -#include "llvm/Target/TargetRegisterInfo.h" >> #include "llvm/Target/TargetData.h" >> #include "llvm/Target/TargetInstrDesc.h" >> #include "llvm/Target/TargetInstrInfo.h" >> #include "llvm/Target/TargetMachine.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> #include "llvm/Support/LeakDetector.h" >> #include "llvm/Support/raw_ostream.h" >> -#include "llvm/Assembly/Writer.h" >> #include >> using namespace llvm; >> >> @@ -448,10 +449,35 @@ >> addSuccessor(New); >> } >> >> +/// BranchesToLandingPad - The basic block branches only to a >> landing pad or to >> +/// another basic block which branches only to a landing pad. No >> other >> +/// instructions are present other than the unconditional branch. > > Looking at the code, this function returns true if the given MBB > itself > is a landing pad, not just if it branches to one; please mention this > in the comment. > >> +bool >> +MachineBasicBlock::BranchesToLandingPad(const MachineBasicBlock >> *MBB) const { >> + SmallSet Visited; >> + const MachineBasicBlock *CurMBB = MBB; >> + >> + while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { >> + if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB- >> >succ_size() != 1) > > Since you're checking for succ_size() != 1, the succ_empty() check is > redundant. > >> + break; >> + >> + const TargetInstrInfo *TII = >> + CurMBB->getParent()->getTarget().getInstrInfo(); >> + if (!TII->isUnpredicatedTerminator(CurMBB->begin())) >> + break; > > This check seems over-specific. > >> + >> + Visited.insert(CurMBB); > > insert returns false if the element was already present, so if you > want > you can use that to avoid needing to do another lookup (the > count call) each iteration. > >> + CurMBB = *CurMBB->succ_begin(); >> + } >> + >> + return CurMBB->isLandingPad(); >> +} >> + >> /// CorrectExtraCFGEdges - Various pieces of code can cause excess >> edges in the >> /// CFG to be inserted. If we have proven that MBB can only branch >> to DestA and >> /// DestB, remove any other MBB successors from the CFG. DestA and >> DestB can >> /// be null. >> +/// >> /// Besides DestA and DestB, retain other edges leading to >> LandingPads >> /// (currently there can be only one; we don't check or require >> that here). >> /// Note it is possible that DestA and/or DestB are LandingPads. >> @@ -481,16 +507,17 @@ >> } >> >> MachineBasicBlock::succ_iterator SI = succ_begin(); >> - MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; >> + const MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB; >> while (SI != succ_end()) { >> - if (*SI == DestA) { >> + const MachineBasicBlock *MBB = *SI; >> + if (MBB == DestA) { >> DestA = 0; >> ++SI; >> - } else if (*SI == DestB) { >> + } else if (MBB == DestB) { >> DestB = 0; >> ++SI; >> - } else if ((*SI)->isLandingPad() && >> - *SI!=OrigDestA && *SI!=OrigDestB) { >> + } else if (BranchesToLandingPad(MBB) && >> + MBB != OrigDestA && MBB != OrigDestB) { > > The != tests here are relatively cheap compared to the > BranchesToLandingPad call, so it would be good to check > them first. > > Dan > >> ++SI; >> } else { >> // Otherwise, this is a superfluous edge, remove it. >> @@ -498,12 +525,14 @@ >> MadeChange = true; >> } >> } >> + >> if (!AddedFallThrough) { >> assert(DestA == 0 && DestB == 0 && >> "MachineCFG is missing edges!"); >> } else if (isCond) { >> assert(DestA == 0 && "MachineCFG is missing edges!"); >> } >> + >> return MadeChange; >> } >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Fri Dec 11 00:01:00 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Dec 2009 06:01:00 -0000 Subject: [llvm-commits] [llvm] r91103 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp SimpleRegisterCoalescing.cpp Message-ID: <200912110601.nBB611If014462@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 11 00:01:00 2009 New Revision: 91103 URL: http://llvm.org/viewvc/llvm-project?rev=91103&view=rev Log: Coalesce insert_subreg undef, x first to avoid phase ordering issue. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=91103&r1=91102&r2=91103&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Dec 11 00:01:00 2009 @@ -745,8 +745,16 @@ if (VNI->getCopy()->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { // If it's extracting out of a physical register, return the sub-register. unsigned Reg = VNI->getCopy()->getOperand(1).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + unsigned SrcSubReg = VNI->getCopy()->getOperand(2).getImm(); + unsigned DstSubReg = VNI->getCopy()->getOperand(0).getSubReg(); + if (SrcSubReg == DstSubReg) + // %reg1034:3 = EXTRACT_SUBREG %EDX, 3 + // reg1034 can still be coalesced to EDX. + return Reg; + assert(DstSubReg == 0); Reg = tri_->getSubReg(Reg, VNI->getCopy()->getOperand(2).getImm()); + } return Reg; } else if (VNI->getCopy()->getOpcode() == TargetInstrInfo::INSERT_SUBREG || VNI->getCopy()->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=91103&r1=91102&r2=91103&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Fri Dec 11 00:01:00 2009 @@ -2422,9 +2422,15 @@ // If this isn't a copy nor a extract_subreg, we can't join intervals. unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + bool isInsUndef = false; if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) { DstReg = Inst->getOperand(0).getReg(); SrcReg = Inst->getOperand(1).getReg(); + } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG) { + DstReg = Inst->getOperand(0).getReg(); + SrcReg = Inst->getOperand(2).getReg(); + if (Inst->getOperand(1).isUndef()) + isInsUndef = true; } else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG || Inst->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) { DstReg = Inst->getOperand(0).getReg(); @@ -2434,7 +2440,8 @@ bool SrcIsPhys = TargetRegisterInfo::isPhysicalRegister(SrcReg); bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg); - if (li_->hasInterval(SrcReg) && li_->getInterval(SrcReg).empty()) + if (isInsUndef || + (li_->hasInterval(SrcReg) && li_->getInterval(SrcReg).empty())) ImpDefCopies.push_back(CopyRec(Inst, 0)); else if (SrcIsPhys || DstIsPhys) PhysCopies.push_back(CopyRec(Inst, 0)); @@ -2442,9 +2449,9 @@ VirtCopies.push_back(CopyRec(Inst, 0)); } - // Try coalescing implicit copies first, followed by copies to / from - // physical registers, then finally copies from virtual registers to - // virtual registers. + // Try coalescing implicit copies and insert_subreg first, + // followed by copies to / from physical registers, then finally copies + // from virtual registers to virtual registers. for (unsigned i = 0, e = ImpDefCopies.size(); i != e; ++i) { CopyRec &TheCopy = ImpDefCopies[i]; bool Again = false; From evan.cheng at apple.com Fri Dec 11 00:01:48 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Dec 2009 06:01:48 -0000 Subject: [llvm-commits] [llvm] r91104 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.h Message-ID: <200912110601.nBB61mfT014511@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 11 00:01:48 2009 New Revision: 91104 URL: http://llvm.org/viewvc/llvm-project?rev=91104&view=rev Log: Add support to 3-addressify 16-bit instructions. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=91104&r1=91103&r2=91104&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 11 00:01:48 2009 @@ -1058,6 +1058,107 @@ return false; } +/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when 16-bit +/// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting +/// to a 32-bit superregister and then truncating back down to a 16-bit +/// subregister. +MachineInstr * +X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc, + MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const { + MachineInstr *MI = MBBI; + unsigned Dest = MI->getOperand(0).getReg(); + unsigned Src = MI->getOperand(1).getReg(); + bool isDead = MI->getOperand(0).isDead(); + bool isKill = MI->getOperand(1).isKill(); + + unsigned Opc = TM.getSubtarget().is64Bit() + ? X86::LEA64_32r : X86::LEA32r; + MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo(); + unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32RegClass); + unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass); + + // Build and insert into an implicit UNDEF value. This is OK because + // well be shifting and then extracting the lower 16-bits. + BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg); + MachineInstr *InsMI = + BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg) + .addReg(leaInReg) + .addReg(Src, getKillRegState(isKill)) + .addImm(X86::SUBREG_16BIT); + + MachineInstrBuilder MIB = BuildMI(*MFI, MBBI, MI->getDebugLoc(), + get(Opc), leaOutReg); + switch (MIOpc) { + default: + llvm_unreachable(0); + break; + case X86::SHL16ri: { + unsigned ShAmt = MI->getOperand(2).getImm(); + MIB.addReg(0).addImm(1 << ShAmt) + .addReg(leaInReg, RegState::Kill).addImm(0); + break; + } + case X86::INC16r: + case X86::INC64_16r: + addLeaRegOffset(MIB, leaInReg, true, 1); + break; + case X86::DEC16r: + case X86::DEC64_16r: + addLeaRegOffset(MIB, leaInReg, true, -1); + break; + case X86::ADD16ri: + case X86::ADD16ri8: + addLeaRegOffset(MIB, leaInReg, true, MI->getOperand(2).getImm()); + break; + case X86::ADD16rr: { + unsigned Src2 = MI->getOperand(2).getReg(); + bool isKill2 = MI->getOperand(2).isKill(); + unsigned leaInReg2 = 0; + MachineInstr *InsMI2 = 0; + if (Src == Src2) { + // ADD16rr %reg1028, %reg1028 + // just a single insert_subreg. + addRegReg(MIB, leaInReg, true, leaInReg, false); + } else { + leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32RegClass); + // Build and insert into an implicit UNDEF value. This is OK because + // well be shifting and then extracting the lower 16-bits. + BuildMI(*MFI, MIB, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg2); + InsMI2 = + BuildMI(*MFI, MIB, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg2) + .addReg(leaInReg2) + .addReg(Src2, getKillRegState(isKill2)) + .addImm(X86::SUBREG_16BIT); + addRegReg(MIB, leaInReg, true, leaInReg2, true); + } + if (LV && isKill2 && InsMI2) + LV->replaceKillInstruction(Src2, MI, InsMI2); + break; + } + } + + MachineInstr *NewMI = MIB; + MachineInstr *ExtMI = + BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG)) + .addReg(Dest, RegState::Define | getDeadRegState(isDead)) + .addReg(leaOutReg, RegState::Kill) + .addImm(X86::SUBREG_16BIT); + + if (LV) { + // Update live variables + LV->getVarInfo(leaInReg).Kills.push_back(NewMI); + LV->getVarInfo(leaOutReg).Kills.push_back(ExtMI); + if (isKill) + LV->replaceKillInstruction(Src, MI, InsMI); + if (isDead) + LV->replaceKillInstruction(Dest, MI, ExtMI); + } + + return ExtMI; +} + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into a true @@ -1137,51 +1238,13 @@ unsigned ShAmt = MI->getOperand(2).getImm(); if (ShAmt == 0 || ShAmt >= 4) return 0; - if (DisableLEA16) { - // If 16-bit LEA is disabled, use 32-bit LEA via subregisters. - MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo(); - unsigned Opc = TM.getSubtarget().is64Bit() - ? X86::LEA64_32r : X86::LEA32r; - unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32RegClass); - unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass); - - // Build and insert into an implicit UNDEF value. This is OK because - // well be shifting and then extracting the lower 16-bits. - BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg); - MachineInstr *InsMI = - BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg) - .addReg(leaInReg) - .addReg(Src, getKillRegState(isKill)) - .addImm(X86::SUBREG_16BIT); - - NewMI = BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(Opc), leaOutReg) - .addReg(0).addImm(1 << ShAmt) - .addReg(leaInReg, RegState::Kill) - .addImm(0); - - MachineInstr *ExtMI = - BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG)) - .addReg(Dest, RegState::Define | getDeadRegState(isDead)) - .addReg(leaOutReg, RegState::Kill) - .addImm(X86::SUBREG_16BIT); - - if (LV) { - // Update live variables - LV->getVarInfo(leaInReg).Kills.push_back(NewMI); - LV->getVarInfo(leaOutReg).Kills.push_back(ExtMI); - if (isKill) - LV->replaceKillInstruction(Src, MI, InsMI); - if (isDead) - LV->replaceKillInstruction(Dest, MI, ExtMI); - } - return ExtMI; - } else { - NewMI = BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) - .addReg(Dest, RegState::Define | getDeadRegState(isDead)) - .addReg(0).addImm(1 << ShAmt) - .addReg(Src, getKillRegState(isKill)) - .addImm(0); - } + if (DisableLEA16) + return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + NewMI = BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) + .addReg(Dest, RegState::Define | getDeadRegState(isDead)) + .addReg(0).addImm(1 << ShAmt) + .addReg(Src, getKillRegState(isKill)) + .addImm(0); break; } default: { @@ -1208,7 +1271,8 @@ } case X86::INC16r: case X86::INC64_16r: - if (DisableLEA16) return 0; + if (DisableLEA16) + return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!"); NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | @@ -1229,7 +1293,8 @@ } case X86::DEC16r: case X86::DEC64_16r: - if (DisableLEA16) return 0; + if (DisableLEA16) + return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!"); NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | @@ -1252,7 +1317,8 @@ break; } case X86::ADD16rr: { - if (DisableLEA16) return 0; + if (DisableLEA16) + return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); unsigned Src2 = MI->getOperand(2).getReg(); bool isKill2 = MI->getOperand(2).isKill(); @@ -1267,56 +1333,32 @@ case X86::ADD64ri32: case X86::ADD64ri8: assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); - if (MI->getOperand(2).isImm()) - NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA64r)) - .addReg(Dest, RegState::Define | - getDeadRegState(isDead)), - Src, isKill, MI->getOperand(2).getImm()); + NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA64r)) + .addReg(Dest, RegState::Define | + getDeadRegState(isDead)), + Src, isKill, MI->getOperand(2).getImm()); break; case X86::ADD32ri: - case X86::ADD32ri8: + case X86::ADD32ri8: { assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); - if (MI->getOperand(2).isImm()) { - unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; - NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc)) - .addReg(Dest, RegState::Define | - getDeadRegState(isDead)), + unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; + NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(Opc)) + .addReg(Dest, RegState::Define | + getDeadRegState(isDead)), Src, isKill, MI->getOperand(2).getImm()); - } break; + } case X86::ADD16ri: case X86::ADD16ri8: - if (DisableLEA16) return 0; + if (DisableLEA16) + return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); - if (MI->getOperand(2).isImm()) - NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) - .addReg(Dest, RegState::Define | - getDeadRegState(isDead)), - Src, isKill, MI->getOperand(2).getImm()); - break; - case X86::SHL16ri: - if (DisableLEA16) return 0; - case X86::SHL32ri: - case X86::SHL64ri: { - assert(MI->getNumOperands() >= 3 && MI->getOperand(2).isImm() && - "Unknown shl instruction!"); - unsigned ShAmt = MI->getOperand(2).getImm(); - if (ShAmt == 1 || ShAmt == 2 || ShAmt == 3) { - X86AddressMode AM; - AM.Scale = 1 << ShAmt; - AM.IndexReg = Src; - unsigned Opc = MIOpc == X86::SHL64ri ? X86::LEA64r - : (MIOpc == X86::SHL32ri - ? (is64Bit ? X86::LEA64_32r : X86::LEA32r) : X86::LEA16r); - NewMI = addFullAddress(BuildMI(MF, MI->getDebugLoc(), get(Opc)) - .addReg(Dest, RegState::Define | - getDeadRegState(isDead)), AM); - if (isKill) - NewMI->getOperand(3).setIsKill(true); - } + NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) + .addReg(Dest, RegState::Define | + getDeadRegState(isDead)), + Src, isKill, MI->getOperand(2).getImm()); break; } - } } } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=91104&r1=91103&r2=91104&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Fri Dec 11 00:01:48 2009 @@ -637,6 +637,11 @@ unsigned getGlobalBaseReg(MachineFunction *MF) const; private: + MachineInstr * convertToThreeAddressWithLEA(unsigned MIOpc, + MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const; + MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, unsigned OpNum, From evan.cheng at apple.com Fri Dec 11 00:02:21 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 11 Dec 2009 06:02:21 -0000 Subject: [llvm-commits] [llvm] r91105 - /llvm/trunk/test/CodeGen/X86/3addr-16bit.ll Message-ID: <200912110602.nBB62LoV014535@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 11 00:02:21 2009 New Revision: 91105 URL: http://llvm.org/viewvc/llvm-project?rev=91105&view=rev Log: Tests for 91103 and 91104. Added: llvm/trunk/test/CodeGen/X86/3addr-16bit.ll Added: llvm/trunk/test/CodeGen/X86/3addr-16bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/3addr-16bit.ll?rev=91105&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/3addr-16bit.ll (added) +++ llvm/trunk/test/CodeGen/X86/3addr-16bit.ll Fri Dec 11 00:02:21 2009 @@ -0,0 +1,93 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin -asm-verbose=false | FileCheck %s -check-prefix=32BIT +; RUN: llc < %s -mtriple=x86_64-apple-darwin -asm-verbose=false | FileCheck %s -check-prefix=64BIT + +define zeroext i16 @t1(i16 zeroext %c, i16 zeroext %k) nounwind ssp { +entry: +; 32BIT: t1: +; 32BIT: movw 20(%esp), %ax +; 32BIT-NOT: movw %ax, %cx +; 32BIT: leal 1(%eax), %ecx + +; 64BIT: t1: +; 64BIT-NOT: movw %si, %ax +; 64BIT: leal 1(%rsi), %eax + %0 = icmp eq i16 %k, %c ; [#uses=1] + %1 = add i16 %k, 1 ; [#uses=3] + br i1 %0, label %bb, label %bb1 + +bb: ; preds = %entry + tail call void @foo(i16 zeroext %1) nounwind + ret i16 %1 + +bb1: ; preds = %entry + ret i16 %1 +} + +define zeroext i16 @t2(i16 zeroext %c, i16 zeroext %k) nounwind ssp { +entry: +; 32BIT: t2: +; 32BIT: movw 20(%esp), %ax +; 32BIT-NOT: movw %ax, %cx +; 32BIT: leal -1(%eax), %ecx + +; 64BIT: t2: +; 64BIT-NOT: movw %si, %ax +; 64BIT: leal -1(%rsi), %eax + %0 = icmp eq i16 %k, %c ; [#uses=1] + %1 = add i16 %k, -1 ; [#uses=3] + br i1 %0, label %bb, label %bb1 + +bb: ; preds = %entry + tail call void @foo(i16 zeroext %1) nounwind + ret i16 %1 + +bb1: ; preds = %entry + ret i16 %1 +} + +declare void @foo(i16 zeroext) + +define zeroext i16 @t3(i16 zeroext %c, i16 zeroext %k) nounwind ssp { +entry: +; 32BIT: t3: +; 32BIT: movw 20(%esp), %ax +; 32BIT-NOT: movw %ax, %cx +; 32BIT: leal 2(%eax), %ecx + +; 64BIT: t3: +; 64BIT-NOT: movw %si, %ax +; 64BIT: leal 2(%rsi), %eax + %0 = add i16 %k, 2 ; [#uses=3] + %1 = icmp eq i16 %k, %c ; [#uses=1] + br i1 %1, label %bb, label %bb1 + +bb: ; preds = %entry + tail call void @foo(i16 zeroext %0) nounwind + ret i16 %0 + +bb1: ; preds = %entry + ret i16 %0 +} + +define zeroext i16 @t4(i16 zeroext %c, i16 zeroext %k) nounwind ssp { +entry: +; 32BIT: t4: +; 32BIT: movw 16(%esp), %ax +; 32BIT: movw 20(%esp), %cx +; 32BIT-NOT: movw %cx, %dx +; 32BIT: leal (%ecx,%eax), %edx + +; 64BIT: t4: +; 64BIT-NOT: movw %si, %ax +; 64BIT: leal (%rsi,%rdi), %eax + %0 = add i16 %k, %c ; [#uses=3] + %1 = icmp eq i16 %k, %c ; [#uses=1] + br i1 %1, label %bb, label %bb1 + +bb: ; preds = %entry + tail call void @foo(i16 zeroext %0) nounwind + ret i16 %0 + +bb1: ; preds = %entry + ret i16 %0 +} From baldrick at free.fr Fri Dec 11 02:36:18 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 08:36:18 -0000 Subject: [llvm-commits] [llvm] r91109 - in /llvm/trunk: include/llvm/Argument.h lib/VMCore/Function.cpp Message-ID: <200912110836.nBB8aI3b019917@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 02:36:17 2009 New Revision: 91109 URL: http://llvm.org/viewvc/llvm-project?rev=91109&view=rev Log: Add utility method for determining whether a function argument has the 'nest' attribute. Modified: llvm/trunk/include/llvm/Argument.h llvm/trunk/lib/VMCore/Function.cpp Modified: llvm/trunk/include/llvm/Argument.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Argument.h?rev=91109&r1=91108&r2=91109&view=diff ============================================================================== --- llvm/trunk/include/llvm/Argument.h (original) +++ llvm/trunk/include/llvm/Argument.h Fri Dec 11 02:36:17 2009 @@ -51,6 +51,10 @@ /// in its containing function. bool hasByValAttr() const; + /// hasNestAttr - Return true if this argument has the nest attribute on + /// it in its containing function. + bool hasNestAttr() const; + /// hasNoAliasAttr - Return true if this argument has the noalias attribute on /// it in its containing function. bool hasNoAliasAttr() const; Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=91109&r1=91108&r2=91109&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Fri Dec 11 02:36:17 2009 @@ -77,6 +77,13 @@ return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal); } +/// hasNestAttr - Return true if this argument has the nest attribute on +/// it in its containing function. +bool Argument::hasNestAttr() const { + if (!isa(getType())) return false; + return getParent()->paramHasAttr(getArgNo()+1, Attribute::Nest); +} + /// hasNoAliasAttr - Return true if this argument has the noalias attribute on /// it in its containing function. bool Argument::hasNoAliasAttr() const { From baldrick at free.fr Fri Dec 11 02:57:05 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 08:57:05 -0000 Subject: [llvm-commits] [dragonegg] r91110 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912110857.nBB8v55W029344@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 02:57:04 2009 New Revision: 91110 URL: http://llvm.org/viewvc/llvm-project?rev=91110&view=rev Log: Some basic thunk support. Does not handle covariant return thunks or thunks with virtual offsets. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91110&r1=91109&r2=91110&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 02:57:04 2009 @@ -1620,10 +1620,62 @@ } /// emit_thunk - Turn a thunk into LLVM IR. -void emit_thunk(struct cgraph_node *thunk) { - assert(false && "Thunks not yet implemented - come back next week!"); +void emit_thunk(struct cgraph_node *node) { + Function *Thunk = cast(DECL_LLVM(node->decl)); + if (Thunk->isVarArg()) { + sorry("thunks to varargs functions not supported"); + return; + } + + bool this_adjusting = node->thunk.this_adjusting; + assert(this_adjusting && "covariant return thunks not done yet!"); + assert(!node->thunk.virtual_offset_p && "virtual offsets not done yet!"); + + LLVMContext &Context = getGlobalContext(); + LLVMBuilder Builder(Context, *TheFolder); + Builder.SetInsertPoint(BasicBlock::Create(Context, "entry", Thunk)); + + bool FoundThis = false; // Did we find 'this' yet? + SmallVector Arguments; + for (Function::arg_iterator AI = Thunk->arg_begin(), AE = Thunk->arg_end(); + AI != AE; ++AI) { + // While 'this' is always the first GCC argument, we may have introduced + // additional artificial arguments for doing struct return or passing a + // nested function static chain. Look for 'this' while passing through + // all arguments except for 'this' unchanged. + if (FoundThis || AI->hasStructRetAttr() || AI->hasNestAttr()) { + Arguments.push_back(AI); + continue; + } + + FoundThis = true; // The current argument is 'this'. + assert(isa(AI->getType()) && "Wrong type for 'this'!"); + + // Adjust 'this' according to the thunk offsets. + // TODO: support virtual offsets + const Type *IntPtrTy = TheTarget->getTargetData()->getIntPtrType(Context); + Value *This = Builder.CreatePtrToInt(AI, IntPtrTy); + Value *Offset = ConstantInt::get(IntPtrTy, node->thunk.fixed_offset); + This = Builder.CreateNSWAdd(This, Offset); + Arguments.push_back(Builder.CreateIntToPtr(This, AI->getType())); + } + + CallInst *Call = Builder.CreateCall(DECL_LLVM(node->thunk.alias), + Arguments.begin(), Arguments.end()); + Call->setCallingConv(Thunk->getCallingConv()); + Call->setAttributes(Thunk->getAttributes()); + // No use is made of the stack - this is a tail call. + // FIXME: what if there are byval arguments? Also, could clear off any + // 'byval' attributes on the call since they are simply being passed thru. + Call->setTailCall(); + + if (Thunk->getReturnType()->isVoidTy()) + Builder.CreateRetVoid(); + else + Builder.CreateRet(Call); + // Mark the thunk as written so gcc doesn't waste time outputting it. - TREE_ASM_WRITTEN(thunk->decl) = 1; + TREE_ASM_WRITTEN(node->decl) = 1; } /// emit_alias - Given decl and target emit alias to target. From baldrick at free.fr Fri Dec 11 03:02:29 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 09:02:29 -0000 Subject: [llvm-commits] [dragonegg] r91111 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912110902.nBB92TW5000675@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 03:02:27 2009 New Revision: 91111 URL: http://llvm.org/viewvc/llvm-project?rev=91111&view=rev Log: It seems that the same-body alias target found when processing a function may not be that function. Strange but true. Follow what GCC does. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91111&r1=91110&r2=91111&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 03:02:27 2009 @@ -1772,8 +1772,7 @@ /// emit_same_body_alias - Turn a same-body alias into LLVM IR. static void emit_same_body_alias(struct cgraph_node *alias, struct cgraph_node *target) { - assert(alias->thunk.alias == target->decl && "Unexpected alias target!"); - emit_alias(alias->decl, target->decl); + emit_alias(alias->decl, alias->thunk.alias); } /// emit_functions - Turn all functions in the compilation unit into LLVM IR. From isanbard at gmail.com Fri Dec 11 04:43:42 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Dec 2009 10:43:42 -0000 Subject: [llvm-commits] [llvm] r91113 - /llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Message-ID: <200912111043.nBBAhg6l006515@zion.cs.uiuc.edu> Author: void Date: Fri Dec 11 04:43:41 2009 New Revision: 91113 URL: http://llvm.org/viewvc/llvm-project?rev=91113&view=rev Log: Revert part of r91101 which was causing an infinite loop in the self-hosting build bots. Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91113&r1=91112&r2=91113&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Fri Dec 11 04:43:41 2009 @@ -457,11 +457,16 @@ SmallSet Visited; const MachineBasicBlock *CurMBB = MBB; - while (!CurMBB->isLandingPad()) { - if (CurMBB->succ_size() != 1) + while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { + if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) break; - if (!Visited.insert(CurMBB)) break; + const TargetInstrInfo *TII = + CurMBB->getParent()->getTarget().getInstrInfo(); + if (!TII->isUnpredicatedTerminator(CurMBB->begin())) + break; + + Visited.insert(CurMBB); CurMBB = *CurMBB->succ_begin(); } From baldrick at free.fr Fri Dec 11 06:05:18 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 12:05:18 -0000 Subject: [llvm-commits] [dragonegg] r91115 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912111205.nBBC5Ig2009203@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 06:05:18 2009 New Revision: 91115 URL: http://llvm.org/viewvc/llvm-project?rev=91115&view=rev Log: Add support for thunks with virtual offsets. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91115&r1=91114&r2=91115&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 06:05:18 2009 @@ -1629,7 +1629,6 @@ bool this_adjusting = node->thunk.this_adjusting; assert(this_adjusting && "covariant return thunks not done yet!"); - assert(!node->thunk.virtual_offset_p && "virtual offsets not done yet!"); LLVMContext &Context = getGlobalContext(); LLVMBuilder Builder(Context, *TheFolder); @@ -1651,12 +1650,34 @@ FoundThis = true; // The current argument is 'this'. assert(isa(AI->getType()) && "Wrong type for 'this'!"); - // Adjust 'this' according to the thunk offsets. - // TODO: support virtual offsets + // Adjust 'this' according to the thunk offsets. First, the fixed offset. const Type *IntPtrTy = TheTarget->getTargetData()->getIntPtrType(Context); Value *This = Builder.CreatePtrToInt(AI, IntPtrTy); Value *Offset = ConstantInt::get(IntPtrTy, node->thunk.fixed_offset); This = Builder.CreateNSWAdd(This, Offset); + + if (node->thunk.virtual_offset_p) { + // The vptr is always at offset zero in the object. + const Type *HandleTy = Type::getInt8PtrTy(Context)->getPointerTo(); + Value *VPtr = Builder.CreateIntToPtr(This, HandleTy->getPointerTo()); + + // Form the vtable address. + Value *VTableAddr = Builder.CreateLoad(VPtr); + + // Find the entry with the vcall offset. + VTableAddr = Builder.CreatePtrToInt(VTableAddr, IntPtrTy); + Value *VOffset = ConstantInt::get(IntPtrTy, node->thunk.virtual_value); + VTableAddr = Builder.CreateNSWAdd(VTableAddr, VOffset); + VTableAddr = Builder.CreateIntToPtr(VTableAddr, HandleTy); + + // Get the offset itself. + Value *VCallOffset = Builder.CreateLoad(VTableAddr); + VCallOffset = Builder.CreatePtrToInt(VCallOffset, IntPtrTy); + + // Adjust the 'this' pointer. + This = Builder.CreateNSWAdd(This, VCallOffset); + } + Arguments.push_back(Builder.CreateIntToPtr(This, AI->getType())); } From baldrick at free.fr Fri Dec 11 06:48:44 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 12:48:44 -0000 Subject: [llvm-commits] [dragonegg] r91116 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912111248.nBBCmi57010570@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 06:48:44 2009 New Revision: 91116 URL: http://llvm.org/viewvc/llvm-project?rev=91116&view=rev Log: Support for file-scope asm. With this, dragonegg can mostly build llvm. Unfortunately the built llvm doesn't actually work properly, causing the build to die at llvm[2]: Building Debug Bytecode Archive libprofile_rt.bca (internalize) llvm-ld: llvm/include/llvm/PassSupport.h:109: llvm::Pass* llvm::PassInfo::createPass() const: Assertion `(!isAnalysisGroup() || NormalCtor) && "No default implementation found for analysis group!"' failed. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91116&r1=91115&r2=91116&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 06:48:44 2009 @@ -417,7 +417,7 @@ IdentString += version_string; IdentString += " LLVM: "; IdentString += REVISION; - IdentString += '"'; + IdentString += "\"\n"; TheModule->setModuleInlineAsm(IdentString); } #endif @@ -1796,6 +1796,14 @@ emit_alias(alias->decl, alias->thunk.alias); } +/// emit_file_scope_asm - Emit the specified string as a file-scope inline +/// asm block. +static void emit_file_scope_asm(tree string) { + if (TREE_CODE(string) == ADDR_EXPR) + string = TREE_OPERAND(string, 0); + TheModule->appendModuleInlineAsm(TREE_STRING_POINTER (string)); +} + /// emit_functions - Turn all functions in the compilation unit into LLVM IR. static void emit_functions(cgraph_node_set set) { LazilyInitializeModule(); @@ -1820,6 +1828,13 @@ emit_same_body_alias(alias, node); } } + + // Emit any file-scope asms. + for (struct cgraph_asm_node *can = cgraph_asm_nodes; can; can = can->next) + emit_file_scope_asm(can->asm_str); + + // Remove the asms so gcc doesn't waste time outputting them. + cgraph_asm_nodes = NULL; } /// pass_emit_functions - IPA pass that turns gimple functions into LLVM IR. From baldrick at free.fr Fri Dec 11 06:59:35 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 12:59:35 -0000 Subject: [llvm-commits] [dragonegg] r91117 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <200912111259.nBBCxZQY010922@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 06:59:35 2009 New Revision: 91117 URL: http://llvm.org/viewvc/llvm-project?rev=91117&view=rev Log: Update formatting strings for GCC changes. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91117&r1=91116&r2=91117&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 06:59:35 2009 @@ -1168,21 +1168,21 @@ /* Detect errors in declaring global registers. */ if (RegNumber == -1) - error("%Jregister name not specified for %qD", decl, decl); + error("register name not specified for %q+D", decl); else if (RegNumber < 0) - error("%Jinvalid register name for %qD", decl, decl); + error("invalid register name for %q+D", decl); else if (TYPE_MODE(TREE_TYPE(decl)) == BLKmode) - error("%Jdata type of %qD isn%'t suitable for a register", decl, decl); + error("data type of %q+D isn%'t suitable for a register", decl); #if 0 // FIXME: enable this. else if (!HARD_REGNO_MODE_OK(RegNumber, TYPE_MODE(TREE_TYPE(decl)))) - error("%Jregister specified for %qD isn%'t suitable for data type", - decl, decl); + error("register specified for %q+D isn%'t suitable for data type", + decl); #endif else if (DECL_INITIAL(decl) != 0 && TREE_STATIC(decl)) error("global register variable has initial value"); else if (AGGREGATE_TYPE_P(TREE_TYPE(decl))) - sorry("%JLLVM cannot handle register variable %qD, report a bug", - decl, decl); + sorry("LLVM cannot handle register variable %q+D, report a bug", + decl); else { if (TREE_THIS_VOLATILE(decl)) warning(0, "volatile register variables don%'t work as you might wish"); @@ -1247,8 +1247,7 @@ if (strlen (REGISTER_PREFIX) != 0) { int reg_number = decode_reg_name(Name); if (reg_number >= 0 || reg_number == -3) - error("%Jregister name given for non-register variable %qD", - decl, decl); + error("register name given for non-register variable %q+D", decl); } #endif } @@ -1742,7 +1741,7 @@ else assert(0 && "Unsuported global value"); } else { - error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); + error ("%q+D aliased to undefined symbol %qs", decl, AliaseeName); return; } } From baldrick at free.fr Fri Dec 11 07:38:22 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 13:38:22 -0000 Subject: [llvm-commits] [dragonegg] r91120 - /dragonegg/trunk/www/index.html Message-ID: <200912111338.nBBDcMtW012251@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 07:38:22 2009 New Revision: 91120 URL: http://llvm.org/viewvc/llvm-project?rev=91120&view=rev Log: Update status. Modified: dragonegg/trunk/www/index.html Modified: dragonegg/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/www/index.html?rev=91120&r1=91119&r2=91120&view=diff ============================================================================== --- dragonegg/trunk/www/index.html (original) +++ dragonegg/trunk/www/index.html Fri Dec 11 07:38:22 2009 @@ -36,14 +36,18 @@
      -
    • C and Fortran work well
    • -
    • Ada and C++ work somewhat
    • +
    • C works quite well, for example you can build a working gcc using it
    • +
    • Fortran used to work well but is currently broken
    • +
    • It can compile quite a lot of C++, but the compiled code may not work + right
    • +
    • It can compile quite a lot of Ada, but the compiled code may not work + right
    • Java, Obj-C and Obj-C++ are untested
    • Exception handling does not work
    • Limited debug info
    • Requires one gcc patch
    • Only supports x86-32 and x86-64
    • -
    • Only supports linux and darwin
    • +
    • Only supports linux and darwin (darwin hasn't been tested recently though)

    DragonEgg is under heavy From baldrick at free.fr Fri Dec 11 09:06:34 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 15:06:34 -0000 Subject: [llvm-commits] [dragonegg] r91121 - in /dragonegg/trunk: gcc-patches/lto_flags.diff llvm-backend.cpp Message-ID: <200912111506.nBBF6YpZ015293@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 09:06:31 2009 New Revision: 91121 URL: http://llvm.org/viewvc/llvm-project?rev=91121&view=rev Log: This change to GCC was rejected by the GCC maintainers. Handle it a different way, by pretending the user set flag_lto. Removed: dragonegg/trunk/gcc-patches/lto_flags.diff Modified: dragonegg/trunk/llvm-backend.cpp Removed: dragonegg/trunk/gcc-patches/lto_flags.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/lto_flags.diff?rev=91120&view=auto ============================================================================== --- dragonegg/trunk/gcc-patches/lto_flags.diff (original) +++ dragonegg/trunk/gcc-patches/lto_flags.diff (removed) @@ -1,88 +0,0 @@ -Index: mainline/gcc/cgraphunit.c -=================================================================== ---- mainline.orig/gcc/cgraphunit.c 2009-12-08 17:31:41.004321857 +0100 -+++ mainline/gcc/cgraphunit.c 2009-12-08 17:36:47.211914685 +0100 -@@ -358,8 +358,7 @@ - && !DECL_DECLARED_INLINE_P (decl) - && !node->origin)) - && !flag_whole_program -- && !flag_lto -- && !flag_whopr) -+ && !flag_generate_lto) - && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) - return true; - -Index: mainline/gcc/ipa-cp.c -=================================================================== ---- mainline.orig/gcc/ipa-cp.c 2009-12-08 17:31:41.024330339 +0100 -+++ mainline/gcc/ipa-cp.c 2009-12-08 17:36:47.221953358 +0100 -@@ -628,7 +628,7 @@ - { - /* We do not need to bother analyzing calls to unknown - functions unless they may become known during lto/whopr. */ -- if (!cs->callee->analyzed && !flag_lto && !flag_whopr) -+ if (!cs->callee->analyzed && !flag_generate_lto) - continue; - ipa_count_arguments (cs); - if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) -Index: mainline/gcc/ipa.c -=================================================================== ---- mainline.orig/gcc/ipa.c 2009-12-08 17:31:41.034318098 +0100 -+++ mainline/gcc/ipa.c 2009-12-08 17:36:47.231861147 +0100 -@@ -27,6 +27,7 @@ - #include "timevar.h" - #include "gimple.h" - #include "ggc.h" -+#include "flags.h" - - /* Fill array order with all nodes with output flag set in the reverse - topological order. */ -@@ -401,7 +402,7 @@ - static unsigned int - local_function_and_variable_visibility (void) - { -- return function_and_variable_visibility (flag_whole_program && !flag_lto && !flag_whopr); -+ return function_and_variable_visibility (flag_whole_program && !flag_generate_lto); - } - - struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility = -Index: mainline/gcc/varpool.c -=================================================================== ---- mainline.orig/gcc/varpool.c 2009-12-08 17:31:41.004321857 +0100 -+++ mainline/gcc/varpool.c 2009-12-08 17:36:47.241964425 +0100 -@@ -244,8 +244,7 @@ - COMDAT variables that must be output only when they are needed. */ - if (TREE_PUBLIC (decl) - && !flag_whole_program -- && !flag_lto -- && !flag_whopr -+ && !flag_generate_lto - && !DECL_COMDAT (decl) - && !DECL_EXTERNAL (decl)) - return true; -Index: mainline/gcc/fortran/options.c -=================================================================== ---- mainline.orig/gcc/fortran/options.c 2009-12-08 17:31:41.014317857 +0100 -+++ mainline/gcc/fortran/options.c 2009-12-08 17:36:47.241964425 +0100 -@@ -243,7 +243,7 @@ - gfc_option.flag_whole_file = 1; - - /* Enable whole-file mode if LTO is in effect. */ -- if (flag_lto || flag_whopr) -+ if (flag_generate_lto) - gfc_option.flag_whole_file = 1; - - /* -fbounds-check is equivalent to -fcheck=bounds */ -Index: mainline/gcc/Makefile.in -=================================================================== ---- mainline.orig/gcc/Makefile.in 2009-12-08 17:31:41.024330339 +0100 -+++ mainline/gcc/Makefile.in 2009-12-08 17:36:47.251874518 +0100 -@@ -2876,7 +2876,7 @@ - $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \ - $(TREE_FLOW_H) gt-varpool.h - ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ -- $(TREE_PASS_H) $(TIMEVAR_H) $(GIMPLE_H) $(GGC_H) -+ $(TREE_PASS_H) $(TIMEVAR_H) $(GIMPLE_H) $(GGC_H) $(FLAGS_H) - ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ - $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=91121&r1=91120&r2=91121&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri Dec 11 09:06:31 2009 @@ -1569,7 +1569,10 @@ // Output LLVM IR if the user requested generation of lto data. EmitIR |= flag_generate_lto != 0; // We have the same needs as GCC's LTO. Always claim to be doing LTO. + flag_lto = 1; + flag_whopr = 0; flag_generate_lto = 1; + flag_whole_program = 0; #else error ("GCC LTO support required but not enabled"); #endif From baldrick at free.fr Fri Dec 11 09:07:22 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 15:07:22 -0000 Subject: [llvm-commits] [dragonegg] r91122 - /dragonegg/trunk/gcc-patches/alloc.diff Message-ID: <200912111507.nBBF7MA2015326@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 09:07:21 2009 New Revision: 91122 URL: http://llvm.org/viewvc/llvm-project?rev=91122&view=rev Log: This has been fixed upstream. Removed: dragonegg/trunk/gcc-patches/alloc.diff Removed: dragonegg/trunk/gcc-patches/alloc.diff URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/gcc-patches/alloc.diff?rev=91121&view=auto ============================================================================== --- dragonegg/trunk/gcc-patches/alloc.diff (original) +++ dragonegg/trunk/gcc-patches/alloc.diff (removed) @@ -1,27 +0,0 @@ -Index: mainline/gcc/passes.c -=================================================================== ---- mainline.orig/gcc/passes.c 2009-12-07 11:58:18.483151321 +0100 -+++ mainline/gcc/passes.c 2009-12-07 12:10:09.040652447 +0100 -@@ -459,9 +459,20 @@ - if (pass->static_pass_number) - { - struct opt_pass *new_pass; -+ size_t pass_size; - -- new_pass = XNEW (struct opt_pass); -- memcpy (new_pass, pass, sizeof (*new_pass)); -+ if (pass->type != IPA_PASS) -+ { -+ new_pass = XNEW (struct opt_pass); -+ pass_size = sizeof(struct opt_pass); -+ } -+ else -+ { -+ new_pass = (struct opt_pass *)XNEW (struct ipa_opt_pass_d); -+ pass_size = sizeof(struct ipa_opt_pass_d); -+ } -+ -+ memcpy (new_pass, pass, pass_size); - new_pass->next = NULL; - - new_pass->todo_flags_start &= ~TODO_mark_first_instance; From ggreif at gmail.com Fri Dec 11 09:30:07 2009 From: ggreif at gmail.com (Gabor Greif) Date: Fri, 11 Dec 2009 15:30:07 -0000 Subject: [llvm-commits] [llvm] r91123 - /llvm/trunk/include/llvm/ADT/StringSwitch.h Message-ID: <200912111530.nBBFU78K016110@zion.cs.uiuc.edu> Author: ggreif Date: Fri Dec 11 09:30:07 2009 New Revision: 91123 URL: http://llvm.org/viewvc/llvm-project?rev=91123&view=rev Log: Simplify this class by removing the result cache. This change removes the DefaultConstructible and CopyAssignable constraints on the template parameter T (the first one). The second template parameter (R) is defaulted to be identical to the first and controls the result type. By specifying it to be (const T&) additionally the CopyConstructible constraint on T can be removed. This allows to use StringSwitch e.g. for llvm::Constant instances. Regarding the other review feedback regarding performance because of taking pointers, this class should be completely optimizable like before, since all methods are inline and the pointer dereferencing and result value caching should be possible behind the scenes by the "as-if" rule. Modified: llvm/trunk/include/llvm/ADT/StringSwitch.h Modified: llvm/trunk/include/llvm/ADT/StringSwitch.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringSwitch.h?rev=91123&r1=91122&r2=91123&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringSwitch.h (original) +++ llvm/trunk/include/llvm/ADT/StringSwitch.h Fri Dec 11 09:30:07 2009 @@ -38,28 +38,24 @@ /// .Cases("violet", "purple", Violet) /// .Default(UnknownColor); /// \endcode -template +template class StringSwitch { /// \brief The string we are matching. StringRef Str; - /// \brief The result of this switch statement, once known. - T Result; - - /// \brief Set true when the result of this switch is already known; in this - /// case, Result is valid. - bool ResultKnown; + /// \brief The pointer to the result of this switch statement, once known, + /// null before that. + const T *Result; public: explicit StringSwitch(StringRef Str) - : Str(Str), ResultKnown(false) { } + : Str(Str), Result(0) { } template StringSwitch& Case(const char (&S)[N], const T& Value) { - if (!ResultKnown && N-1 == Str.size() && + if (!Result && N-1 == Str.size() && (std::memcmp(S, Str.data(), N-1) == 0)) { - Result = Value; - ResultKnown = true; + Result = &Value; } return *this; @@ -92,16 +88,16 @@ .Case(S4, Value); } - T Default(const T& Value) { - if (ResultKnown) - return Result; + R Default(const T& Value) const { + if (Result) + return *Result; return Value; } - operator T() { - assert(ResultKnown && "Fell off the end of a string-switch"); - return Result; + operator R() const { + assert(Result && "Fell off the end of a string-switch"); + return *Result; } }; From baldrick at free.fr Fri Dec 11 10:10:48 2009 From: baldrick at free.fr (Duncan Sands) Date: Fri, 11 Dec 2009 16:10:48 -0000 Subject: [llvm-commits] [dragonegg] r91124 - /dragonegg/trunk/COPYING Message-ID: <200912111610.nBBGAmGB017749@zion.cs.uiuc.edu> Author: baldrick Date: Fri Dec 11 10:10:48 2009 New Revision: 91124 URL: http://llvm.org/viewvc/llvm-project?rev=91124&view=rev Log: Add a copy of the GPLv2. Added: dragonegg/trunk/COPYING Added: dragonegg/trunk/COPYING URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/COPYING?rev=91124&view=auto ============================================================================== --- dragonegg/trunk/COPYING (added) +++ dragonegg/trunk/COPYING Fri Dec 11 10:10:48 2009 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. From bob.wilson at apple.com Fri Dec 11 11:27:47 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 09:27:47 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450911252018p3930f82cg43ebe9f6ded326c0@mail.gmail.com> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> Message-ID: <644DACFE-E75F-488F-8833-A631C330897C@apple.com> On Dec 10, 2009, at 5:08 PM, Rafael Espindola wrote: >> I think it's a bad idea to try to do this in target-independent code. >> Whether the information goes in the high part or the low part of the >> register is target-dependent (there's some correlation with endianness), and >> just which structs need special treatment is also target-dependent. I think >> there's even a target where >> struct { char[3] a;} >> and >> struct { short a; char b; } >> are passed differently. >> >> I think most existing targets use byval, so I'd use that; there's lots of >> prior art to copy. > > > I think I failed to pass by point: How would you expand > > -------------------------- > struct foo { > char c[5]; > }; > > void f(int a, int b, int c, struct foo d) { > ... > } > ----------------------- I don't think I get your point. The expansion of that may be target-specific. E.G., x86 passes "d" using "byval", but x86-64 expands it to an i64. > > Byval was created to force something to the stack > (http://llvm.org/bugs/show_bug.cgi?id=1521). In this case the first 4 > bytes have to go in a register. The last byte goes to the stack. I can > use byval, but only for the last byte. I still need to know when the > registers are over so that I can split the structure at that point. Byval does not force things to the stack. From the llvm IR perspective, byval arguments look like they are passed in memory, but the codegen needs to understand the target ABI and figure out how to pass them. The values (or portions of values) that are actually passed in registers are then copied into memory. There are some performance problems with this, and it's certainly not pretty, but we should fix the ARM ABI issues before trying to redesign the way llvm handles argument passing. From espindola at google.com Fri Dec 11 11:50:41 2009 From: espindola at google.com (Rafael Espindola) Date: Fri, 11 Dec 2009 12:50:41 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <644DACFE-E75F-488F-8833-A631C330897C@apple.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> Message-ID: <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> > I don't think I get your point. ?The expansion of that may be target-specific. ?E.G., x86 passes "d" using "byval", but x86-64 expands it to an i64. My point is that I see two reasonable ways to expand this for ARM given the current infrastructure: declare arm_aapcscc void @f(i32, i32, i32, i32, i8) or %struct.foo_part = type { i8 } declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) For both cases I need to know in *llvm-gcc* when to stop using registers and switch to memory. If I understand you, you are proposing that this should be expanded to %struct.foo = type { [5 x i8] } declare arm_aapcscc void @f(i32, i32, i32, %struct.foo_part* byval) And get the codegen to split the last argument in part register part stack. Is that your proposal? > >> >> Byval was created to force something to the stack >> (http://llvm.org/bugs/show_bug.cgi?id=1521). In this case the first 4 >> bytes have to go in a register. The last byte goes to the stack. I can >> use byval, but only for the last byte. I still need to know when the >> registers are over so that I can split the structure at that point. > > Byval does not force things to the stack. ?From the llvm IR perspective, byval arguments look like they are passed in memory, but the codegen needs to understand the target ABI and figure out how to pass them. ?The values (or portions of values) that are actually passed in registers are then copied into memory. ?There are some performance problems with this, and it's certainly not pretty, but we should fix the ARM ABI issues before trying to redesign the way llvm handles argument passing. byval looks like a pointer to everything in llvm. Using it for something that will not have an address at all is very confusing. Do we actually do it in some current architecture? Do you have an example of a byval argument being passed in registers? For example, in x86-64 something like %struct.s = type { i64 } define i64 @f(%struct.s* byval %a) gets passed on the stack. It would be passed in registers on arm with your proposal. I also want to fix this bug first and try to improve things afterward. The first option (using a final i8) looks the easiest to implement right now. Would it be OK with you if I finish implementing that first? Cheers, -- Rafael ?vila de Esp?ndola From bob.wilson at apple.com Fri Dec 11 12:10:32 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 10:10:32 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912011506n2577f4dfoaea9de802b37954f@mail.gmail.com> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> Message-ID: <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> On Dec 11, 2009, at 9:50 AM, Rafael Espindola wrote: >> I don't think I get your point. The expansion of that may be target-specific. E.G., x86 passes "d" using "byval", but x86-64 expands it to an i64. > > My point is that I see two reasonable ways to expand this for ARM > given the current infrastructure: > > declare arm_aapcscc void @f(i32, i32, i32, i32, i8) > > or > > %struct.foo_part = type { i8 } > declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) > > For both cases I need to know in *llvm-gcc* when to stop using > registers and switch to memory. You could try to get the target hooks in llvm-gcc to know when to stop using registers, or you can just look at the type and decide to always use "byval" for that type. The latter is simpler and cleaner, although probably less efficient. > > If I understand you, you are proposing that this should be expanded to > > %struct.foo = type { [5 x i8] } > declare arm_aapcscc void @f(i32, i32, i32, %struct.foo_part* byval) > > And get the codegen to split the last argument in part register part > stack. Is that your proposal? Yes. That is how other targets handle this sort of thing. > >> >>> >>> Byval was created to force something to the stack >>> (http://llvm.org/bugs/show_bug.cgi?id=1521). In this case the first 4 >>> bytes have to go in a register. The last byte goes to the stack. I can >>> use byval, but only for the last byte. I still need to know when the >>> registers are over so that I can split the structure at that point. >> >> Byval does not force things to the stack. From the llvm IR perspective, byval arguments look like they are passed in memory, but the codegen needs to understand the target ABI and figure out how to pass them. The values (or portions of values) that are actually passed in registers are then copied into memory. There are some performance problems with this, and it's certainly not pretty, but we should fix the ARM ABI issues before trying to redesign the way llvm handles argument passing. > > byval looks like a pointer to everything in llvm. Using it for > something that will not have an address at all is very confusing. Do > we actually do it in some current architecture? Do you have an example > of a byval argument being passed in registers? byval arguments are always copied to memory, so they do have addresses, but they may be passed in registers. Look at PPCISelLowering's LowerFormalArguments_Darwin, for example. For pr5406, we use byval on all the other major supported architectures except ARM. We should fix ARM first to use the approach that we know works. After that, if you want to initiate a project to find a more elegant solution, that would be fantastic. It is pretty horrible that we essentially require all targets to implement byval to get compatibility with any sane ABI. > > For example, in x86-64 something like > > %struct.s = type { i64 } > define i64 @f(%struct.s* byval %a) > > gets passed on the stack. It would be passed in registers on arm with > your proposal. > > I also want to fix this bug first and try to improve things afterward. > The first option (using a final i8) looks the easiest to implement > right now. Would it be OK with you if I finish implementing that > first? I don't think that's the right way to go. From espindola at google.com Fri Dec 11 12:33:32 2009 From: espindola at google.com (Rafael Espindola) Date: Fri, 11 Dec 2009 13:33:32 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> Message-ID: <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> > byval arguments are always copied to memory, so they do have addresses, but they may be passed in registers. ?Look at PPCISelLowering's LowerFormalArguments_Darwin, for example. For ARM this part should not be on memory, that is not the layout mandated by the ABI. > For pr5406, we use byval on all the other major supported architectures except ARM. ?We should fix ARM first to use the approach that we know works. ?After that, if you want to initiate a project to find a more elegant solution, that would be fantastic. ?It is pretty horrible that we essentially require all targets to implement byval to get compatibility with any sane ABI. No we don't. Take x86-64 for example. Since char[5] <= 16 bytes llvm-gcc decomposes the structure: declare void @f(i32, i32, i32, i64) If I change 5 with 17 I get declare void @f(i32, i32, i32, %struct.foo* byval) Which is good, since *all* of stuct foo is passed on the stack. >> >> For example, in x86-64 something like >> >> %struct.s = type { i64 } >> define i64 @f(%struct.s* byval %a) >> >> gets passed on the stack. It would be passed in registers on arm with >> your proposal. >> >> I also want to fix this bug first and try to improve things afterward. >> The first option (using a final i8) looks the easiest to implement >> right now. Would it be OK with you if I finish implementing that >> first? > > I don't think that's the right way to go. What about the second proposal: %struct.foo_part = type { i8 } declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) Sorry, I am not going to implement byval splitting in the ARM backend to just immediately open a bug report about it producing bad quality code. We know what will and will not be in the stack early on. Cheers, -- Rafael ?vila de Esp?ndola From bob.wilson at apple.com Fri Dec 11 12:45:29 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 10:45:29 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912021345n646360ddtf847aaa57cc34356@mail.gmail.com> <7A18F56D-9717-4765-91D8-CADC3276E959@apple.com> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> Message-ID: <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> On Dec 11, 2009, at 10:33 AM, Rafael Espindola wrote: >> byval arguments are always copied to memory, so they do have addresses, but they may be passed in registers. Look at PPCISelLowering's LowerFormalArguments_Darwin, for example. > > For ARM this part should not be on memory, that is not the layout > mandated by the ABI. Right, so codegen has to recognize that and copy the arguments to/from the registers mandated by the ABI. > >> For pr5406, we use byval on all the other major supported architectures except ARM. We should fix ARM first to use the approach that we know works. After that, if you want to initiate a project to find a more elegant solution, that would be fantastic. It is pretty horrible that we essentially require all targets to implement byval to get compatibility with any sane ABI. > > No we don't. Take x86-64 for example. Since char[5] <= 16 bytes > llvm-gcc decomposes the structure: > > declare void @f(i32, i32, i32, i64) > > If I change 5 with 17 I get > > declare void @f(i32, i32, i32, %struct.foo* byval) > > Which is good, since *all* of stuct foo is passed on the stack. You're right about x86-64 -- I was misremembering that. x86 and ppc use byval. > >>> >>> For example, in x86-64 something like >>> >>> %struct.s = type { i64 } >>> define i64 @f(%struct.s* byval %a) >>> >>> gets passed on the stack. It would be passed in registers on arm with >>> your proposal. >>> >>> I also want to fix this bug first and try to improve things afterward. >>> The first option (using a final i8) looks the easiest to implement >>> right now. Would it be OK with you if I finish implementing that >>> first? >> >> I don't think that's the right way to go. > > What about the second proposal: > > %struct.foo_part = type { i8 } > declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) > > Sorry, I am not going to implement byval splitting in the ARM backend > to just immediately open a bug report about it producing bad quality > code. We know what will and will not be in the stack early on. You are right about the code quality. If you want to implement something like the x86-64 solution, that would be great. From grosbach at apple.com Fri Dec 11 12:52:42 2009 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 11 Dec 2009 18:52:42 -0000 Subject: [llvm-commits] [llvm] r91140 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200912111852.nBBIqgGb023508@zion.cs.uiuc.edu> Author: grosbach Date: Fri Dec 11 12:52:41 2009 New Revision: 91140 URL: http://llvm.org/viewvc/llvm-project?rev=91140&view=rev Log: Update properties. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91140&r1=91139&r2=91140&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Dec 11 12:52:41 2009 @@ -1574,7 +1574,7 @@ // // memory barriers protect the atomic sequences -let isBarrier = 1, isPredicable = 0 in { +let isPredicable = 0 in { def Int_MemBarrierV7 : AI<(outs), (ins), Pseudo, NoItinerary, "dmb", "", @@ -1596,7 +1596,7 @@ } } -let usesCustomInserter = 1, mayLoad = 1, mayStore = 1 in { +let usesCustomInserter = 1 in { def ATOMIC_CMP_SWAP_I8 : PseudoInst< (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", From gohman at apple.com Fri Dec 11 13:19:57 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 11:19:57 -0800 Subject: [llvm-commits] [llvm] r91104 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.h In-Reply-To: <200912110601.nBB61mfT014511@zion.cs.uiuc.edu> References: <200912110601.nBB61mfT014511@zion.cs.uiuc.edu> Message-ID: On Dec 10, 2009, at 10:01 PM, Evan Cheng wrote: > Author: evancheng > Date: Fri Dec 11 00:01:48 2009 > New Revision: 91104 > > URL: http://llvm.org/viewvc/llvm-project?rev=91104&view=rev > Log: > Add support to 3-addressify 16-bit instructions. > > Modified: > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.h > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=91104&r1=91103&r2=91104&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 11 00:01:48 2009 > @@ -1058,6 +1058,107 @@ > return false; > } > > +/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when 16-bit > +/// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting Typo: "16-bit 16-bit". > +/// to a 32-bit superregister and then truncating back down to a 16-bit > +/// subregister. This change introduces a partial register stall condition; are you sure this is worthwhile? If so, please note this in a comment. Also, do you have a testcase? Dan From daniel at zuster.org Fri Dec 11 13:23:22 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 11 Dec 2009 19:23:22 -0000 Subject: [llvm-commits] [test-suite] r91142 - /test-suite/trunk/Makefile.tests Message-ID: <200912111923.nBBJNMdb024551@zion.cs.uiuc.edu> Author: ddunbar Date: Fri Dec 11 13:23:22 2009 New Revision: 91142 URL: http://llvm.org/viewvc/llvm-project?rev=91142&view=rev Log: NightlyTest: At least suppress failures when the LLVMCC under-test fails -- otherwise we won't get a proper test report. Modified: test-suite/trunk/Makefile.tests Modified: test-suite/trunk/Makefile.tests URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.tests?rev=91142&r1=91141&r2=91142&view=diff ============================================================================== --- test-suite/trunk/Makefile.tests (original) +++ test-suite/trunk/Makefile.tests Fri Dec 11 13:23:22 2009 @@ -39,27 +39,27 @@ # Compile from X.c to Output/X.bc Output/%.bc: %.c $(LCC1) Output/.dir $(INCLUDES) - $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cpp to Output/X.bc Output/%.bc: %.cpp $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.cc to Output/X.bc Output/%.bc: %.cc $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.C to Output/X.bc Output/%.bc: %.C $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.m to Output/X.bc Output/%.bc: %.m $(LCC1) Output/.dir $(INCLUDES) - $(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGCC) $(CPPFLAGS) $(CFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # Compile from X.mm to Output/X.bc Output/%.bc: %.mm $(LCC1XX) Output/.dir $(INCLUDES) - $(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm + -$(LLVMGXX) $(CPPFLAGS) $(CXXFLAGS) $(LOPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ -emit-llvm # LLVM Assemble from X.ll to Output/X.bc. Because we are coming directly from # LLVM source, use the non-transforming assembler. From johnny.chen at apple.com Fri Dec 11 13:37:26 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 11 Dec 2009 19:37:26 -0000 Subject: [llvm-commits] [llvm] r91143 - /llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Message-ID: <200912111937.nBBJbQbB024980@zion.cs.uiuc.edu> Author: johnny Date: Fri Dec 11 13:37:26 2009 New Revision: 91143 URL: http://llvm.org/viewvc/llvm-project?rev=91143&view=rev Log: Store Register Exclusive should leave the source register Inst{3-0} unspecified. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=91143&r1=91142&r2=91143&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Fri Dec 11 13:37:26 2009 @@ -285,7 +285,7 @@ let Inst{27-23} = 0b00011; let Inst{22-21} = opcod; let Inst{20} = 0; - let Inst{11-0} = 0b111110011111; + let Inst{11-4} = 0b11111001; } // addrmode1 instructions From asl at math.spbu.ru Fri Dec 11 13:39:56 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 11 Dec 2009 19:39:56 -0000 Subject: [llvm-commits] [llvm] r91144 - in /llvm/trunk: lib/CodeGen/PrologEpilogInserter.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll Message-ID: <200912111939.nBBJdunl025069@zion.cs.uiuc.edu> Author: asl Date: Fri Dec 11 13:39:55 2009 New Revision: 91144 URL: http://llvm.org/viewvc/llvm-project?rev=91144&view=rev Log: Honour setHasCalls() set from isel. This is used in some weird cases like general dynamic TLS model. This fixes PR5723 Added: llvm/trunk/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=91144&r1=91143&r2=91144&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Fri Dec 11 13:39:55 2009 @@ -136,9 +136,10 @@ /// pseudo instructions. void PEI::calculateCallsInformation(MachineFunction &Fn) { const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + MachineFrameInfo *FFI = Fn.getFrameInfo(); unsigned MaxCallFrameSize = 0; - bool HasCalls = false; + bool HasCalls = FFI->hasCalls(); // Get the function call frame set-up and tear-down instruction opcode int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); @@ -166,7 +167,6 @@ HasCalls = true; } - MachineFrameInfo *FFI = Fn.getFrameInfo(); FFI->setHasCalls(HasCalls); FFI->setMaxCallFrameSize(MaxCallFrameSize); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=91144&r1=91143&r2=91144&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 11 13:39:55 2009 @@ -4902,6 +4902,7 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA, SDValue *InFlag, const EVT PtrVT, unsigned ReturnReg, unsigned char OperandFlags) { + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); DebugLoc dl = GA->getDebugLoc(); SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), @@ -4915,6 +4916,10 @@ SDValue Ops[] = { Chain, TGA }; Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2); } + + // TLSADDR will be codegen'ed as call. Inform MFI that function has calls. + MFI->setHasCalls(true); + SDValue Flag = Chain.getValue(1); return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag); } Added: llvm/trunk/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll?rev=91144&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll (added) +++ llvm/trunk/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll Fri Dec 11 13:39:55 2009 @@ -0,0 +1,63 @@ +; RUN: llc -relocation-model=pic < %s | FileCheck %s +; PR5723 +target datalayout = "e-p:64:64" +target triple = "x86_64-unknown-linux-gnu" + +%0 = type { [1 x i64] } +%link = type { %0* } +%test = type { i32, %link } + + at data = global [2 x i64] zeroinitializer, align 64 ; <[2 x i64]*> [#uses=1] + at ptr = linkonce thread_local global [1 x i64] [i64 ptrtoint ([2 x i64]* @data to i64)], align 64 ; <[1 x i64]*> [#uses=1] + at link_ptr = linkonce thread_local global [1 x i64] zeroinitializer, align 64 ; <[1 x i64]*> [#uses=1] + at _dm_my_pe = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + at _dm_pes_in_prog = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + at _dm_npes_div_mult = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + at _dm_npes_div_shift = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + at _dm_pe_addr_loc = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + at _dm_offset_addr_mask = external global [1 x i64], align 64 ; <[1 x i64]*> [#uses=0] + +define void @leaf() nounwind { +; CHECK: leaf: +; CHECK-NOT: -8(%rsp) +; CHECK: leaq link_ptr at TLSGD +; CHECK: call __tls_get_addr at PLT +"file foo2.c, line 14, bb1": + %p = alloca %test*, align 8 ; <%test**> [#uses=4] + br label %"file foo2.c, line 14, bb2" + +"file foo2.c, line 14, bb2": ; preds = %"file foo2.c, line 14, bb1" + br label %"@CFE_debug_label_0" + +"@CFE_debug_label_0": ; preds = %"file foo2.c, line 14, bb2" + %r = load %test** bitcast ([1 x i64]* @ptr to %test**), align 8 ; <%test*> [#uses=1] + store %test* %r, %test** %p, align 8 + br label %"@CFE_debug_label_2" + +"@CFE_debug_label_2": ; preds = %"@CFE_debug_label_0" + %r1 = load %link** bitcast ([1 x i64]* @link_ptr to %link**), align 8 ; <%link*> [#uses=1] + %r2 = load %test** %p, align 8 ; <%test*> [#uses=1] + %r3 = ptrtoint %test* %r2 to i64 ; [#uses=1] + %r4 = inttoptr i64 %r3 to %link** ; <%link**> [#uses=1] + %r5 = getelementptr %link** %r4, i64 1 ; <%link**> [#uses=1] + store %link* %r1, %link** %r5, align 8 + br label %"@CFE_debug_label_3" + +"@CFE_debug_label_3": ; preds = %"@CFE_debug_label_2" + %r6 = load %test** %p, align 8 ; <%test*> [#uses=1] + %r7 = ptrtoint %test* %r6 to i64 ; [#uses=1] + %r8 = inttoptr i64 %r7 to %link* ; <%link*> [#uses=1] + %r9 = getelementptr %link* %r8, i64 1 ; <%link*> [#uses=1] + store %link* %r9, %link** bitcast ([1 x i64]* @link_ptr to %link**), align 8 + br label %"@CFE_debug_label_4" + +"@CFE_debug_label_4": ; preds = %"@CFE_debug_label_3" + %r10 = load %test** %p, align 8 ; <%test*> [#uses=1] + %r11 = ptrtoint %test* %r10 to i64 ; [#uses=1] + %r12 = inttoptr i64 %r11 to i32* ; [#uses=1] + store i32 1, i32* %r12, align 4 + br label %"@CFE_debug_label_5" + +"@CFE_debug_label_5": ; preds = %"@CFE_debug_label_4" + ret void +} From gohman at apple.com Fri Dec 11 13:50:51 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 19:50:51 -0000 Subject: [llvm-commits] [llvm] r91145 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp test/CodeGen/X86/select-aggregate.ll Message-ID: <200912111950.nBBJopGR025494@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 11 13:50:50 2009 New Revision: 91145 URL: http://llvm.org/viewvc/llvm-project?rev=91145&view=rev Log: Fix the result type of SELECT nodes lowered from Select instructions with aggregate return values. This fixes PR5754. Added: llvm/trunk/test/CodeGen/X86/select-aggregate.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=91145&r1=91144&r2=91145&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Dec 11 13:50:50 2009 @@ -2108,7 +2108,7 @@ for (unsigned i = 0; i != NumValues; ++i) Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), - TrueVal.getValueType(), Cond, + TrueVal.getNode()->getValueType(i), Cond, SDValue(TrueVal.getNode(), TrueVal.getResNo() + i), SDValue(FalseVal.getNode(), FalseVal.getResNo() + i)); Added: llvm/trunk/test/CodeGen/X86/select-aggregate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/select-aggregate.ll?rev=91145&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/select-aggregate.ll (added) +++ llvm/trunk/test/CodeGen/X86/select-aggregate.ll Fri Dec 11 13:50:50 2009 @@ -0,0 +1,15 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s +; PR5754 + +; CHECK: cmovne %rdi, %rsi +; CHECK: movl (%rsi), %eax + +%0 = type { i64, i32 } + +define i32 @foo(%0* %p, %0* %q, i1 %r) nounwind { + %t0 = load %0* %p + %t1 = load %0* %q + %t4 = select i1 %r, %0 %t0, %0 %t1 + %t5 = extractvalue %0 %t4, 1 + ret i32 %t5 +} From gohman at apple.com Fri Dec 11 14:05:23 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 20:05:23 -0000 Subject: [llvm-commits] [llvm] r91147 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp test/Transforms/IndVarSimplify/indirectbr.ll Message-ID: <200912112005.nBBK5NLY026052@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 11 14:05:23 2009 New Revision: 91147 URL: http://llvm.org/viewvc/llvm-project?rev=91147&view=rev Log: Make getUniqueExitBlocks's precondition assert more precise, to avoid spurious failures. This fixes PR5758. Added: llvm/trunk/test/Transforms/IndVarSimplify/indirectbr.ll Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h llvm/trunk/lib/Analysis/LoopInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=91147&r1=91146&r2=91147&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Fri Dec 11 14:05:23 2009 @@ -568,7 +568,7 @@ /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. - /// This assumes that loop is in canonical form. + /// This assumes that loop exits are in canonical form. /// void getUniqueExitBlocks(SmallVectorImpl &ExitBlocks) const; Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=91147&r1=91146&r2=91147&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Fri Dec 11 14:05:23 2009 @@ -316,12 +316,12 @@ /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. -/// This assumes that loop is in canonical form. +/// This assumes that loop exits are in canonical form. /// void Loop::getUniqueExitBlocks(SmallVectorImpl &ExitBlocks) const { - assert(isLoopSimplifyForm() && - "getUniqueExitBlocks assumes the loop is in canonical form!"); + assert(hasDedicatedExits() && + "getUniqueExitBlocks assumes the loop has canonical form exits!"); // Sort the blocks vector so that we can use binary search to do quick // lookups. Added: llvm/trunk/test/Transforms/IndVarSimplify/indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/indirectbr.ll?rev=91147&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/indirectbr.ll (added) +++ llvm/trunk/test/Transforms/IndVarSimplify/indirectbr.ll Fri Dec 11 14:05:23 2009 @@ -0,0 +1,22 @@ +; RUN: opt < %s -indvars -S -disable-output +; PR5758 + +define zeroext i1 @foo() nounwind { +entry: + indirectbr i8* undef, [label %"202", label %"133"] + +"132": ; preds = %"133" + %0 = add i32 %1, 1 ; [#uses=1] + br label %"133" + +"133": ; preds = %"132", %entry + %1 = phi i32 [ %0, %"132" ], [ 0, %entry ] ; [#uses=2] + %2 = icmp eq i32 %1, 4 ; [#uses=1] + br i1 %2, label %"134", label %"132" + +"134": ; preds = %"133" + ret i1 true + +"202": ; preds = %entry + ret i1 false +} From gohman at apple.com Fri Dec 11 14:09:21 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 20:09:21 -0000 Subject: [llvm-commits] [llvm] r91148 - /llvm/trunk/test/CodeGen/X86/select-aggregate.ll Message-ID: <200912112009.nBBK9Lod026231@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 11 14:09:21 2009 New Revision: 91148 URL: http://llvm.org/viewvc/llvm-project?rev=91148&view=rev Log: Change this to the correct PR number. Modified: llvm/trunk/test/CodeGen/X86/select-aggregate.ll Modified: llvm/trunk/test/CodeGen/X86/select-aggregate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/select-aggregate.ll?rev=91148&r1=91147&r2=91148&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/select-aggregate.ll (original) +++ llvm/trunk/test/CodeGen/X86/select-aggregate.ll Fri Dec 11 14:09:21 2009 @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86-64 | FileCheck %s -; PR5754 +; PR5757 ; CHECK: cmovne %rdi, %rsi ; CHECK: movl (%rsi), %eax From espindola at google.com Fri Dec 11 14:28:25 2009 From: espindola at google.com (Rafael Espindola) Date: Fri, 11 Dec 2009 15:28:25 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> Message-ID: <38a0d8450912111228u3edb21c1qa1952f66f4c19f5f@mail.gmail.com> >> Which is good, since *all* of stuct foo is passed on the stack. > > You're right about x86-64 -- I was misremembering that. ?x86 and ppc use byval. So, for x86 that is fine too since all of the struct will be passed in the stack. I don't know ppc, > You are right about the code quality. ?If you want to implement something like the x86-64 solution, that would be great. Yes, I want something like x86-64. The big difference that we have to account for on ARM is that it can split structures with a part going to registers and a part going to the stack. *) For the part that goes in registers, we should just use i32 (x86-64 uses i64). Do you agree with that? *) For the part that goes in the stack I see 2 options 1) Use simple integers (i8, i16 ...) 2) Use a byval Option 1 is easier to implement. Option 2 is probably the best since it makes it explicit that something is going to memory. One disadvantage of option 2 is that we introduce a new type representing the bits that go to memory. Do you see other options? Which one do you like best? Cheers, -- Rafael ?vila de Esp?ndola From grosbach at apple.com Fri Dec 11 14:29:54 2009 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 11 Dec 2009 20:29:54 -0000 Subject: [llvm-commits] [llvm] r91150 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200912112029.nBBKTsg8027004@zion.cs.uiuc.edu> Author: grosbach Date: Fri Dec 11 14:29:53 2009 New Revision: 91150 URL: http://llvm.org/viewvc/llvm-project?rev=91150&view=rev Log: memory barrier instructions by definition have side effects. This prevents the post-RA scheduler from moving them around. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91150&r1=91149&r2=91150&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Dec 11 14:29:53 2009 @@ -1574,7 +1574,7 @@ // // memory barriers protect the atomic sequences -let isPredicable = 0 in { +let isPredicable = 0, hasSideEffects = 1 in { def Int_MemBarrierV7 : AI<(outs), (ins), Pseudo, NoItinerary, "dmb", "", From gohman at apple.com Fri Dec 11 15:31:27 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 21:31:27 -0000 Subject: [llvm-commits] [llvm] r91158 - in /llvm/trunk: include/llvm/CodeGen/ValueTypes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/vec_ext_inreg.ll Message-ID: <200912112131.nBBLVSbn029491@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 11 15:31:27 2009 New Revision: 91158 URL: http://llvm.org/viewvc/llvm-project?rev=91158&view=rev Log: Implement vector widening, splitting, and scalarizing for SIGN_EXTEND_INREG. Added: llvm/trunk/test/CodeGen/X86/vec_ext_inreg.ll Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Fri Dec 11 15:31:27 2009 @@ -166,6 +166,12 @@ return *this; } } + + /// getScalarType - If this is a vector type, return the element type, + /// otherwise return this. + MVT getScalarType() const { + return isVector() ? getVectorElementType() : *this; + } MVT getVectorElementType() const { switch (SimpleTy) { @@ -524,6 +530,12 @@ return V; } + /// getScalarType - If this is a vector type, return the element type, + /// otherwise return this. + EVT getScalarType() const { + return isVector() ? getVectorElementType() : *this; + } + /// getVectorElementType - Given a vector type, return the type of /// each element. EVT getVectorElementType() const { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Dec 11 15:31:27 2009 @@ -119,7 +119,8 @@ /// it can be simplified or if things it uses can be simplified by bit /// propagation. If so, return true. bool SimplifyDemandedBits(SDValue Op) { - APInt Demanded = APInt::getAllOnesValue(Op.getValueSizeInBits()); + unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits(); + APInt Demanded = APInt::getAllOnesValue(BitWidth); return SimplifyDemandedBits(Op, Demanded); } @@ -2441,7 +2442,7 @@ ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); EVT VT = N0.getValueType(); - unsigned OpSizeInBits = VT.getSizeInBits(); + unsigned OpSizeInBits = VT.getScalarType().getSizeInBits(); // fold (shl c1, c2) -> c1< (shl x, (and (trunc y), (trunc c))). if (N1.getOpcode() == ISD::TRUNCATE && @@ -2533,6 +2534,7 @@ ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); EVT VT = N0.getValueType(); + unsigned OpSizeInBits = VT.getScalarType().getSizeInBits(); // fold (sra c1, c2) -> (sra c1, c2) if (N0C && N1C) @@ -2544,7 +2546,7 @@ if (N0C && N0C->isAllOnesValue()) return N0; // fold (sra x, (setge c, size(x))) -> undef - if (N1C && N1C->getZExtValue() >= VT.getSizeInBits()) + if (N1C && N1C->getZExtValue() >= OpSizeInBits) return DAG.getUNDEF(VT); // fold (sra x, 0) -> x if (N1C && N1C->isNullValue()) @@ -2552,7 +2554,7 @@ // fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and target supports // sext_inreg. if (N1C && N0.getOpcode() == ISD::SHL && N1 == N0.getOperand(1)) { - unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getZExtValue(); + unsigned LowBits = OpSizeInBits - (unsigned)N1C->getZExtValue(); EVT EVT = EVT::getIntegerVT(*DAG.getContext(), LowBits); if ((!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT))) return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, @@ -2563,7 +2565,7 @@ if (N1C && N0.getOpcode() == ISD::SRA) { if (ConstantSDNode *C1 = dyn_cast(N0.getOperand(1))) { unsigned Sum = N1C->getZExtValue() + C1->getZExtValue(); - if (Sum >= VT.getSizeInBits()) Sum = VT.getSizeInBits()-1; + if (Sum >= OpSizeInBits) Sum = OpSizeInBits-1; return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(Sum, N1C->getValueType(0))); } @@ -2579,9 +2581,8 @@ const ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); if (N01C && N1C) { // Determine what the truncate's result bitsize and type would be. - unsigned VTValSize = VT.getSizeInBits(); EVT TruncVT = - EVT::getIntegerVT(*DAG.getContext(), VTValSize - N1C->getZExtValue()); + EVT::getIntegerVT(*DAG.getContext(), OpSizeInBits - N1C->getZExtValue()); // Determine the residual right-shift amount. signed ShiftAmt = N1C->getZExtValue() - N01C->getZExtValue(); @@ -2614,7 +2615,7 @@ EVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); APInt TruncC = N101C->getAPIntValue(); - TruncC.trunc(TruncVT.getSizeInBits()); + TruncC.trunc(TruncVT.getScalarType().getSizeInBits()); return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, @@ -2643,7 +2644,7 @@ ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); EVT VT = N0.getValueType(); - unsigned OpSizeInBits = VT.getSizeInBits(); + unsigned OpSizeInBits = VT.getScalarType().getSizeInBits(); // fold (srl c1, c2) -> c1 >>u c2 if (N0C && N1C) @@ -3036,7 +3037,7 @@ else if (Op.getValueType().bitsGT(VT)) Op = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), VT, Op); return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, Op, - DAG.getValueType(N0.getValueType())); + DAG.getValueType(N0.getValueType().getScalarType())); } } @@ -3177,7 +3178,8 @@ } else if (Op.getValueType().bitsGT(VT)) { Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Op); } - return DAG.getZeroExtendInReg(Op, N->getDebugLoc(), N0.getValueType()); + return DAG.getZeroExtendInReg(Op, N->getDebugLoc(), + N0.getValueType().getScalarType()); } // Fold (zext (and (trunc x), cst)) -> (and x, cst), @@ -3536,7 +3538,7 @@ SDValue N1 = N->getOperand(1); EVT VT = N->getValueType(0); EVT EVT = cast(N1)->getVT(); - unsigned VTBits = VT.getSizeInBits(); + unsigned VTBits = VT.getScalarType().getSizeInBits(); unsigned EVTBits = EVT.getSizeInBits(); // fold (sext_in_reg c1) -> c1 @@ -3544,7 +3546,7 @@ return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, N0, N1); // If the input is already sign extended, just drop the extension. - if (DAG.ComputeNumSignBits(N0) >= VT.getSizeInBits()-EVTBits+1) + if (DAG.ComputeNumSignBits(N0) >= VTBits-EVTBits+1) return N0; // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 @@ -3559,7 +3561,7 @@ // if x is small enough. if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) { SDValue N00 = N0.getOperand(0); - if (N00.getValueType().getSizeInBits() < EVTBits) + if (N00.getValueType().getScalarType().getSizeInBits() < EVTBits) return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, N00, N1); } @@ -3583,11 +3585,11 @@ // We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above. if (N0.getOpcode() == ISD::SRL) { if (ConstantSDNode *ShAmt = dyn_cast(N0.getOperand(1))) - if (ShAmt->getZExtValue()+EVTBits <= VT.getSizeInBits()) { + if (ShAmt->getZExtValue()+EVTBits <= VTBits) { // We can turn this into an SRA iff the input to the SRL is already sign // extended enough. unsigned InSignBits = DAG.ComputeNumSignBits(N0.getOperand(0)); - if (VT.getSizeInBits()-(ShAmt->getZExtValue()+EVTBits) < InSignBits) + if (VTBits-(ShAmt->getZExtValue()+EVTBits) < InSignBits) return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0.getOperand(0), N0.getOperand(1)); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Dec 11 15:31:27 2009 @@ -2294,9 +2294,16 @@ // NOTE: we could fall back on load/store here too for targets without // SAR. However, it is doubtful that any exist. EVT ExtraVT = cast(Node->getOperand(1))->getVT(); - unsigned BitsDiff = Node->getValueType(0).getSizeInBits() - + EVT VT = Node->getValueType(0); + EVT ShiftAmountTy = TLI.getShiftAmountTy(); + if (ExtraVT.isVector()) ExtraVT = ExtraVT.getVectorElementType(); + if (VT.isVector()) { + ShiftAmountTy = VT; + VT = VT.getVectorElementType(); + } + unsigned BitsDiff = VT.getSizeInBits() - ExtraVT.getSizeInBits(); - SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy()); + SDValue ShiftCst = DAG.getConstant(BitsDiff, ShiftAmountTy); Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), Node->getOperand(0), ShiftCst); Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Fri Dec 11 15:31:27 2009 @@ -517,6 +517,7 @@ SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N); SDValue ScalarizeVecRes_LOAD(LoadSDNode *N); SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N); + SDValue ScalarizeVecRes_SIGN_EXTEND_INREG(SDNode *N); SDValue ScalarizeVecRes_SELECT(SDNode *N); SDValue ScalarizeVecRes_SELECT_CC(SDNode *N); SDValue ScalarizeVecRes_SETCC(SDNode *N); @@ -560,6 +561,7 @@ void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); + void SplitVecRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo, @@ -602,6 +604,7 @@ SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N); SDValue WidenVecRes_LOAD(SDNode* N); SDValue WidenVecRes_SCALAR_TO_VECTOR(SDNode* N); + SDValue WidenVecRes_SIGN_EXTEND_INREG(SDNode* N); SDValue WidenVecRes_SELECT(SDNode* N); SDValue WidenVecRes_SELECT_CC(SDNode* N); SDValue WidenVecRes_UNDEF(SDNode *N); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp Fri Dec 11 15:31:27 2009 @@ -179,6 +179,7 @@ case ISD::FRINT: case ISD::FNEARBYINT: case ISD::FFLOOR: + case ISD::SIGN_EXTEND_INREG: QueryType = Node->getValueType(0); break; case ISD::SINT_TO_FP: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Fri Dec 11 15:31:27 2009 @@ -54,6 +54,7 @@ case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast(N));break; case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break; + case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_SIGN_EXTEND_INREG(N); break; case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break; case ISD::SETCC: R = ScalarizeVecRes_SETCC(N); break; @@ -195,6 +196,13 @@ return InOp; } +SDValue DAGTypeLegalizer::ScalarizeVecRes_SIGN_EXTEND_INREG(SDNode *N) { + EVT EltVT = N->getValueType(0).getVectorElementType(); + SDValue LHS = GetScalarizedVector(N->getOperand(0)); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), EltVT, + LHS, N->getOperand(1)); +} + SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(1)); return DAG.getNode(ISD::SELECT, N->getDebugLoc(), @@ -401,6 +409,7 @@ case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break; + case ISD::SIGN_EXTEND_INREG: SplitVecRes_SIGN_EXTEND_INREG(N, Lo, Hi); break; case ISD::LOAD: SplitVecRes_LOAD(cast(N), Lo, Hi); break; @@ -700,6 +709,18 @@ Hi = DAG.getUNDEF(HiVT); } +void DAGTypeLegalizer::SplitVecRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue LHSLo, LHSHi; + GetSplitVector(N->getOperand(0), LHSLo, LHSHi); + DebugLoc dl = N->getDebugLoc(); + + Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, + N->getOperand(1)); + Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, + N->getOperand(1)); +} + void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi) { assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!"); @@ -1141,6 +1162,7 @@ case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break; case ISD::LOAD: Res = WidenVecRes_LOAD(N); break; case ISD::SCALAR_TO_VECTOR: Res = WidenVecRes_SCALAR_TO_VECTOR(N); break; + case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_SIGN_EXTEND_INREG(N); break; case ISD::SELECT: Res = WidenVecRes_SELECT(N); break; case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break; @@ -1691,6 +1713,13 @@ WidenVT, N->getOperand(0)); } +SDValue DAGTypeLegalizer::WidenVecRes_SIGN_EXTEND_INREG(SDNode *N) { + EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDValue WidenLHS = GetWidenedVector(N->getOperand(0)); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), + WidenVT, WidenLHS, N->getOperand(1)); +} + SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); unsigned WidenNumElts = WidenVT.getVectorNumElements(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Dec 11 15:31:27 2009 @@ -832,8 +832,12 @@ } SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, EVT VT) { + assert(!VT.isVector() && + "getZeroExtendInReg should use the vector element type instead of " + "the vector type!"); if (Op.getValueType() == VT) return Op; - APInt Imm = APInt::getLowBitsSet(Op.getValueSizeInBits(), + unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits(); + APInt Imm = APInt::getLowBitsSet(BitWidth, VT.getSizeInBits()); return getNode(ISD::AND, DL, Op.getValueType(), Op, getConstant(Imm, Op.getValueType())); @@ -1481,7 +1485,7 @@ if (Op.getValueType().isVector()) return false; - unsigned BitWidth = Op.getValueSizeInBits(); + unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits(); return MaskedValueIsZero(Op, APInt::getSignBit(BitWidth), Depth); } @@ -1504,7 +1508,7 @@ APInt &KnownZero, APInt &KnownOne, unsigned Depth) const { unsigned BitWidth = Mask.getBitWidth(); - assert(BitWidth == Op.getValueType().getSizeInBits() && + assert(BitWidth == Op.getValueType().getScalarType().getSizeInBits() && "Mask size mismatches value type size!"); KnownZero = KnownOne = APInt(BitWidth, 0); // Don't know anything. @@ -1761,7 +1765,7 @@ } case ISD::ZERO_EXTEND: { EVT InVT = Op.getOperand(0).getValueType(); - unsigned InBits = InVT.getSizeInBits(); + unsigned InBits = InVT.getScalarType().getSizeInBits(); APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask; APInt InMask = Mask; InMask.trunc(InBits); @@ -1775,7 +1779,7 @@ } case ISD::SIGN_EXTEND: { EVT InVT = Op.getOperand(0).getValueType(); - unsigned InBits = InVT.getSizeInBits(); + unsigned InBits = InVT.getScalarType().getSizeInBits(); APInt InSignBit = APInt::getSignBit(InBits); APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask; APInt InMask = Mask; @@ -1816,7 +1820,7 @@ } case ISD::ANY_EXTEND: { EVT InVT = Op.getOperand(0).getValueType(); - unsigned InBits = InVT.getSizeInBits(); + unsigned InBits = InVT.getScalarType().getSizeInBits(); APInt InMask = Mask; InMask.trunc(InBits); KnownZero.trunc(InBits); @@ -1828,7 +1832,7 @@ } case ISD::TRUNCATE: { EVT InVT = Op.getOperand(0).getValueType(); - unsigned InBits = InVT.getSizeInBits(); + unsigned InBits = InVT.getScalarType().getSizeInBits(); APInt InMask = Mask; InMask.zext(InBits); KnownZero.zext(InBits); @@ -1961,7 +1965,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ EVT VT = Op.getValueType(); assert(VT.isInteger() && "Invalid VT!"); - unsigned VTBits = VT.getSizeInBits(); + unsigned VTBits = VT.getScalarType().getSizeInBits(); unsigned Tmp, Tmp2; unsigned FirstAnswer = 1; @@ -1988,7 +1992,7 @@ } case ISD::SIGN_EXTEND: - Tmp = VTBits-Op.getOperand(0).getValueType().getSizeInBits(); + Tmp = VTBits-Op.getOperand(0).getValueType().getScalarType().getSizeInBits(); return ComputeNumSignBits(Op.getOperand(0), Depth+1) + Tmp; case ISD::SIGN_EXTEND_INREG: @@ -2624,6 +2628,9 @@ assert(VT == N1.getValueType() && "Not an inreg extend!"); assert(VT.isInteger() && EVT.isInteger() && "Cannot *_EXTEND_INREG FP types"); + assert(!EVT.isVector() && + "AssertSExt/AssertZExt type should be the vector element type " + "rather than the vector type!"); assert(EVT.bitsLE(VT) && "Not extending!"); if (VT == EVT) return N1; // noop assertion. break; @@ -2633,12 +2640,15 @@ assert(VT == N1.getValueType() && "Not an inreg extend!"); assert(VT.isInteger() && EVT.isInteger() && "Cannot *_EXTEND_INREG FP types"); - assert(EVT.bitsLE(VT) && "Not extending!"); + assert(!EVT.isVector() && + "SIGN_EXTEND_INREG type should be the vector element type rather " + "than the vector type!"); + assert(EVT.bitsLE(VT.getScalarType()) && "Not extending!"); if (EVT == VT) return N1; // Not actually extending if (N1C) { APInt Val = N1C->getAPIntValue(); - unsigned FromBits = cast(N2)->getVT().getSizeInBits(); + unsigned FromBits = EVT.getSizeInBits(); Val <<= Val.getBitWidth()-FromBits; Val = Val.ashr(Val.getBitWidth()-FromBits); return getConstant(Val, VT); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Fri Dec 11 15:31:27 2009 @@ -911,7 +911,7 @@ TargetLoweringOpt &TLO, unsigned Depth) const { unsigned BitWidth = DemandedMask.getBitWidth(); - assert(Op.getValueSizeInBits() == BitWidth && + assert(Op.getValueType().getScalarType().getSizeInBits() == BitWidth && "Mask size mismatches value type size!"); APInt NewMask = DemandedMask; DebugLoc dl = Op.getDebugLoc(); @@ -1240,7 +1240,7 @@ // demand the input sign bit. APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt); if (HighBits.intersects(NewMask)) - InDemandedMask |= APInt::getSignBit(VT.getSizeInBits()); + InDemandedMask |= APInt::getSignBit(VT.getScalarType().getSizeInBits()); if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask, KnownZero, KnownOne, TLO, Depth+1)) Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=91158&r1=91157&r2=91158&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 11 15:31:27 2009 @@ -595,6 +595,7 @@ setOperationAction(ISD::FP_TO_SINT, (MVT::SimpleValueType)VT, Expand); setOperationAction(ISD::UINT_TO_FP, (MVT::SimpleValueType)VT, Expand); setOperationAction(ISD::SINT_TO_FP, (MVT::SimpleValueType)VT, Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, (MVT::SimpleValueType)VT,Expand); } // FIXME: In order to prevent SSE instructions being expanded to MMX ones Added: llvm/trunk/test/CodeGen/X86/vec_ext_inreg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_ext_inreg.ll?rev=91158&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_ext_inreg.ll (added) +++ llvm/trunk/test/CodeGen/X86/vec_ext_inreg.ll Fri Dec 11 15:31:27 2009 @@ -0,0 +1,37 @@ +; RUN: llc < %s -march=x86-64 + +define <8 x i32> @a(<8 x i32> %a) nounwind { + %b = trunc <8 x i32> %a to <8 x i16> + %c = sext <8 x i16> %b to <8 x i32> + ret <8 x i32> %c +} + +define <3 x i32> @b(<3 x i32> %a) nounwind { + %b = trunc <3 x i32> %a to <3 x i16> + %c = sext <3 x i16> %b to <3 x i32> + ret <3 x i32> %c +} + +define <1 x i32> @c(<1 x i32> %a) nounwind { + %b = trunc <1 x i32> %a to <1 x i16> + %c = sext <1 x i16> %b to <1 x i32> + ret <1 x i32> %c +} + +define <8 x i32> @d(<8 x i32> %a) nounwind { + %b = trunc <8 x i32> %a to <8 x i16> + %c = zext <8 x i16> %b to <8 x i32> + ret <8 x i32> %c +} + +define <3 x i32> @e(<3 x i32> %a) nounwind { + %b = trunc <3 x i32> %a to <3 x i16> + %c = zext <3 x i16> %b to <3 x i32> + ret <3 x i32> %c +} + +define <1 x i32> @f(<1 x i32> %a) nounwind { + %b = trunc <1 x i32> %a to <1 x i16> + %c = zext <1 x i16> %b to <1 x i32> + ret <1 x i32> %c +} From bob.wilson at apple.com Fri Dec 11 15:31:06 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 13:31:06 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912111228u3edb21c1qa1952f66f4c19f5f@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <38a0d8450912021439y640f9183q220319ca5dbf087e@mail.gmail.com> <38a0d8450912101519k56de61b7j4eade31b76edf80f@mail.gmail.com> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> <38a0d8450912111228u3edb21c1qa1952f66f4c19f5f@mail.gmail.com> Message-ID: On Dec 11, 2009, at 12:28 PM, Rafael Espindola wrote: >>> Which is good, since *all* of stuct foo is passed on the stack. >> >> You're right about x86-64 -- I was misremembering that. x86 and ppc use byval. > > So, for x86 that is fine too since all of the struct will be passed in > the stack. I don't know ppc, > >> You are right about the code quality. If you want to implement something like the x86-64 solution, that would be great. > > Yes, I want something like x86-64. The big difference that we have to > account for on ARM is that it can split structures with a part going > to registers and a part going to the stack. > > *) For the part that goes in registers, we should just use i32 (x86-64 > uses i64). Do you agree with that? > *) For the part that goes in the stack I see 2 options > 1) Use simple integers (i8, i16 ...) > 2) Use a byval > > Option 1 is easier to implement. Option 2 is probably the best since > it makes it explicit that something is going to memory. One > disadvantage of option 2 is that we introduce a new type representing > the bits that go to memory. > > Do you see other options? Which one do you like best? I don't know. Honestly, I think those choices may be the least of your worries. If llvm-gcc is going to figure out exactly how each argument will be passed, there are a lot of details to get right. If you can come up with something that works with APCS, AAPCS, and AAPCS-hardfloat, preferably both big- and little-endian (watch out for structure padding differences with those), and passes the GCC ABI compatibility testsuite, I don't much care how you do it. If I don't get pulled into other work, I'll probably go ahead with the "byval" implementation. That would at least give you a baseline to compare against. From dpatel at apple.com Fri Dec 11 15:37:07 2009 From: dpatel at apple.com (Devang Patel) Date: Fri, 11 Dec 2009 21:37:07 -0000 Subject: [llvm-commits] [llvm] r91159 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200912112137.nBBLb7VX029695@zion.cs.uiuc.edu> Author: dpatel Date: Fri Dec 11 15:37:07 2009 New Revision: 91159 URL: http://llvm.org/viewvc/llvm-project?rev=91159&view=rev Log: Construct CompileUnits lazily. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=91159&r1=91158&r2=91159&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Dec 11 15:37:07 2009 @@ -393,7 +393,7 @@ return; unsigned Line = V->getLineNumber(); - unsigned FileID = findCompileUnit(V->getCompileUnit()).getID(); + unsigned FileID = findCompileUnit(V->getCompileUnit())->getID(); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -407,7 +407,7 @@ return; unsigned Line = G->getLineNumber(); - unsigned FileID = findCompileUnit(G->getCompileUnit()).getID(); + unsigned FileID = findCompileUnit(G->getCompileUnit())->getID(); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -425,7 +425,7 @@ unsigned Line = SP->getLineNumber(); - unsigned FileID = findCompileUnit(SP->getCompileUnit()).getID(); + unsigned FileID = findCompileUnit(SP->getCompileUnit())->getID(); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -440,7 +440,7 @@ return; unsigned Line = Ty->getLineNumber(); - unsigned FileID = findCompileUnit(CU).getID(); + unsigned FileID = findCompileUnit(CU)->getID(); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -1214,11 +1214,12 @@ /// findCompileUnit - Get the compile unit for the given descriptor. /// -CompileUnit &DwarfDebug::findCompileUnit(DICompileUnit Unit) const { +CompileUnit *DwarfDebug::findCompileUnit(DICompileUnit Unit) { DenseMap::const_iterator I = CompileUnitMap.find(Unit.getNode()); - assert(I != CompileUnitMap.end() && "Missing compile unit."); - return *I->second; + if (I == CompileUnitMap.end()) + return constructCompileUnit(Unit.getNode()); + return I->second; } /// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. @@ -1579,7 +1580,7 @@ return SrcId; } -void DwarfDebug::constructCompileUnit(MDNode *N) { +CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); StringRef Dir = DIUnit.getDirectory(); @@ -1618,6 +1619,7 @@ CompileUnitMap[DIUnit.getNode()] = Unit; CompileUnits.push_back(Unit); + return Unit; } void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=91159&r1=91158&r2=91159&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Fri Dec 11 15:37:07 2009 @@ -364,7 +364,7 @@ /// findCompileUnit - Get the compile unit for the given descriptor. /// - CompileUnit &findCompileUnit(DICompileUnit Unit) const; + CompileUnit *findCompileUnit(DICompileUnit Unit); /// getUpdatedDbgScope - Find or create DbgScope assicated with /// the instruction. Initialize scope and update scope hierarchy. @@ -495,7 +495,7 @@ /// as well. unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName); - void constructCompileUnit(MDNode *N); + CompileUnit *constructCompileUnit(MDNode *N); void constructGlobalVariableDIE(MDNode *N); From isanbard at gmail.com Fri Dec 11 15:47:36 2009 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 11 Dec 2009 21:47:36 -0000 Subject: [llvm-commits] [llvm] r91161 - in /llvm/trunk/lib/CodeGen: BranchFolding.cpp MachineBasicBlock.cpp Message-ID: <200912112147.nBBLlatQ030057@zion.cs.uiuc.edu> Author: void Date: Fri Dec 11 15:47:36 2009 New Revision: 91161 URL: http://llvm.org/viewvc/llvm-project?rev=91161&view=rev Log: Don't try to move a MBB into the fall-through position if it's a landing pad or branches only to a landing pad. Without this check, the compiler would go into an infinite loop because the branch to a landing pad is an "abnormal" edge which wasn't being taken into account. This is the meat of that fix: if (!PrevBB.canFallThrough() && !MBB->BranchesToLandingPad(MBB)) { The other stuff is simplification of the "branches to a landing pad" code. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=91161&r1=91160&r2=91161&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Fri Dec 11 15:47:36 2009 @@ -1205,11 +1205,11 @@ } } - // If the prior block doesn't fall through into this block, and if this - // block doesn't fall through into some other block, see if we can find a - // place to move this block where a fall-through will happen. - if (!PrevBB.canFallThrough()) { - + // If the prior block doesn't fall through into this block and if this block + // doesn't fall through into some other block and it's not branching only to a + // landing pad, then see if we can find a place to move this block where a + // fall-through will happen. + if (!PrevBB.canFallThrough() && !MBB->BranchesToLandingPad(MBB)) { // Now we know that there was no fall-through into this block, check to // see if it has a fall-through into its successor. bool CurFallsThru = MBB->canFallThrough(); @@ -1221,28 +1221,32 @@ E = MBB->pred_end(); PI != E; ++PI) { // Analyze the branch at the end of the pred. MachineBasicBlock *PredBB = *PI; - MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough; + MachineFunction::iterator PredNextBB = PredBB; ++PredNextBB; MachineBasicBlock *PredTBB, *PredFBB; SmallVector PredCond; - if (PredBB != MBB && !PredBB->canFallThrough() && - !TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true) + if (PredBB != MBB && !PredBB->canFallThrough() + && !TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true) && (!CurFallsThru || !CurTBB || !CurFBB) && (!CurFallsThru || MBB->getNumber() >= PredBB->getNumber())) { - // If the current block doesn't fall through, just move it. - // If the current block can fall through and does not end with a - // conditional branch, we need to append an unconditional jump to - // the (current) next block. To avoid a possible compile-time - // infinite loop, move blocks only backward in this case. - // Also, if there are already 2 branches here, we cannot add a third; - // this means we have the case - // Bcc next - // B elsewhere - // next: + // If the current block doesn't fall through, just move it. If the + // current block can fall through and does not end with a conditional + // branch, we need to append an unconditional jump to the (current) + // next block. To avoid a possible compile-time infinite loop, move + // blocks only backward in this case. + // + // Also, if there are already 2 branches here, we cannot add a third. + // I.e. we have the case: + // + // Bcc next + // B elsewhere + // next: if (CurFallsThru) { - MachineBasicBlock *NextBB = llvm::next(MachineFunction::iterator(MBB)); + MachineBasicBlock *NextBB = + llvm::next(MachineFunction::iterator(MBB)); CurCond.clear(); TII->InsertBranch(*MBB, NextBB, 0, CurCond); } + MBB->moveAfter(PredBB); MadeChange = true; goto ReoptimizeBlock; Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=91161&r1=91160&r2=91161&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Fri Dec 11 15:47:36 2009 @@ -457,16 +457,9 @@ SmallSet Visited; const MachineBasicBlock *CurMBB = MBB; - while (!Visited.count(CurMBB) && !CurMBB->isLandingPad()) { - if (CurMBB->size() != 1 || CurMBB->succ_empty() || CurMBB->succ_size() != 1) - break; - - const TargetInstrInfo *TII = - CurMBB->getParent()->getTarget().getInstrInfo(); - if (!TII->isUnpredicatedTerminator(CurMBB->begin())) - break; - - Visited.insert(CurMBB); + while (!CurMBB->isLandingPad()) { + if (CurMBB->succ_size() != 1) break; + if (!Visited.insert(CurMBB)) break; CurMBB = *CurMBB->succ_begin(); } From espindola at google.com Fri Dec 11 16:02:04 2009 From: espindola at google.com (Rafael Espindola) Date: Fri, 11 Dec 2009 17:02:04 -0500 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> <38a0d8450912111228u3edb21c1qa1952f66f4c19f5f@mail.gmail.com> Message-ID: <38a0d8450912111402h44a1cf3fxa3a70f13ebfd8952@mail.gmail.com> > I don't know. > > Honestly, I think those choices may be the least of your worries. ?If llvm-gcc is going to figure out exactly how each argument will be passed, there are a lot of details to get right. ?If you can come up with something that works with APCS, AAPCS, and AAPCS-hardfloat, preferably both big- and little-endian (watch out for structure padding differences with those), and passes the GCC ABI compatibility testsuite, I don't much care how you do it. > > If I don't get pulled into other work, I'll probably go ahead with the "byval" implementation. ?That would at least give you a baseline to compare against. Just to be explicit, the above case with a char[5] should expand to %struct.foo_part = type { i8 } declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) I am happy to do as much testing as needed, but I will try to fix just pr5406 first. Can you provide some details on how do I run the "GCC ABI compatibility testsuite" for APCS, AAPCS, and AAPCS-hardfloat? I will make sure I don't introduce a regression on it. Cheers, -- Rafael ?vila de Esp?ndola From asl at math.spbu.ru Fri Dec 11 17:01:30 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 11 Dec 2009 23:01:30 -0000 Subject: [llvm-commits] [llvm] r91175 - in /llvm/trunk: lib/Target/MSP430/MSP430ISelLowering.cpp lib/Target/MSP430/MSP430ISelLowering.h test/CodeGen/MSP430/setcc.ll Message-ID: <200912112301.nBBN1U5W000376@zion.cs.uiuc.edu> Author: asl Date: Fri Dec 11 17:01:29 2009 New Revision: 91175 URL: http://llvm.org/viewvc/llvm-project?rev=91175&view=rev Log: Lower setcc branchless, if this is profitable. Based on the patch by Brian Lucas! Added: llvm/trunk/test/CodeGen/MSP430/setcc.ll Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=91175&r1=91174&r2=91175&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Fri Dec 11 17:01:29 2009 @@ -115,8 +115,8 @@ setOperationAction(ISD::BR_CC, MVT::i8, Custom); setOperationAction(ISD::BR_CC, MVT::i16, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Expand); - setOperationAction(ISD::SETCC, MVT::i8, Expand); - setOperationAction(ISD::SETCC, MVT::i16, Expand); + setOperationAction(ISD::SETCC, MVT::i8, Custom); + setOperationAction(ISD::SETCC, MVT::i16, Custom); setOperationAction(ISD::SELECT, MVT::i8, Expand); setOperationAction(ISD::SELECT, MVT::i16, Expand); setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); @@ -183,6 +183,7 @@ case ISD::SRA: return LowerShifts(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); + case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); @@ -701,6 +702,88 @@ Chain, Dest, TargetCC, Flag); } + +SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + DebugLoc dl = Op.getDebugLoc(); + + // If we are doing an AND and testing against zero, then the CMP + // will not be generated. The AND (or BIT) will generate the condition codes, + // but they are different from CMP. + bool andCC = false; + if (ConstantSDNode *RHSC = dyn_cast(RHS)) { + if (RHSC->isNullValue() && LHS.hasOneUse() && + (LHS.getOpcode() == ISD::AND || + (LHS.getOpcode() == ISD::TRUNCATE && + LHS.getOperand(0).getOpcode() == ISD::AND))) { + andCC = true; + } + } + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + SDValue TargetCC; + SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); + + // Get the condition codes directly from the status register, if its easy. + // Otherwise a branch will be generated. Note that the AND and BIT + // instructions generate different flags than CMP, the carry bit can be used + // for NE/EQ. + bool Invert = false; + bool Shift = false; + bool Convert = true; + switch (cast(TargetCC)->getZExtValue()) { + default: + Convert = false; + break; + case MSP430CC::COND_HS: + // Res = SRW & 1, no processing is required + break; + case MSP430CC::COND_LO: + // Res = ~(SRW & 1) + Invert = true; + break; + case MSP430CC::COND_NE: + if (andCC) { + // C = ~Z, thus Res = SRW & 1, no processing is required + } else { + // Res = (SRW >> 1) & 1 + Shift = true; + } + break; + case MSP430CC::COND_E: + if (andCC) { + // C = ~Z, thus Res = ~(SRW & 1) + } else { + // Res = ~((SRW >> 1) & 1) + Shift = true; + } + Invert = true; + break; + } + EVT VT = Op.getValueType(); + SDValue One = DAG.getConstant(1, VT); + if (Convert) { + SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, + MVT::i16, Flag); + if (Shift) + // FIXME: somewhere this is turned into a SRL, lower it MSP specific? + SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); + SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); + if (Invert) + SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); + return SR; + } else { + SDValue Zero = DAG.getConstant(0, VT); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SmallVector Ops; + Ops.push_back(One); + Ops.push_back(Zero); + Ops.push_back(TargetCC); + Ops.push_back(Flag); + return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); + } +} + SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h?rev=91175&r1=91174&r2=91175&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h Fri Dec 11 17:01:29 2009 @@ -84,6 +84,7 @@ SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG); SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); + SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG); SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG); Added: llvm/trunk/test/CodeGen/MSP430/setcc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/setcc.ll?rev=91175&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/MSP430/setcc.ll (added) +++ llvm/trunk/test/CodeGen/MSP430/setcc.ll Fri Dec 11 17:01:29 2009 @@ -0,0 +1,116 @@ +; RUN: llc -march=msp430 < %s | FileCheck %s +target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:32" +target triple = "msp430-generic-generic" + +define i16 @sccweqand(i16 %a, i16 %b) nounwind { + %t1 = and i16 %a, %b + %t2 = icmp eq i16 %t1, 0 + %t3 = zext i1 %t2 to i16 + ret i16 %t3 +} +; CHECK: sccweqand: +; CHECK: bit.w r14, r15 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 +; CHECK-NEXT: xor.w #1, r15 + +define i16 @sccwneand(i16 %a, i16 %b) nounwind { + %t1 = and i16 %a, %b + %t2 = icmp ne i16 %t1, 0 + %t3 = zext i1 %t2 to i16 + ret i16 %t3 +} +; CHECK: sccwneand: +; CHECK: bit.w r14, r15 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 + +define i16 @sccwne(i16 %a, i16 %b) nounwind { + %t1 = icmp ne i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccwne: +; CHECK: cmp.w r15, r14 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: rra.w r15 +; CHECK-NEXT: and.w #1, r15 + +define i16 @sccweq(i16 %a, i16 %b) nounwind { + %t1 = icmp eq i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccweq: +; CHECK: cmp.w r15, r14 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: rra.w r15 +; CHECK-NEXT: and.w #1, r15 +; CHECK-NEXT: xor.w #1, r15 + +define i16 @sccwugt(i16 %a, i16 %b) nounwind { + %t1 = icmp ugt i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccwugt: +; CHECK: cmp.w r14, r15 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 +; CHECK-NEXT: xor.w #1, r15 + +define i16 @sccwuge(i16 %a, i16 %b) nounwind { + %t1 = icmp uge i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccwuge: +; CHECK: cmp.w r15, r14 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 + +define i16 @sccwult(i16 %a, i16 %b) nounwind { + %t1 = icmp ult i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccwult: +; CHECK: cmp.w r15, r14 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 +; CHECK-NEXT: xor.w #1, r15 + +define i16 @sccwule(i16 %a, i16 %b) nounwind { + %t1 = icmp ule i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} +; CHECK:sccwule: +; CHECK: cmp.w r14, r15 +; CHECK-NEXT: mov.w r2, r15 +; CHECK-NEXT: and.w #1, r15 + +define i16 @sccwsgt(i16 %a, i16 %b) nounwind { + %t1 = icmp sgt i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} + +define i16 @sccwsge(i16 %a, i16 %b) nounwind { + %t1 = icmp sge i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} + +define i16 @sccwslt(i16 %a, i16 %b) nounwind { + %t1 = icmp slt i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} + +define i16 @sccwsle(i16 %a, i16 %b) nounwind { + %t1 = icmp sle i16 %a, %b + %t2 = zext i1 %t1 to i16 + ret i16 %t2 +} + From gohman at apple.com Fri Dec 11 17:26:08 2009 From: gohman at apple.com (Dan Gohman) Date: Fri, 11 Dec 2009 23:26:08 -0000 Subject: [llvm-commits] [llvm] r91181 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200912112326.nBBNQ8bI001625@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 11 17:26:08 2009 New Revision: 91181 URL: http://llvm.org/viewvc/llvm-project?rev=91181&view=rev Log: Delete an unnecessary line. The VTSDNode on a SIGN_EXTEND_REG is never a vector type. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=91181&r1=91180&r2=91181&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Dec 11 17:26:08 2009 @@ -2296,7 +2296,6 @@ EVT ExtraVT = cast(Node->getOperand(1))->getVT(); EVT VT = Node->getValueType(0); EVT ShiftAmountTy = TLI.getShiftAmountTy(); - if (ExtraVT.isVector()) ExtraVT = ExtraVT.getVectorElementType(); if (VT.isVector()) { ShiftAmountTy = VT; VT = VT.getVectorElementType(); From bob.wilson at apple.com Fri Dec 11 17:47:40 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 23:47:40 -0000 Subject: [llvm-commits] [llvm] r91184 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Message-ID: <200912112347.nBBNleh0002511@zion.cs.uiuc.edu> Author: bwilson Date: Fri Dec 11 17:47:40 2009 New Revision: 91184 URL: http://llvm.org/viewvc/llvm-project?rev=91184&view=rev Log: Revise scalar replacement to be more flexible about handle bitcasts and GEPs. While scanning through the uses of an alloca, keep track of the current offset relative to the start of the alloca, and check memory references to see if the offset & size correspond to a component within the alloca. This has the nice benefit of unifying much of the code from isSafeUseOfAllocation, isSafeElementUse, and isSafeUseOfBitCastedAllocation. The code to rewrite the uses of a promoted alloca, after it is determined to be safe, is reorganized in the same way. Also, when rewriting GEP instructions, mark them as "in-bounds" since all the indices are known to be safe. Added: llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=91184&r1=91183&r2=91184&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Fri Dec 11 17:47:40 2009 @@ -102,25 +102,27 @@ int isSafeAllocaToScalarRepl(AllocaInst *AI); - void isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, - AllocaInfo &Info); - void isSafeElementUse(Value *Ptr, bool isFirstElt, AllocaInst *AI, - AllocaInfo &Info); - void isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocaInst *AI, - unsigned OpNo, AllocaInfo &Info); - void isSafeUseOfBitCastedAllocation(BitCastInst *User, AllocaInst *AI, - AllocaInfo &Info); + void isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, + uint64_t ArrayOffset, AllocaInfo &Info); + void isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t &Offset, + uint64_t &ArrayOffset, AllocaInfo &Info); + void isSafeMemAccess(AllocaInst *AI, uint64_t Offset, uint64_t ArrayOffset, + uint64_t MemSize, const Type *MemOpType, bool isStore, + AllocaInfo &Info); + bool TypeHasComponent(const Type *T, uint64_t Offset, uint64_t Size); + unsigned FindElementAndOffset(const Type *&T, uint64_t &Offset); void DoScalarReplacement(AllocaInst *AI, std::vector &WorkList); void CleanupGEP(GetElementPtrInst *GEP); - void CleanupAllocaUsers(AllocaInst *AI); + void CleanupAllocaUsers(Value *V); AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocaInst *Base); - void RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocaInst *AI, - SmallVector &NewElts); - - void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, + void RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, + SmallVector &NewElts); + void RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset, + SmallVector &NewElts); + void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, AllocaInst *AI, SmallVector &NewElts); void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI, @@ -360,176 +362,12 @@ } } - // Now that we have created the alloca instructions that we want to use, - // expand the getelementptr instructions to use them. - while (!AI->use_empty()) { - Instruction *User = cast(AI->use_back()); - if (BitCastInst *BCInst = dyn_cast(User)) { - RewriteBitCastUserOfAlloca(BCInst, AI, ElementAllocas); - BCInst->eraseFromParent(); - continue; - } - - // Replace: - // %res = load { i32, i32 }* %alloc - // with: - // %load.0 = load i32* %alloc.0 - // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0 - // %load.1 = load i32* %alloc.1 - // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1 - // (Also works for arrays instead of structs) - if (LoadInst *LI = dyn_cast(User)) { - Value *Insert = UndefValue::get(LI->getType()); - for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) { - Value *Load = new LoadInst(ElementAllocas[i], "load", LI); - Insert = InsertValueInst::Create(Insert, Load, i, "insert", LI); - } - LI->replaceAllUsesWith(Insert); - LI->eraseFromParent(); - continue; - } - - // Replace: - // store { i32, i32 } %val, { i32, i32 }* %alloc - // with: - // %val.0 = extractvalue { i32, i32 } %val, 0 - // store i32 %val.0, i32* %alloc.0 - // %val.1 = extractvalue { i32, i32 } %val, 1 - // store i32 %val.1, i32* %alloc.1 - // (Also works for arrays instead of structs) - if (StoreInst *SI = dyn_cast(User)) { - Value *Val = SI->getOperand(0); - for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) { - Value *Extract = ExtractValueInst::Create(Val, i, Val->getName(), SI); - new StoreInst(Extract, ElementAllocas[i], SI); - } - SI->eraseFromParent(); - continue; - } - - GetElementPtrInst *GEPI = cast(User); - // We now know that the GEP is of the form: GEP , 0, - unsigned Idx = - (unsigned)cast(GEPI->getOperand(2))->getZExtValue(); - - assert(Idx < ElementAllocas.size() && "Index out of range?"); - AllocaInst *AllocaToUse = ElementAllocas[Idx]; - - Value *RepValue; - if (GEPI->getNumOperands() == 3) { - // Do not insert a new getelementptr instruction with zero indices, only - // to have it optimized out later. - RepValue = AllocaToUse; - } else { - // We are indexing deeply into the structure, so we still need a - // getelement ptr instruction to finish the indexing. This may be - // expanded itself once the worklist is rerun. - // - SmallVector NewArgs; - NewArgs.push_back(Constant::getNullValue( - Type::getInt32Ty(AI->getContext()))); - NewArgs.append(GEPI->op_begin()+3, GEPI->op_end()); - RepValue = GetElementPtrInst::Create(AllocaToUse, NewArgs.begin(), - NewArgs.end(), "", GEPI); - RepValue->takeName(GEPI); - } - - // If this GEP is to the start of the aggregate, check for memcpys. - if (Idx == 0 && GEPI->hasAllZeroIndices()) - RewriteBitCastUserOfAlloca(GEPI, AI, ElementAllocas); - - // Move all of the users over to the new GEP. - GEPI->replaceAllUsesWith(RepValue); - // Delete the old GEP - GEPI->eraseFromParent(); - } - - // Finally, delete the Alloca instruction - AI->eraseFromParent(); + // Now that we have created the new alloca instructions, rewrite all the + // uses of the old alloca. + RewriteForScalarRepl(AI, AI, 0, ElementAllocas); NumReplaced++; } - -/// isSafeElementUse - Check to see if this use is an allowed use for a -/// getelementptr instruction of an array aggregate allocation. isFirstElt -/// indicates whether Ptr is known to the start of the aggregate. -void SROA::isSafeElementUse(Value *Ptr, bool isFirstElt, AllocaInst *AI, - AllocaInfo &Info) { - for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); - I != E; ++I) { - Instruction *User = cast(*I); - switch (User->getOpcode()) { - case Instruction::Load: break; - case Instruction::Store: - // Store is ok if storing INTO the pointer, not storing the pointer - if (User->getOperand(0) == Ptr) return MarkUnsafe(Info); - break; - case Instruction::GetElementPtr: { - GetElementPtrInst *GEP = cast(User); - bool AreAllZeroIndices = isFirstElt; - if (GEP->getNumOperands() > 1 && - (!isa(GEP->getOperand(1)) || - !cast(GEP->getOperand(1))->isZero())) - // Using pointer arithmetic to navigate the array. - return MarkUnsafe(Info); - - // Verify that any array subscripts are in range. - for (gep_type_iterator GEPIt = gep_type_begin(GEP), - E = gep_type_end(GEP); GEPIt != E; ++GEPIt) { - // Ignore struct elements, no extra checking needed for these. - if (isa(*GEPIt)) - continue; - - // This GEP indexes an array. Verify that this is an in-range - // constant integer. Specifically, consider A[0][i]. We cannot know that - // the user isn't doing invalid things like allowing i to index an - // out-of-range subscript that accesses A[1]. Because of this, we have - // to reject SROA of any accesses into structs where any of the - // components are variables. - ConstantInt *IdxVal = dyn_cast(GEPIt.getOperand()); - if (!IdxVal) return MarkUnsafe(Info); - - // Are all indices still zero? - AreAllZeroIndices &= IdxVal->isZero(); - - if (const ArrayType *AT = dyn_cast(*GEPIt)) { - if (IdxVal->getZExtValue() >= AT->getNumElements()) - return MarkUnsafe(Info); - } else if (const VectorType *VT = dyn_cast(*GEPIt)) { - if (IdxVal->getZExtValue() >= VT->getNumElements()) - return MarkUnsafe(Info); - } - } - - isSafeElementUse(GEP, AreAllZeroIndices, AI, Info); - if (Info.isUnsafe) return; - break; - } - case Instruction::BitCast: - if (isFirstElt) { - isSafeUseOfBitCastedAllocation(cast(User), AI, Info); - if (Info.isUnsafe) return; - break; - } - DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); - return MarkUnsafe(Info); - case Instruction::Call: - if (MemIntrinsic *MI = dyn_cast(User)) { - if (isFirstElt) { - isSafeMemIntrinsicOnAllocation(MI, AI, I.getOperandNo(), Info); - if (Info.isUnsafe) return; - break; - } - } - DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); - return MarkUnsafe(Info); - default: - DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); - return MarkUnsafe(Info); - } - } - return; // All users look ok :) -} - + /// AllUsersAreLoads - Return true if all users of this value are loads. static bool AllUsersAreLoads(Value *Ptr) { for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); @@ -539,72 +377,116 @@ return true; } -/// isSafeUseOfAllocation - Check if this user is an allowed use for an -/// aggregate allocation. -void SROA::isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, - AllocaInfo &Info) { - if (BitCastInst *C = dyn_cast(User)) - return isSafeUseOfBitCastedAllocation(C, AI, Info); - - if (LoadInst *LI = dyn_cast(User)) - if (!LI->isVolatile()) - return;// Loads (returning a first class aggregrate) are always rewritable - - if (StoreInst *SI = dyn_cast(User)) - if (!SI->isVolatile() && SI->getOperand(0) != AI) - return;// Store is ok if storing INTO the pointer, not storing the pointer - - GetElementPtrInst *GEPI = dyn_cast(User); - if (GEPI == 0) - return MarkUnsafe(Info); - - gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); +/// isSafeForScalarRepl - Check if instruction I is a safe use with regard to +/// performing scalar replacement of alloca AI. The results are flagged in +/// the Info parameter. Offset and ArrayOffset indicate the position within +/// AI that is referenced by this instruction. +void SROA::isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, + uint64_t ArrayOffset, AllocaInfo &Info) { + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI!=E; ++UI) { + Instruction *User = cast(*UI); - // The GEP is not safe to transform if not of the form "GEP , 0, ". - if (I == E || - I.getOperand() != Constant::getNullValue(I.getOperand()->getType())) { - return MarkUnsafe(Info); + if (BitCastInst *BC = dyn_cast(User)) { + isSafeForScalarRepl(BC, AI, Offset, ArrayOffset, Info); + } else if (GetElementPtrInst *GEPI = dyn_cast(User)) { + uint64_t GEPArrayOffset = ArrayOffset; + uint64_t GEPOffset = Offset; + isSafeGEP(GEPI, AI, GEPOffset, GEPArrayOffset, Info); + if (!Info.isUnsafe) + isSafeForScalarRepl(GEPI, AI, GEPOffset, GEPArrayOffset, Info); + } else if (MemIntrinsic *MI = dyn_cast(UI)) { + ConstantInt *Length = dyn_cast(MI->getLength()); + if (Length) + isSafeMemAccess(AI, Offset, ArrayOffset, Length->getZExtValue(), 0, + UI.getOperandNo() == 1, Info); + else + MarkUnsafe(Info); + } else if (LoadInst *LI = dyn_cast(User)) { + if (!LI->isVolatile()) { + const Type *LIType = LI->getType(); + isSafeMemAccess(AI, Offset, ArrayOffset, TD->getTypeAllocSize(LIType), + LIType, false, Info); + } else + MarkUnsafe(Info); + } else if (StoreInst *SI = dyn_cast(User)) { + // Store is ok if storing INTO the pointer, not storing the pointer + if (!SI->isVolatile() && SI->getOperand(0) != I) { + const Type *SIType = SI->getOperand(0)->getType(); + isSafeMemAccess(AI, Offset, ArrayOffset, TD->getTypeAllocSize(SIType), + SIType, true, Info); + } else + MarkUnsafe(Info); + } else if (isa(UI)) { + // If one user is DbgInfoIntrinsic then check if all users are + // DbgInfoIntrinsics. + if (OnlyUsedByDbgInfoIntrinsics(I)) { + Info.needsCleanup = true; + return; + } + MarkUnsafe(Info); + } else { + DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); + MarkUnsafe(Info); + } + if (Info.isUnsafe) return; } +} - ++I; - if (I == E) return MarkUnsafe(Info); // ran out of GEP indices?? +/// isSafeGEP - Check if a GEP instruction can be handled for scalar +/// replacement. It is safe when all the indices are constant, in-bounds +/// references, and when the resulting offset corresponds to an element within +/// the alloca type. The results are flagged in the Info parameter. Upon +/// return, Offset is adjusted as specified by the GEP indices. For the +/// special case of a variable index to a 2-element array, ArrayOffset is set +/// to the array element size. +void SROA::isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI, + uint64_t &Offset, uint64_t &ArrayOffset, + AllocaInfo &Info) { + gep_type_iterator GEPIt = gep_type_begin(GEPI), E = gep_type_end(GEPI); + if (GEPIt == E) + return; + + // The first GEP index must be zero. + if (!isa(GEPIt.getOperand()) || + !cast(GEPIt.getOperand())->isZero()) + return MarkUnsafe(Info); + if (++GEPIt == E) + return; - bool IsAllZeroIndices = true; - // If the first index is a non-constant index into an array, see if we can // handle it as a special case. - if (const ArrayType *AT = dyn_cast(*I)) { - if (!isa(I.getOperand())) { - IsAllZeroIndices = 0; - uint64_t NumElements = AT->getNumElements(); - - // If this is an array index and the index is not constant, we cannot - // promote... that is unless the array has exactly one or two elements in - // it, in which case we CAN promote it, but we have to canonicalize this - // out if this is the only problem. - if ((NumElements == 1 || NumElements == 2) && - AllUsersAreLoads(GEPI)) { + const Type *ArrayEltTy = 0; + if (ArrayOffset == 0 && Offset == 0) { + if (const ArrayType *AT = dyn_cast(*GEPIt)) { + if (!isa(GEPIt.getOperand())) { + uint64_t NumElements = AT->getNumElements(); + + // If this is an array index and the index is not constant, we cannot + // promote... that is unless the array has exactly one or two elements + // in it, in which case we CAN promote it, but we have to canonicalize + // this out if this is the only problem. + if ((NumElements != 1 && NumElements != 2) || !AllUsersAreLoads(GEPI)) + return MarkUnsafe(Info); Info.needsCleanup = true; - return; // Canonicalization required! + ArrayOffset = TD->getTypeAllocSizeInBits(AT->getElementType()); + ArrayEltTy = AT->getElementType(); + ++GEPIt; } - return MarkUnsafe(Info); } } - + // Walk through the GEP type indices, checking the types that this indexes // into. - for (; I != E; ++I) { + for (; GEPIt != E; ++GEPIt) { // Ignore struct elements, no extra checking needed for these. - if (isa(*I)) + if (isa(*GEPIt)) continue; - - ConstantInt *IdxVal = dyn_cast(I.getOperand()); - if (!IdxVal) return MarkUnsafe(Info); - // Are all indices still zero? - IsAllZeroIndices &= IdxVal->isZero(); - - if (const ArrayType *AT = dyn_cast(*I)) { + ConstantInt *IdxVal = dyn_cast(GEPIt.getOperand()); + if (!IdxVal) + return MarkUnsafe(Info); + + if (const ArrayType *AT = dyn_cast(*GEPIt)) { // This GEP indexes an array. Verify that this is an in-range constant // integer. Specifically, consider A[0][i]. We cannot know that the user // isn't doing invalid things like allowing i to index an out-of-range @@ -612,144 +494,254 @@ // of any accesses into structs where any of the components are variables. if (IdxVal->getZExtValue() >= AT->getNumElements()) return MarkUnsafe(Info); - } else if (const VectorType *VT = dyn_cast(*I)) { + } else { + const VectorType *VT = dyn_cast(*GEPIt); + assert(VT && "unexpected type in GEP type iterator"); if (IdxVal->getZExtValue() >= VT->getNumElements()) return MarkUnsafe(Info); } } - - // If there are any non-simple uses of this getelementptr, make sure to reject - // them. - return isSafeElementUse(GEPI, IsAllZeroIndices, AI, Info); + + // All the indices are safe. Now compute the offset due to this GEP and + // check if the alloca has a component element at that offset. + if (ArrayOffset == 0) { + SmallVector Indices(GEPI->op_begin() + 1, GEPI->op_end()); + Offset += TD->getIndexedOffset(GEPI->getPointerOperandType(), + &Indices[0], Indices.size()); + } else { + // Both array elements have the same type, so it suffices to check one of + // them. Copy the GEP indices starting from the array index, but replace + // that variable index with a constant zero. + SmallVector Indices(GEPI->op_begin() + 2, GEPI->op_end()); + Indices[0] = Constant::getNullValue(Type::getInt32Ty(GEPI->getContext())); + const Type *ArrayEltPtr = PointerType::getUnqual(ArrayEltTy); + Offset += TD->getIndexedOffset(ArrayEltPtr, &Indices[0], Indices.size()); + } + if (!TypeHasComponent(AI->getAllocatedType(), Offset, 0)) + MarkUnsafe(Info); +} + +/// isSafeMemAccess - Check if a load/store/memcpy operates on the entire AI +/// alloca or has an offset and size that corresponds to a component element +/// within it. The offset checked here may have been formed from a GEP with a +/// pointer bitcasted to a different type. +void SROA::isSafeMemAccess(AllocaInst *AI, uint64_t Offset, + uint64_t ArrayOffset, uint64_t MemSize, + const Type *MemOpType, bool isStore, + AllocaInfo &Info) { + // Check if this is a load/store of the entire alloca. + if (Offset == 0 && ArrayOffset == 0 && + MemSize == TD->getTypeAllocSize(AI->getAllocatedType())) { + bool UsesAggregateType = (MemOpType == AI->getAllocatedType()); + // This is safe for MemIntrinsics (where MemOpType is 0), integer types + // (which are essentially the same as the MemIntrinsics, especially with + // regard to copying padding between elements), or references using the + // aggregate type of the alloca. + if (!MemOpType || isa(MemOpType) || UsesAggregateType) { + if (!UsesAggregateType) { + if (isStore) + Info.isMemCpyDst = true; + else + Info.isMemCpySrc = true; + } + return; + } + } + // Check if the offset/size correspond to a component within the alloca type. + const Type *T = AI->getAllocatedType(); + if (TypeHasComponent(T, Offset, MemSize) && + (ArrayOffset == 0 || TypeHasComponent(T, Offset + ArrayOffset, MemSize))) + return; + + return MarkUnsafe(Info); } -/// isSafeMemIntrinsicOnAllocation - Check if the specified memory -/// intrinsic can be promoted by SROA. At this point, we know that the operand -/// of the memintrinsic is a pointer to the beginning of the allocation. -void SROA::isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocaInst *AI, - unsigned OpNo, AllocaInfo &Info) { - // If not constant length, give up. - ConstantInt *Length = dyn_cast(MI->getLength()); - if (!Length) return MarkUnsafe(Info); - - // If not the whole aggregate, give up. - if (Length->getZExtValue() != - TD->getTypeAllocSize(AI->getType()->getElementType())) - return MarkUnsafe(Info); - - // We only know about memcpy/memset/memmove. - if (!isa(MI)) - return MarkUnsafe(Info); - - // Otherwise, we can transform it. Determine whether this is a memcpy/set - // into or out of the aggregate. - if (OpNo == 1) - Info.isMemCpyDst = true; - else { - assert(OpNo == 2); - Info.isMemCpySrc = true; +/// TypeHasComponent - Return true if T has a component type with the +/// specified offset and size. If Size is zero, do not check the size. +bool SROA::TypeHasComponent(const Type *T, uint64_t Offset, uint64_t Size) { + const Type *EltTy; + uint64_t EltSize; + if (const StructType *ST = dyn_cast(T)) { + const StructLayout *Layout = TD->getStructLayout(ST); + unsigned EltIdx = Layout->getElementContainingOffset(Offset); + EltTy = ST->getContainedType(EltIdx); + EltSize = TD->getTypeAllocSize(EltTy); + Offset -= Layout->getElementOffset(EltIdx); + } else if (const ArrayType *AT = dyn_cast(T)) { + EltTy = AT->getElementType(); + EltSize = TD->getTypeAllocSize(EltTy); + Offset %= EltSize; + } else { + return false; } + if (Offset == 0 && (Size == 0 || EltSize == Size)) + return true; + // Check if the component spans multiple elements. + if (Offset + Size > EltSize) + return false; + return TypeHasComponent(EltTy, Offset, Size); } -/// isSafeUseOfBitCastedAllocation - Check if all users of this bitcast -/// from an alloca are safe for SROA of that alloca. -void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocaInst *AI, - AllocaInfo &Info) { - for (Value::use_iterator UI = BC->use_begin(), E = BC->use_end(); - UI != E; ++UI) { - if (BitCastInst *BCU = dyn_cast(UI)) { - isSafeUseOfBitCastedAllocation(BCU, AI, Info); - } else if (MemIntrinsic *MI = dyn_cast(UI)) { - isSafeMemIntrinsicOnAllocation(MI, AI, UI.getOperandNo(), Info); - } else if (StoreInst *SI = dyn_cast(UI)) { - if (SI->isVolatile()) - return MarkUnsafe(Info); - - // If storing the entire alloca in one chunk through a bitcasted pointer - // to integer, we can transform it. This happens (for example) when you - // cast a {i32,i32}* to i64* and store through it. This is similar to the - // memcpy case and occurs in various "byval" cases and emulated memcpys. - if (isa(SI->getOperand(0)->getType()) && - TD->getTypeAllocSize(SI->getOperand(0)->getType()) == - TD->getTypeAllocSize(AI->getType()->getElementType())) { - Info.isMemCpyDst = true; - continue; - } - return MarkUnsafe(Info); - } else if (LoadInst *LI = dyn_cast(UI)) { - if (LI->isVolatile()) - return MarkUnsafe(Info); +/// RewriteForScalarRepl - Alloca AI is being split into NewElts, so rewrite +/// the instruction I, which references it, to use the separate elements. +/// Offset indicates the position within AI that is referenced by this +/// instruction. +void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, + SmallVector &NewElts) { + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ) { + Instruction *User = cast(*UI++); - // If loading the entire alloca in one chunk through a bitcasted pointer - // to integer, we can transform it. This happens (for example) when you - // cast a {i32,i32}* to i64* and load through it. This is similar to the - // memcpy case and occurs in various "byval" cases and emulated memcpys. - if (isa(LI->getType()) && - TD->getTypeAllocSize(LI->getType()) == - TD->getTypeAllocSize(AI->getType()->getElementType())) { - Info.isMemCpySrc = true; - continue; + if (BitCastInst *BC = dyn_cast(User)) { + if (BC->getOperand(0) == AI) + BC->setOperand(0, NewElts[0]); + // If the bitcast type now matches the operand type, it will be removed + // after processing its uses. + RewriteForScalarRepl(BC, AI, Offset, NewElts); + } else if (GetElementPtrInst *GEPI = dyn_cast(User)) { + RewriteGEP(GEPI, AI, Offset, NewElts); + } else if (MemIntrinsic *MI = dyn_cast(User)) { + ConstantInt *Length = dyn_cast(MI->getLength()); + uint64_t MemSize = Length->getZExtValue(); + if (Offset == 0 && + MemSize == TD->getTypeAllocSize(AI->getAllocatedType())) + RewriteMemIntrinUserOfAlloca(MI, I, AI, NewElts); + } else if (LoadInst *LI = dyn_cast(User)) { + const Type *LIType = LI->getType(); + if (LIType == AI->getAllocatedType()) { + // Replace: + // %res = load { i32, i32 }* %alloc + // with: + // %load.0 = load i32* %alloc.0 + // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0 + // %load.1 = load i32* %alloc.1 + // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1 + // (Also works for arrays instead of structs) + Value *Insert = UndefValue::get(LIType); + for (unsigned i = 0, e = NewElts.size(); i != e; ++i) { + Value *Load = new LoadInst(NewElts[i], "load", LI); + Insert = InsertValueInst::Create(Insert, Load, i, "insert", LI); + } + LI->replaceAllUsesWith(Insert); + LI->eraseFromParent(); + } else if (isa(LIType) && + TD->getTypeAllocSize(LIType) == + TD->getTypeAllocSize(AI->getAllocatedType())) { + // If this is a load of the entire alloca to an integer, rewrite it. + RewriteLoadUserOfWholeAlloca(LI, AI, NewElts); } - return MarkUnsafe(Info); - } else if (isa(UI)) { - // If one user is DbgInfoIntrinsic then check if all users are - // DbgInfoIntrinsics. - if (OnlyUsedByDbgInfoIntrinsics(BC)) { - Info.needsCleanup = true; - return; + } else if (StoreInst *SI = dyn_cast(User)) { + Value *Val = SI->getOperand(0); + const Type *SIType = Val->getType(); + if (SIType == AI->getAllocatedType()) { + // Replace: + // store { i32, i32 } %val, { i32, i32 }* %alloc + // with: + // %val.0 = extractvalue { i32, i32 } %val, 0 + // store i32 %val.0, i32* %alloc.0 + // %val.1 = extractvalue { i32, i32 } %val, 1 + // store i32 %val.1, i32* %alloc.1 + // (Also works for arrays instead of structs) + for (unsigned i = 0, e = NewElts.size(); i != e; ++i) { + Value *Extract = ExtractValueInst::Create(Val, i, Val->getName(), SI); + new StoreInst(Extract, NewElts[i], SI); + } + SI->eraseFromParent(); + } else if (isa(SIType) && + TD->getTypeAllocSize(SIType) == + TD->getTypeAllocSize(AI->getAllocatedType())) { + // If this is a store of the entire alloca from an integer, rewrite it. + RewriteStoreUserOfWholeAlloca(SI, AI, NewElts); } - else - MarkUnsafe(Info); } - else { - return MarkUnsafe(Info); + } + // Delete unused instructions and identity bitcasts. + if (I->use_empty()) + I->eraseFromParent(); + else if (BitCastInst *BC = dyn_cast(I)) { + if (BC->getDestTy() == BC->getSrcTy()) { + BC->replaceAllUsesWith(BC->getOperand(0)); + BC->eraseFromParent(); } - if (Info.isUnsafe) return; } } -/// RewriteBitCastUserOfAlloca - BCInst (transitively) bitcasts AI, or indexes -/// to its first element. Transform users of the cast to use the new values -/// instead. -void SROA::RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocaInst *AI, - SmallVector &NewElts) { - Value::use_iterator UI = BCInst->use_begin(), UE = BCInst->use_end(); - while (UI != UE) { - Instruction *User = cast(*UI++); - if (BitCastInst *BCU = dyn_cast(User)) { - RewriteBitCastUserOfAlloca(BCU, AI, NewElts); - if (BCU->use_empty()) BCU->eraseFromParent(); - continue; - } - - if (MemIntrinsic *MI = dyn_cast(User)) { - // This must be memcpy/memmove/memset of the entire aggregate. - // Split into one per element. - RewriteMemIntrinUserOfAlloca(MI, BCInst, AI, NewElts); - continue; - } - - if (StoreInst *SI = dyn_cast(User)) { - // If this is a store of the entire alloca from an integer, rewrite it. - RewriteStoreUserOfWholeAlloca(SI, AI, NewElts); - continue; +/// FindElementAndOffset - Return the index of the element containing Offset +/// within the specified type, which must be either a struct or an array. +/// Sets T to the type of the element and Offset to the offset within that +/// element. +unsigned SROA::FindElementAndOffset(const Type *&T, uint64_t &Offset) { + unsigned Idx = 0; + if (const StructType *ST = dyn_cast(T)) { + const StructLayout *Layout = TD->getStructLayout(ST); + Idx = Layout->getElementContainingOffset(Offset); + T = ST->getContainedType(Idx); + Offset -= Layout->getElementOffset(Idx); + } else { + const ArrayType *AT = dyn_cast(T); + assert(AT && "unexpected type for scalar replacement"); + T = AT->getElementType(); + uint64_t EltSize = TD->getTypeAllocSize(T); + Idx = (unsigned)(Offset / EltSize); + Offset -= Idx * EltSize; + } + return Idx; +} + +/// RewriteGEP - Check if this GEP instruction moves the pointer across +/// elements of the alloca that are being split apart, and if so, rewrite +/// the GEP to be relative to the new element. +void SROA::RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset, + SmallVector &NewElts) { + Instruction *Val = GEPI; + + uint64_t OldOffset = Offset; + SmallVector Indices(GEPI->op_begin() + 1, GEPI->op_end()); + Offset += TD->getIndexedOffset(GEPI->getPointerOperandType(), + &Indices[0], Indices.size()); + + const Type *T = AI->getAllocatedType(); + unsigned OldIdx = FindElementAndOffset(T, OldOffset); + if (GEPI->getOperand(0) == AI) + OldIdx = ~0U; // Force the GEP to be rewritten. + + T = AI->getAllocatedType(); + uint64_t EltOffset = Offset; + unsigned Idx = FindElementAndOffset(T, EltOffset); + + // If this GEP moves the pointer across elements of the alloca that are + // being split, then it needs to be rewritten. + if (Idx != OldIdx) { + const Type *i32Ty = Type::getInt32Ty(AI->getContext()); + SmallVector NewArgs; + NewArgs.push_back(Constant::getNullValue(i32Ty)); + while (EltOffset != 0) { + unsigned EltIdx = FindElementAndOffset(T, EltOffset); + NewArgs.push_back(ConstantInt::get(i32Ty, EltIdx)); + } + if (NewArgs.size() > 1) { + Val = GetElementPtrInst::CreateInBounds(NewElts[Idx], NewArgs.begin(), + NewArgs.end(), "", GEPI); + Val->takeName(GEPI); + if (Val->getType() != GEPI->getType()) + Val = new BitCastInst(Val, GEPI->getType(), Val->getNameStr(), GEPI); + } else { + Val = NewElts[Idx]; + // Insert a new bitcast. If the types match, it will be removed after + // handling all of its uses. + Val = new BitCastInst(Val, GEPI->getType(), Val->getNameStr(), GEPI); + Val->takeName(GEPI); } - if (LoadInst *LI = dyn_cast(User)) { - // If this is a load of the entire alloca to an integer, rewrite it. - RewriteLoadUserOfWholeAlloca(LI, AI, NewElts); - continue; - } - - // Otherwise it must be some other user of a gep of the first pointer. Just - // leave these alone. - continue; + GEPI->replaceAllUsesWith(Val); + GEPI->eraseFromParent(); } + + RewriteForScalarRepl(Val, AI, Offset, NewElts); } /// RewriteMemIntrinUserOfAlloca - MI is a memcpy/memset/memmove from or to AI. /// Rewrite it to copy or set the elements of the scalarized memory. -void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, +void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, AllocaInst *AI, SmallVector &NewElts) { @@ -761,10 +753,10 @@ LLVMContext &Context = MI->getContext(); unsigned MemAlignment = MI->getAlignment(); if (MemTransferInst *MTI = dyn_cast(MI)) { // memmove/memcopy - if (BCInst == MTI->getRawDest()) + if (Inst == MTI->getRawDest()) OtherPtr = MTI->getRawSource(); else { - assert(BCInst == MTI->getRawSource()); + assert(Inst == MTI->getRawSource()); OtherPtr = MTI->getRawDest(); } } @@ -798,7 +790,7 @@ // Process each element of the aggregate. Value *TheFn = MI->getOperand(0); const Type *BytePtrTy = MI->getRawDest()->getType(); - bool SROADest = MI->getRawDest() == BCInst; + bool SROADest = MI->getRawDest() == Inst; Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext())); @@ -810,9 +802,9 @@ if (OtherPtr) { Value *Idx[2] = { Zero, ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) }; - OtherElt = GetElementPtrInst::Create(OtherPtr, Idx, Idx + 2, + OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx, Idx + 2, OtherPtr->getNameStr()+"."+Twine(i), - MI); + MI); uint64_t EltOffset; const PointerType *OtherPtrTy = cast(OtherPtr->getType()); if (const StructType *ST = @@ -937,15 +929,9 @@ // Extract each element out of the integer according to its structure offset // and store the element value to the individual alloca. Value *SrcVal = SI->getOperand(0); - const Type *AllocaEltTy = AI->getType()->getElementType(); + const Type *AllocaEltTy = AI->getAllocatedType(); uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); - // If this isn't a store of an integer to the whole alloca, it may be a store - // to the first element. Just ignore the store in this case and normal SROA - // will handle it. - if (!isa(SrcVal->getType()) || - TD->getTypeAllocSizeInBits(SrcVal->getType()) != AllocaSizeBits) - return; // Handle tail padding by extending the operand if (TD->getTypeSizeInBits(SrcVal->getType()) != AllocaSizeBits) SrcVal = new ZExtInst(SrcVal, @@ -1059,16 +1045,9 @@ SmallVector &NewElts) { // Extract each element out of the NewElts according to its structure offset // and form the result value. - const Type *AllocaEltTy = AI->getType()->getElementType(); + const Type *AllocaEltTy = AI->getAllocatedType(); uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); - // If this isn't a load of the whole alloca to an integer, it may be a load - // of the first element. Just ignore the load in this case and normal SROA - // will handle it. - if (!isa(LI->getType()) || - TD->getTypeAllocSizeInBits(LI->getType()) != AllocaSizeBits) - return; - DEBUG(errs() << "PROMOTING LOAD OF WHOLE ALLOCA: " << *AI << '\n' << *LI << '\n'); @@ -1142,7 +1121,6 @@ LI->eraseFromParent(); } - /// HasPadding - Return true if the specified type has any structure or /// alignment padding, false otherwise. static bool HasPadding(const Type *Ty, const TargetData &TD) { @@ -1192,14 +1170,10 @@ // the users are safe to transform. AllocaInfo Info; - for (Value::use_iterator I = AI->use_begin(), E = AI->use_end(); - I != E; ++I) { - isSafeUseOfAllocation(cast(*I), AI, Info); - if (Info.isUnsafe) { - DEBUG(errs() << "Cannot transform: " << *AI << "\n due to user: " - << **I << '\n'); - return 0; - } + isSafeForScalarRepl(AI, AI, 0, 0, Info); + if (Info.isUnsafe) { + DEBUG(errs() << "Cannot transform: " << *AI << '\n'); + return 0; } // Okay, we know all the users are promotable. If the aggregate is a memcpy @@ -1208,7 +1182,7 @@ // types, but may actually be used. In these cases, we refuse to promote the // struct. if (Info.isMemCpySrc && Info.isMemCpyDst && - HasPadding(AI->getType()->getElementType(), *TD)) + HasPadding(AI->getAllocatedType(), *TD)) return 0; // If we require cleanup, return 1, otherwise return 3. @@ -1245,15 +1219,15 @@ // Insert the new GEP instructions, which are properly indexed. SmallVector Indices(GEPI->op_begin()+1, GEPI->op_end()); Indices[1] = Constant::getNullValue(Type::getInt32Ty(GEPI->getContext())); - Value *ZeroIdx = GetElementPtrInst::Create(GEPI->getOperand(0), - Indices.begin(), - Indices.end(), - GEPI->getName()+".0", GEPI); + Value *ZeroIdx = GetElementPtrInst::CreateInBounds(GEPI->getOperand(0), + Indices.begin(), + Indices.end(), + GEPI->getName()+".0",GEPI); Indices[1] = ConstantInt::get(Type::getInt32Ty(GEPI->getContext()), 1); - Value *OneIdx = GetElementPtrInst::Create(GEPI->getOperand(0), - Indices.begin(), - Indices.end(), - GEPI->getName()+".1", GEPI); + Value *OneIdx = GetElementPtrInst::CreateInBounds(GEPI->getOperand(0), + Indices.begin(), + Indices.end(), + GEPI->getName()+".1", GEPI); // Replace all loads of the variable index GEP with loads from both // indexes and a select. while (!GEPI->use_empty()) { @@ -1264,22 +1238,24 @@ LI->replaceAllUsesWith(R); LI->eraseFromParent(); } - GEPI->eraseFromParent(); } - /// CleanupAllocaUsers - If SROA reported that it can promote the specified /// allocation, but only if cleaned up, perform the cleanups required. -void SROA::CleanupAllocaUsers(AllocaInst *AI) { +void SROA::CleanupAllocaUsers(Value *V) { // At this point, we know that the end result will be SROA'd and promoted, so // we can insert ugly code if required so long as sroa+mem2reg will clean it // up. - for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); + for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ) { User *U = *UI++; - if (GetElementPtrInst *GEPI = dyn_cast(U)) + if (isa(U)) { + CleanupAllocaUsers(U); + } else if (GetElementPtrInst *GEPI = dyn_cast(U)) { CleanupGEP(GEPI); - else { + CleanupAllocaUsers(GEPI); + if (GEPI->use_empty()) GEPI->eraseFromParent(); + } else { Instruction *I = cast(U); SmallVector DbgInUses; if (!isa(I) && OnlyUsedByDbgInfoIntrinsics(I, &DbgInUses)) { @@ -1395,7 +1371,7 @@ // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); - uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getPointerOperandType(), &Indices[0], Indices.size()); // See if all uses can be converted. if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, SawVec,Offset+GEPOffset, @@ -1457,7 +1433,7 @@ if (GetElementPtrInst *GEP = dyn_cast(User)) { // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); - uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getPointerOperandType(), &Indices[0], Indices.size()); ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8); GEP->eraseFromParent(); Added: llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll?rev=91184&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll (added) +++ llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Fri Dec 11 17:47:40 2009 @@ -0,0 +1,68 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +; Radar 7441282 + +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10" + +%struct.__neon_int16x8x2_t = type { <8 x i16>, <8 x i16> } +%struct.int16x8_t = type { <8 x i16> } +%struct.int16x8x2_t = type { [2 x %struct.int16x8_t] } +%union..0anon = type { %struct.int16x8x2_t } + +define arm_apcscc void @test(<8 x i16> %tmp.0, %struct.int16x8x2_t* %dst) nounwind { +; CHECK: @test +; CHECK-NOT: alloca +; CHECK: "alloca point" +entry: + %tmp_addr = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=3] + %dst_addr = alloca %struct.int16x8x2_t* ; <%struct.int16x8x2_t**> [#uses=2] + %__rv = alloca %union..0anon ; <%union..0anon*> [#uses=2] + %__bx = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] + %__ax = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] + %tmp2 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] + %0 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %1 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %tmp.0, <8 x i16>* %1 + store %struct.int16x8x2_t* %dst, %struct.int16x8x2_t** %dst_addr + %2 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %3 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %4 = load <8 x i16>* %3, align 16 ; <<8 x i16>> [#uses=1] + store <8 x i16> %4, <8 x i16>* %2, align 16 + %5 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %6 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %7 = load <8 x i16>* %6, align 16 ; <<8 x i16>> [#uses=1] + store <8 x i16> %7, <8 x i16>* %5, align 16 + %8 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %9 = load <8 x i16>* %8, align 16 ; <<8 x i16>> [#uses=2] + %10 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %11 = load <8 x i16>* %10, align 16 ; <<8 x i16>> [#uses=2] + %12 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] + %13 = bitcast %struct.int16x8x2_t* %12 to %struct.__neon_int16x8x2_t* ; <%struct.__neon_int16x8x2_t*> [#uses=2] + %14 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> ; <<8 x i16>> [#uses=1] + %15 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %14, <8 x i16>* %15 + %16 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> ; <<8 x i16>> [#uses=1] + %17 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 1 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %16, <8 x i16>* %17 + %18 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] + %19 = bitcast %struct.int16x8x2_t* %0 to i8* ; [#uses=1] + %20 = bitcast %struct.int16x8x2_t* %18 to i8* ; [#uses=1] + call void @llvm.memcpy.i32(i8* %19, i8* %20, i32 32, i32 16) + %tmp21 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; [#uses=1] + %21 = bitcast %struct.int16x8x2_t* %0 to i8* ; [#uses=1] + call void @llvm.memcpy.i32(i8* %tmp21, i8* %21, i32 32, i32 16) + %22 = load %struct.int16x8x2_t** %dst_addr, align 4 ; <%struct.int16x8x2_t*> [#uses=1] + %23 = bitcast %struct.int16x8x2_t* %22 to i8* ; [#uses=1] + %tmp22 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; [#uses=1] + call void @llvm.memcpy.i32(i8* %23, i8* %tmp22, i32 32, i32 16) + br label %return + +; CHECK: store <8 x i16> +; CHECK: store <8 x i16> + +return: ; preds = %entry + ret void +} + +declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind From bob.wilson at apple.com Fri Dec 11 18:14:33 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 11 Dec 2009 16:14:33 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h In-Reply-To: <38a0d8450912111402h44a1cf3fxa3a70f13ebfd8952@mail.gmail.com> References: <200911112305.nABN5jd1010544@zion.cs.uiuc.edu> <07D47602-9061-4995-863C-0927C7AE65FC@apple.com> <38a0d8450912101708s11a088dw80c78a8b094e4566@mail.gmail.com> <644DACFE-E75F-488F-8833-A631C330897C@apple.com> <38a0d8450912110950v6ca9d653o1830d510c846ffe8@mail.gmail.com> <6C6E848D-55F3-4D50-9EB5-2D556380BEE5@apple.com> <38a0d8450912111033u68bd10c5sea4037d7a9c5c23@mail.gmail.com> <2A9F119C-31B4-4056-8DF8-BC6F2F382604@apple.com> <38a0d8450912111228u3edb21c1qa1952f66f4c19f5f@mail.gmail.com> <38a0d8450912111402h44a1cf3fxa3a70f13ebfd8952@mail.gmail.com> Message-ID: On Dec 11, 2009, at 2:02 PM, Rafael Espindola wrote: >> I don't know. >> >> Honestly, I think those choices may be the least of your worries. If llvm-gcc is going to figure out exactly how each argument will be passed, there are a lot of details to get right. If you can come up with something that works with APCS, AAPCS, and AAPCS-hardfloat, preferably both big- and little-endian (watch out for structure padding differences with those), and passes the GCC ABI compatibility testsuite, I don't much care how you do it. >> >> If I don't get pulled into other work, I'll probably go ahead with the "byval" implementation. That would at least give you a baseline to compare against. > > Just to be explicit, the above case with a char[5] should expand to > > %struct.foo_part = type { i8 } > declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval) > > I am happy to do as much testing as needed, but I will try to fix just > pr5406 first. > > Can you provide some details on how do I run the "GCC ABI > compatibility testsuite" for APCS, AAPCS, and AAPCS-hardfloat? I will > make sure I don't introduce a regression on it. See llvm-gcc-4.2/gcc/testsuite/README.compat. From grosbach at apple.com Fri Dec 11 19:40:06 2009 From: grosbach at apple.com (Jim Grosbach) Date: Sat, 12 Dec 2009 01:40:06 -0000 Subject: [llvm-commits] [llvm] r91200 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h ARMInstrInfo.td Message-ID: <200912120140.nBC1e6oX006751@zion.cs.uiuc.edu> Author: grosbach Date: Fri Dec 11 19:40:06 2009 New Revision: 91200 URL: http://llvm.org/viewvc/llvm-project?rev=91200&view=rev Log: Framework for atomic binary operations. The emitter for the pseudo instructions just issues an error for the moment. The front end won't yet generate these intrinsics for ARM, so this is behind the scenes until complete. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=91200&r1=91199&r2=91200&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Dec 11 19:40:06 2009 @@ -42,6 +42,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" #include using namespace llvm; @@ -3043,8 +3044,9 @@ //===----------------------------------------------------------------------===// MachineBasicBlock * -ARMTargetLowering::EmitAtomicCmpSwap(unsigned Size, MachineInstr *MI, - MachineBasicBlock *BB) const { +ARMTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Size) const { unsigned dest = MI->getOperand(0).getReg(); unsigned ptr = MI->getOperand(1).getReg(); unsigned oldval = MI->getOperand(2).getReg(); @@ -3114,6 +3116,16 @@ } MachineBasicBlock * +ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, + unsigned Size, unsigned BinOpcode) const { + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Cannot yet emit: "; + MI->print(Msg); + llvm_report_error(Msg.str()); +} + +MachineBasicBlock * ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB, DenseMap *EM) const { @@ -3124,12 +3136,37 @@ MI->dump(); llvm_unreachable("Unexpected instr type to insert"); - - - - case ARM::ATOMIC_CMP_SWAP_I8: return EmitAtomicCmpSwap(1, MI, BB); - case ARM::ATOMIC_CMP_SWAP_I16: return EmitAtomicCmpSwap(2, MI, BB); - case ARM::ATOMIC_CMP_SWAP_I32: return EmitAtomicCmpSwap(4, MI, BB); + case ARM::ATOMIC_LOAD_ADD_I8: return EmitAtomicBinary(MI, BB, 1, ARM::ADDrr); + case ARM::ATOMIC_LOAD_ADD_I16: return EmitAtomicBinary(MI, BB, 2, ARM::ADDrr); + case ARM::ATOMIC_LOAD_ADD_I32: return EmitAtomicBinary(MI, BB, 4, ARM::ADDrr); + + case ARM::ATOMIC_LOAD_AND_I8: return EmitAtomicBinary(MI, BB, 1, ARM::ANDrr); + case ARM::ATOMIC_LOAD_AND_I16: return EmitAtomicBinary(MI, BB, 2, ARM::ANDrr); + case ARM::ATOMIC_LOAD_AND_I32: return EmitAtomicBinary(MI, BB, 4, ARM::ANDrr); + + case ARM::ATOMIC_LOAD_OR_I8: return EmitAtomicBinary(MI, BB, 1, ARM::ORRrr); + case ARM::ATOMIC_LOAD_OR_I16: return EmitAtomicBinary(MI, BB, 2, ARM::ORRrr); + case ARM::ATOMIC_LOAD_OR_I32: return EmitAtomicBinary(MI, BB, 4, ARM::ORRrr); + + case ARM::ATOMIC_LOAD_XOR_I8: return EmitAtomicBinary(MI, BB, 1, ARM::EORrr); + case ARM::ATOMIC_LOAD_XOR_I16: return EmitAtomicBinary(MI, BB, 2, ARM::EORrr); + case ARM::ATOMIC_LOAD_XOR_I32: return EmitAtomicBinary(MI, BB, 4, ARM::EORrr); + + case ARM::ATOMIC_LOAD_NAND_I8: return EmitAtomicBinary(MI, BB, 1, ARM::BICrr); + case ARM::ATOMIC_LOAD_NAND_I16:return EmitAtomicBinary(MI, BB, 2, ARM::BICrr); + case ARM::ATOMIC_LOAD_NAND_I32:return EmitAtomicBinary(MI, BB, 4, ARM::BICrr); + + case ARM::ATOMIC_LOAD_SUB_I8: return EmitAtomicBinary(MI, BB, 1, ARM::SUBrr); + case ARM::ATOMIC_LOAD_SUB_I16: return EmitAtomicBinary(MI, BB, 2, ARM::SUBrr); + case ARM::ATOMIC_LOAD_SUB_I32: return EmitAtomicBinary(MI, BB, 4, ARM::SUBrr); + + case ARM::ATOMIC_SWAP_I8: return EmitAtomicBinary(MI, BB, 1, 0); + case ARM::ATOMIC_SWAP_I16: return EmitAtomicBinary(MI, BB, 2, 0); + case ARM::ATOMIC_SWAP_I32: return EmitAtomicBinary(MI, BB, 4, 0); + + case ARM::ATOMIC_CMP_SWAP_I8: return EmitAtomicCmpSwap(MI, BB, 1); + case ARM::ATOMIC_CMP_SWAP_I16: return EmitAtomicCmpSwap(MI, BB, 2); + case ARM::ATOMIC_CMP_SWAP_I32: return EmitAtomicCmpSwap(MI, BB, 4); case ARM::tMOVCCr_pseudo: { // To "insert" a SELECT_CC instruction, we actually have to insert the Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=91200&r1=91199&r2=91200&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Dec 11 19:40:06 2009 @@ -332,8 +332,13 @@ SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMCC, SelectionDAG &DAG, DebugLoc dl); - MachineBasicBlock *EmitAtomicCmpSwap(unsigned Size, MachineInstr *MI, - MachineBasicBlock *BB) const; + MachineBasicBlock *EmitAtomicCmpSwap(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Size) const; + MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Size, + unsigned BinOpcode) const; }; } Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=91200&r1=91199&r2=91200&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Dec 11 19:40:06 2009 @@ -1597,18 +1597,107 @@ } let usesCustomInserter = 1 in { - def ATOMIC_CMP_SWAP_I8 : PseudoInst< - (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, - "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", - [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; - def ATOMIC_CMP_SWAP_I16 : PseudoInst< - (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, - "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!", - [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; - def ATOMIC_CMP_SWAP_I32 : PseudoInst< - (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, - "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!", - [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; + let Uses = [CPSR] in { + def ATOMIC_LOAD_ADD_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_SUB_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_AND_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_OR_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_XOR_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_NAND_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!", + [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_ADD_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_SUB_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_AND_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_OR_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_XOR_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_NAND_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!", + [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_ADD_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_SUB_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_AND_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_OR_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_XOR_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; + def ATOMIC_LOAD_NAND_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, + "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!", + [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; + + def ATOMIC_SWAP_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, + "${:comment} ATOMIC_SWAP_I8 PSEUDO!", + [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; + def ATOMIC_SWAP_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, + "${:comment} ATOMIC_SWAP_I16 PSEUDO!", + [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; + def ATOMIC_SWAP_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, + "${:comment} ATOMIC_SWAP_I32 PSEUDO!", + [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; + + + def ATOMIC_CMP_SWAP_I8 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; + def ATOMIC_CMP_SWAP_I16 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; + def ATOMIC_CMP_SWAP_I32 : PseudoInst< + (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, + "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!", + [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; +} } let mayLoad = 1 in { From jyasskin at google.com Fri Dec 11 22:08:33 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Sat, 12 Dec 2009 04:08:33 -0000 Subject: [llvm-commits] [llvm] r91206 - in /llvm/trunk/include/llvm/Support: Debug.h ErrorHandling.h Message-ID: <200912120408.nBC48XB5011932@zion.cs.uiuc.edu> Author: jyasskin Date: Fri Dec 11 22:08:32 2009 New Revision: 91206 URL: http://llvm.org/viewvc/llvm-project?rev=91206&view=rev Log: Make it easier to use the llvm_unreachable and DEBUG macros without "using namespace llvm" by qualifying their implementations with ::llvm::. Modified: llvm/trunk/include/llvm/Support/Debug.h llvm/trunk/include/llvm/Support/ErrorHandling.h Modified: llvm/trunk/include/llvm/Support/Debug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Debug.h?rev=91206&r1=91205&r2=91206&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Debug.h (original) +++ llvm/trunk/include/llvm/Support/Debug.h Fri Dec 11 22:08:32 2009 @@ -63,7 +63,8 @@ /// This will emit the debug information if -debug is present, and -debug-only /// is not specified, or is specified as "bitset". #define DEBUG_WITH_TYPE(TYPE, X) \ - do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0) + do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \ + } while (0) #else #define isCurrentDebugType(X) (false) Modified: llvm/trunk/include/llvm/Support/ErrorHandling.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorHandling.h?rev=91206&r1=91205&r2=91206&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ErrorHandling.h (original) +++ llvm/trunk/include/llvm/Support/ErrorHandling.h Fri Dec 11 22:08:32 2009 @@ -79,9 +79,10 @@ /// Use this instead of assert(0), so that the compiler knows this path /// is not reachable even for NDEBUG builds. #ifndef NDEBUG -#define llvm_unreachable(msg) llvm_unreachable_internal(msg, __FILE__, __LINE__) +#define llvm_unreachable(msg) \ + ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) #else -#define llvm_unreachable(msg) llvm_unreachable_internal() +#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() #endif #endif From jyasskin at google.com Fri Dec 11 23:58:14 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Sat, 12 Dec 2009 05:58:14 -0000 Subject: [llvm-commits] [llvm] r91208 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200912120558.nBC5wETX015232@zion.cs.uiuc.edu> Author: jyasskin Date: Fri Dec 11 23:58:14 2009 New Revision: 91208 URL: http://llvm.org/viewvc/llvm-project?rev=91208&view=rev Log: Fix available_externally linkage for globals. It's probably still not supported by emitGlobals, but I don't have a test case for that. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91208&r1=91207&r2=91208&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Fri Dec 11 23:58:14 2009 @@ -681,7 +681,7 @@ if (Ptr) return Ptr; // If the global is external, just remember the address. - if (GV->isDeclaration()) { + if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { #if HAVE___DSO_HANDLE if (GV->getName() == "__dso_handle") return (void*)&__dso_handle; Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91208&r1=91207&r2=91208&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Fri Dec 11 23:58:14 2009 @@ -534,6 +534,31 @@ #endif } +} // anonymous namespace +// This variable is intentionally defined differently in the statically-compiled +// program from the IR input to the JIT to assert that the JIT doesn't use its +// definition. +extern "C" int32_t JITTest_AvailableExternallyGlobal; +int32_t JITTest_AvailableExternallyGlobal = 42; +namespace { + +TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { + TheJIT->DisableLazyCompilation(true); + LoadAssembly("@JITTest_AvailableExternallyGlobal = " + " available_externally global i32 7 " + " " + "define i32 @loader() { " + " %result = load i32* @JITTest_AvailableExternallyGlobal " + " ret i32 %result " + "} "); + Function *loaderIR = M->getFunction("loader"); + + int32_t (*loader)() = reinterpret_cast( + (intptr_t)TheJIT->getPointerToFunction(loaderIR)); + EXPECT_EQ(42, loader()) << "func should return 42 from the external global," + << " not 7 from the IR version."; +} + // This code is copied from JITEventListenerTest, but it only runs once for all // the tests in this directory. Everything seems fine, but that's strange // behavior. From jyasskin at google.com Sat Dec 12 00:18:46 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Sat, 12 Dec 2009 06:18:46 -0000 Subject: [llvm-commits] [llvm] r91209 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200912120618.nBC6Ikix015917@zion.cs.uiuc.edu> Author: jyasskin Date: Sat Dec 12 00:18:46 2009 New Revision: 91209 URL: http://llvm.org/viewvc/llvm-project?rev=91209&view=rev Log: Revert r91208. Something on Linux prevents the JIT from looking up a symbol defined in the test, and I don't have time tonight to figure it out. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91209&r1=91208&r2=91209&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat Dec 12 00:18:46 2009 @@ -681,7 +681,7 @@ if (Ptr) return Ptr; // If the global is external, just remember the address. - if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { + if (GV->isDeclaration()) { #if HAVE___DSO_HANDLE if (GV->getName() == "__dso_handle") return (void*)&__dso_handle; Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91209&r1=91208&r2=91209&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Sat Dec 12 00:18:46 2009 @@ -534,31 +534,6 @@ #endif } -} // anonymous namespace -// This variable is intentionally defined differently in the statically-compiled -// program from the IR input to the JIT to assert that the JIT doesn't use its -// definition. -extern "C" int32_t JITTest_AvailableExternallyGlobal; -int32_t JITTest_AvailableExternallyGlobal = 42; -namespace { - -TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { - TheJIT->DisableLazyCompilation(true); - LoadAssembly("@JITTest_AvailableExternallyGlobal = " - " available_externally global i32 7 " - " " - "define i32 @loader() { " - " %result = load i32* @JITTest_AvailableExternallyGlobal " - " ret i32 %result " - "} "); - Function *loaderIR = M->getFunction("loader"); - - int32_t (*loader)() = reinterpret_cast( - (intptr_t)TheJIT->getPointerToFunction(loaderIR)); - EXPECT_EQ(42, loader()) << "func should return 42 from the external global," - << " not 7 from the IR version."; -} - // This code is copied from JITEventListenerTest, but it only runs once for all // the tests in this directory. Everything seems fine, but that's strange // behavior. From nlewycky at google.com Sat Dec 12 01:20:03 2009 From: nlewycky at google.com (Nick Lewycky) Date: Fri, 11 Dec 2009 23:20:03 -0800 Subject: [llvm-commits] [llvm] r91209 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp In-Reply-To: <200912120618.nBC6Ikix015917@zion.cs.uiuc.edu> References: <200912120618.nBC6Ikix015917@zion.cs.uiuc.edu> Message-ID: It was just missing -rdynamic. Patch attached. Nick 2009/12/11 Jeffrey Yasskin > Author: jyasskin > Date: Sat Dec 12 00:18:46 2009 > New Revision: 91209 > > URL: http://llvm.org/viewvc/llvm-project?rev=91209&view=rev > Log: > Revert r91208. Something on Linux prevents the JIT from looking up a > symbol > defined in the test, and I don't have time tonight to figure it out. > > Modified: > llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91209&r1=91208&r2=91209&view=diff > > > ============================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat Dec 12 00:18:46 2009 > @@ -681,7 +681,7 @@ > if (Ptr) return Ptr; > > // If the global is external, just remember the address. > - if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { > + if (GV->isDeclaration()) { > #if HAVE___DSO_HANDLE > if (GV->getName() == "__dso_handle") > return (void*)&__dso_handle; > > Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91209&r1=91208&r2=91209&view=diff > > > ============================================================================== > --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) > +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Sat Dec 12 > 00:18:46 2009 > @@ -534,31 +534,6 @@ > #endif > } > > -} // anonymous namespace > -// This variable is intentionally defined differently in the > statically-compiled > -// program from the IR input to the JIT to assert that the JIT doesn't use > its > -// definition. > -extern "C" int32_t JITTest_AvailableExternallyGlobal; > -int32_t JITTest_AvailableExternallyGlobal = 42; > -namespace { > - > -TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { > - TheJIT->DisableLazyCompilation(true); > - LoadAssembly("@JITTest_AvailableExternallyGlobal = " > - " available_externally global i32 7 " > - " " > - "define i32 @loader() { " > - " %result = load i32* @JITTest_AvailableExternallyGlobal " > - " ret i32 %result " > - "} "); > - Function *loaderIR = M->getFunction("loader"); > - > - int32_t (*loader)() = reinterpret_cast( > - (intptr_t)TheJIT->getPointerToFunction(loaderIR)); > - EXPECT_EQ(42, loader()) << "func should return 42 from the external > global," > - << " not 7 from the IR version."; > -} > - > // This code is copied from JITEventListenerTest, but it only runs once > for all > // the tests in this directory. Everything seems fine, but that's strange > // behavior. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091211/02401464/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: rdynamic-jittests.patch Type: text/x-diff Size: 422 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091211/02401464/attachment.bin From benny.kra at googlemail.com Sat Dec 12 03:25:51 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 12 Dec 2009 09:25:51 -0000 Subject: [llvm-commits] [llvm] r91214 - in /llvm/trunk/test/Transforms: DeadStoreElimination/const-pointers.ll InstCombine/compare-signs.ll Message-ID: <200912120925.nBC9PpxN003480@zion.cs.uiuc.edu> Author: d0k Date: Sat Dec 12 03:25:50 2009 New Revision: 91214 URL: http://llvm.org/viewvc/llvm-project?rev=91214&view=rev Log: Fix some CHECK lines which were ignored by accident. Modified: llvm/trunk/test/Transforms/DeadStoreElimination/const-pointers.ll llvm/trunk/test/Transforms/InstCombine/compare-signs.ll Modified: llvm/trunk/test/Transforms/DeadStoreElimination/const-pointers.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/const-pointers.ll?rev=91214&r1=91213&r2=91214&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/const-pointers.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/const-pointers.ll Sat Dec 12 03:25:50 2009 @@ -11,7 +11,7 @@ %x = load i32* inttoptr (i32 12345 to i32*) store i32 %x, i32* %p ret void -; CHECK define void @test1 +; CHECK: define void @test1 ; CHECK: store ; CHECK-NOT: store ; CHECK: ret void @@ -21,10 +21,10 @@ store i32 1, i32* @g; <-- This is dead. store i32 42, i32* @g ret void -;CHECK define void @test3 -;CHECK: store -;CHECK-NOT: store -;CHECK: ret void +; CHECK: define void @test3 +; CHECK: store +; CHECK-NOT: store +; CHECK: ret void } define void @test4(i32* %p) { @@ -32,7 +32,7 @@ %x = load i32* @g; <-- %p and @g could alias store i32 %x, i32* %p ret void -; CHECK define void @test4 +; CHECK: define void @test4 ; CHECK: store ; CHECK: store ; CHECK: ret void Modified: llvm/trunk/test/Transforms/InstCombine/compare-signs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/compare-signs.ll?rev=91214&r1=91213&r2=91214&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/compare-signs.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/compare-signs.ll Sat Dec 12 03:25:50 2009 @@ -25,7 +25,7 @@ ; CHECK: @test3 entry: ; CHECK: xor i32 %a, %b -; CHECK; lshr i32 %0, 31 +; CHECK: lshr i32 %0, 31 ; CHECK: xor i32 %1, 1 %0 = lshr i32 %a, 31 ; [#uses=1] %1 = lshr i32 %b, 31 ; [#uses=1] @@ -43,7 +43,7 @@ ; CHECK: @test3i entry: ; CHECK: xor i32 %a, %b -; CHECK; lshr i32 %0, 31 +; CHECK: lshr i32 %0, 31 ; CHECK: xor i32 %1, 1 %0 = lshr i32 %a, 29 ; [#uses=1] %1 = lshr i32 %b, 29 ; [#uses=1] From edwintorok at gmail.com Sat Dec 12 06:42:31 2009 From: edwintorok at gmail.com (Torok Edwin) Date: Sat, 12 Dec 2009 12:42:31 -0000 Subject: [llvm-commits] [llvm] r91217 - /llvm/trunk/lib/System/Host.cpp Message-ID: <200912121242.nBCCgVaf010032@zion.cs.uiuc.edu> Author: edwin Date: Sat Dec 12 06:42:31 2009 New Revision: 91217 URL: http://llvm.org/viewvc/llvm-project?rev=91217&view=rev Log: Enable CPU detection when using MS VS 2k8 too. MSVS2k8 doesn't define __i386__, hence all the CPU detection code was disabled. Enable it by looking for _MSC_VER. Modified: llvm/trunk/lib/System/Host.cpp Modified: llvm/trunk/lib/System/Host.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Host.cpp?rev=91217&r1=91216&r2=91217&view=diff ============================================================================== --- llvm/trunk/lib/System/Host.cpp (original) +++ llvm/trunk/lib/System/Host.cpp Sat Dec 12 06:42:31 2009 @@ -107,7 +107,7 @@ std::string sys::getHostCPUName() { -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) return "generic"; From evan.cheng at apple.com Sat Dec 12 12:40:34 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 10:40:34 -0800 Subject: [llvm-commits] [llvm] r91104 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.h In-Reply-To: References: <200912110601.nBB61mfT014511@zion.cs.uiuc.edu> Message-ID: <1CCE5C39-C8AF-4BAE-8A6D-FD6B618F4040@apple.com> On Dec 11, 2009, at 11:19 AM, Dan Gohman wrote: > > On Dec 10, 2009, at 10:01 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Fri Dec 11 00:01:48 2009 >> New Revision: 91104 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=91104&view=rev >> Log: >> Add support to 3-addressify 16-bit instructions. >> >> Modified: >> llvm/trunk/lib/Target/X86/X86InstrInfo.cpp >> llvm/trunk/lib/Target/X86/X86InstrInfo.h >> >> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=91104&r1=91103&r2=91104&view=diff >> >> ============================================================================== >> --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 11 00:01:48 2009 >> @@ -1058,6 +1058,107 @@ >> return false; >> } >> >> +/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when 16-bit >> +/// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting > > Typo: "16-bit 16-bit". > >> +/// to a 32-bit superregister and then truncating back down to a 16-bit >> +/// subregister. > > This change introduces a partial register stall condition; are you > sure this is worthwhile? If so, please note this in a comment. > > Also, do you have a testcase? See 91105. I had considered the issue of partial register stall. I do have a micro-benchmark that shows this patch speeding it up noticeably. Perhaps lea doesn't suffer from it? I'll fix up the test and commit it later. It might also be worthwhile to consider just using the 16-bit lea instruction. I'll experiment. Evan > > Dan > From evan.cheng at apple.com Sat Dec 12 12:51:56 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 18:51:56 -0000 Subject: [llvm-commits] [llvm] r91219 - /llvm/trunk/lib/Target/X86/X86InstrInfo.td Message-ID: <200912121851.nBCIpukb021734@zion.cs.uiuc.edu> Author: evancheng Date: Sat Dec 12 12:51:56 2009 New Revision: 91219 URL: http://llvm.org/viewvc/llvm-project?rev=91219&view=rev Log: Fix an obvious bug. No test case since LEA16r is not being used. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=91219&r1=91218&r2=91219&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Dec 12 12:51:56 2009 @@ -816,7 +816,7 @@ let neverHasSideEffects = 1 in def LEA16r : I<0x8D, MRMSrcMem, - (outs GR16:$dst), (ins i32mem:$src), + (outs GR16:$dst), (ins lea32mem:$src), "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize; let isReMaterializable = 1 in def LEA32r : I<0x8D, MRMSrcMem, From evan.cheng at apple.com Sat Dec 12 12:55:26 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 18:55:26 -0000 Subject: [llvm-commits] [llvm] r91220 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200912121855.nBCItQTn021855@zion.cs.uiuc.edu> Author: evancheng Date: Sat Dec 12 12:55:26 2009 New Revision: 91220 URL: http://llvm.org/viewvc/llvm-project?rev=91220&view=rev Log: Add comment about potential partial register stall. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=91220&r1=91219&r2=91220&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 12 12:55:26 2009 @@ -1081,6 +1081,11 @@ // Build and insert into an implicit UNDEF value. This is OK because // well be shifting and then extracting the lower 16-bits. + // This has the potential to cause partial stall. e.g. + // movw (%rbp,%rcx,2), %dx + // leal -65(%rdx), %esi + // But testing has shown this *does* help performance (at least on modern + // x86 machines). BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg); MachineInstr *InsMI = BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg) From asl at math.spbu.ru Sat Dec 12 12:55:37 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 12 Dec 2009 18:55:37 -0000 Subject: [llvm-commits] [llvm] r91221 - in /llvm/trunk/lib/Target/MSP430: MSP430ISelLowering.cpp MSP430ISelLowering.h MSP430InstrInfo.td Message-ID: <200912121855.nBCItb4Z021879@zion.cs.uiuc.edu> Author: asl Date: Sat Dec 12 12:55:37 2009 New Revision: 91221 URL: http://llvm.org/viewvc/llvm-project?rev=91221&view=rev Log: Implement variable-width shifts. No testcase yet - it seems we're exposing generic codegen bugs. Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=91221&r1=91220&r2=91221&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Sat Dec 12 12:55:37 2009 @@ -592,9 +592,21 @@ EVT VT = Op.getValueType(); DebugLoc dl = N->getDebugLoc(); - // We currently only lower shifts of constant argument. + // Expand non-constant shifts to loops: if (!isa(N->getOperand(1))) - return SDValue(); + switch (Opc) { + default: + assert(0 && "Invalid shift opcode!"); + case ISD::SHL: + return DAG.getNode(MSP430ISD::SHL, dl, + VT, N->getOperand(0), N->getOperand(1)); + case ISD::SRA: + return DAG.getNode(MSP430ISD::SRA, dl, + VT, N->getOperand(0), N->getOperand(1)); + case ISD::SRL: + return DAG.getNode(MSP430ISD::SRL, dl, + VT, N->getOperand(0), N->getOperand(1)); + } uint64_t ShiftAmount = cast(N->getOperand(1))->getZExtValue(); @@ -916,6 +928,8 @@ case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; case MSP430ISD::CMP: return "MSP430ISD::CMP"; case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; + case MSP430ISD::SHL: return "MSP430ISD::SHL"; + case MSP430ISD::SRA: return "MSP430ISD::SRA"; } } @@ -924,13 +938,131 @@ //===----------------------------------------------------------------------===// MachineBasicBlock* +MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, + MachineBasicBlock *BB, + DenseMap *EM) const { + MachineFunction *F = BB->getParent(); + MachineRegisterInfo &RI = F->getRegInfo(); + DebugLoc dl = MI->getDebugLoc(); + const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); + + unsigned Opc; + const TargetRegisterClass * RC; + switch (MI->getOpcode()) { + default: + assert(0 && "Invalid shift opcode!"); + case MSP430::Shl8: + Opc = MSP430::SHL8r1; + RC = MSP430::GR8RegisterClass; + break; + case MSP430::Shl16: + Opc = MSP430::SHL16r1; + RC = MSP430::GR16RegisterClass; + break; + case MSP430::Sra8: + Opc = MSP430::SAR8r1; + RC = MSP430::GR8RegisterClass; + break; + case MSP430::Sra16: + Opc = MSP430::SAR16r1; + RC = MSP430::GR16RegisterClass; + break; + case MSP430::Srl8: + Opc = MSP430::SAR8r1c; + RC = MSP430::GR8RegisterClass; + break; + case MSP430::Srl16: + Opc = MSP430::SAR16r1c; + RC = MSP430::GR16RegisterClass; + break; + } + + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator I = BB; + ++I; + + // Create loop block + MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); + + F->insert(I, LoopBB); + F->insert(I, RemBB); + + // Update machine-CFG edges by transferring all successors of the current + // block to the block containing instructions after shift. + RemBB->transferSuccessors(BB); + + // Inform sdisel of the edge changes. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + EM->insert(std::make_pair(*SI, RemBB)); + + // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB + BB->addSuccessor(LoopBB); + BB->addSuccessor(RemBB); + LoopBB->addSuccessor(RemBB); + LoopBB->addSuccessor(LoopBB); + + unsigned ShiftAmtReg = RI.createVirtualRegister(MSP430::GR8RegisterClass); + unsigned ShiftAmtReg2 = RI.createVirtualRegister(MSP430::GR8RegisterClass); + unsigned ShiftReg = RI.createVirtualRegister(RC); + unsigned ShiftReg2 = RI.createVirtualRegister(RC); + unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); + unsigned DstReg = MI->getOperand(0).getReg(); + + // BB: + // cmp 0, N + // je RemBB + BuildMI(BB, dl, TII.get(MSP430::CMP8ir)) + .addImm(0).addReg(ShiftAmtSrcReg); + BuildMI(BB, dl, TII.get(MSP430::JCC)) + .addMBB(RemBB) + .addImm(MSP430CC::COND_E); + + // LoopBB: + // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] + // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] + // ShiftReg2 = shift ShiftReg + // ShiftAmt2 = ShiftAmt - 1; + BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) + .addReg(SrcReg).addMBB(BB) + .addReg(ShiftReg2).addMBB(LoopBB); + BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) + .addReg(ShiftAmtSrcReg).addMBB(BB) + .addReg(ShiftAmtReg2).addMBB(LoopBB); + BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) + .addReg(ShiftReg); + BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) + .addReg(ShiftAmtReg).addImm(1); + BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) + .addMBB(LoopBB) + .addImm(MSP430CC::COND_NE); + + // RemBB: + // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] + BuildMI(RemBB, dl, TII.get(MSP430::PHI), DstReg) + .addReg(SrcReg).addMBB(BB) + .addReg(ShiftReg2).addMBB(LoopBB); + + return RemBB; +} + +MachineBasicBlock* MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB, DenseMap *EM) const { + unsigned Opc = MI->getOpcode(); + + if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || + Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || + Opc == MSP430::Srl8 || Opc == MSP430::Srl16) + return EmitShiftInstr(MI, BB, EM); + const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); DebugLoc dl = MI->getDebugLoc(); - assert((MI->getOpcode() == MSP430::Select16 || - MI->getOpcode() == MSP430::Select8) && + + assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && "Unexpected instr type to insert"); // To "insert" a SELECT instruction, we actually have to insert the diamond Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h?rev=91221&r1=91220&r2=91221&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.h Sat Dec 12 12:55:37 2009 @@ -47,7 +47,7 @@ /// CMP - Compare instruction. CMP, - /// SetCC. Operand 0 is condition code, and operand 1 is the flag + /// SetCC - Operand 0 is condition code, and operand 1 is the flag /// operand produced by a CMP instruction. SETCC, @@ -57,9 +57,12 @@ /// instruction. BR_CC, - /// SELECT_CC. Operand 0 and operand 1 are selection variable, operand 3 + /// SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3 /// is condition code and operand 4 is flag operand. - SELECT_CC + SELECT_CC, + + /// SHL, SRA, SRL - Non-constant shifts. + SHL, SRA, SRL }; } @@ -99,6 +102,9 @@ MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB, DenseMap *EM) const; + MachineBasicBlock* EmitShiftInstr(MachineInstr *MI, + MachineBasicBlock *BB, + DenseMap *EM) const; private: SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td?rev=91221&r1=91220&r2=91221&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.td Sat Dec 12 12:55:37 2009 @@ -31,6 +31,7 @@ SDTCisVT<1, i8>]>; def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>; +def SDT_MSP430Shift : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisI8<2>]>; //===----------------------------------------------------------------------===// // MSP430 Specific Node Definitions. @@ -56,6 +57,9 @@ def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>; def MSP430brcc : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>; def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>; +def MSP430shl : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>; +def MSP430sra : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>; +def MSP430srl : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>; //===----------------------------------------------------------------------===// // MSP430 Operand Definitions. @@ -121,6 +125,27 @@ "# Select16 PSEUDO", [(set GR16:$dst, (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>; + let Defs = [SRW] in { + def Shl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), + "# Shl8 PSEUDO", + [(set GR8:$dst, (MSP430shl GR8:$src, GR8:$cnt))]>; + def Shl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), + "# Shl16 PSEUDO", + [(set GR16:$dst, (MSP430shl GR16:$src, GR8:$cnt))]>; + def Sra8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), + "# Sra8 PSEUDO", + [(set GR8:$dst, (MSP430sra GR8:$src, GR8:$cnt))]>; + def Sra16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), + "# Sra16 PSEUDO", + [(set GR16:$dst, (MSP430sra GR16:$src, GR8:$cnt))]>; + def Srl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), + "# Srl8 PSEUDO", + [(set GR8:$dst, (MSP430srl GR8:$src, GR8:$cnt))]>; + def Srl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), + "# Srl16 PSEUDO", + [(set GR16:$dst, (MSP430srl GR16:$src, GR8:$cnt))]>; + + } } let neverHasSideEffects = 1 in From evan.cheng at apple.com Sat Dec 12 13:21:59 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 11:21:59 -0800 Subject: [llvm-commits] [llvm] r91104 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.h In-Reply-To: <1CCE5C39-C8AF-4BAE-8A6D-FD6B618F4040@apple.com> References: <200912110601.nBB61mfT014511@zion.cs.uiuc.edu> <1CCE5C39-C8AF-4BAE-8A6D-FD6B618F4040@apple.com> Message-ID: <1FA6C5E6-CCA9-471F-915A-FC3DD1255FC2@apple.com> On Dec 12, 2009, at 10:40 AM, Evan Cheng wrote: > > See 91105. > > I had considered the issue of partial register stall. I do have a micro-benchmark that shows this patch speeding it up noticeably. Perhaps lea doesn't suffer from it? I'll fix up the test and commit it later. Actually in 32-bit partial register stall does happen and makes it slower. > > It might also be worthwhile to consider just using the 16-bit lea instruction. I'll experiment. 16-bit lea is indeed super slow. Evan > > Evan > >> >> Dan >> > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Sat Dec 12 14:03:14 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 20:03:14 -0000 Subject: [llvm-commits] [llvm] r91223 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.cpp test/CodeGen/X86/3addr-16bit.ll Message-ID: <200912122003.nBCK3Esm024065@zion.cs.uiuc.edu> Author: evancheng Date: Sat Dec 12 14:03:14 2009 New Revision: 91223 URL: http://llvm.org/viewvc/llvm-project?rev=91223&view=rev Log: Disable r91104 for x86. It causes partial register stall which pessimize code in 32-bit. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/test/CodeGen/X86/3addr-16bit.ll Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=91223&r1=91222&r2=91223&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 12 14:03:14 2009 @@ -1058,7 +1058,7 @@ return false; } -/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when 16-bit +/// convertToThreeAddressWithLEA - Helper for convertToThreeAddress when /// 16-bit LEA is disabled, use 32-bit LEA to form 3-address code by promoting /// to a 32-bit superregister and then truncating back down to a 16-bit /// subregister. @@ -1081,11 +1081,11 @@ // Build and insert into an implicit UNDEF value. This is OK because // well be shifting and then extracting the lower 16-bits. - // This has the potential to cause partial stall. e.g. + // This has the potential to cause partial register stall. e.g. // movw (%rbp,%rcx,2), %dx // leal -65(%rdx), %esi - // But testing has shown this *does* help performance (at least on modern - // x86 machines). + // But testing has shown this *does* help performance in 64-bit mode (at + // least on modern x86 machines). BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg); MachineInstr *InsMI = BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg) @@ -1189,7 +1189,9 @@ MachineInstr *NewMI = NULL; // FIXME: 16-bit LEA's are really slow on Athlons, but not bad on P4's. When // we have better subtarget support, enable the 16-bit LEA generation here. + // 16-bit LEA is also slow on Core2. bool DisableLEA16 = true; + bool is64Bit = TM.getSubtarget().is64Bit(); unsigned MIOpc = MI->getOpcode(); switch (MIOpc) { @@ -1228,8 +1230,7 @@ unsigned ShAmt = MI->getOperand(2).getImm(); if (ShAmt == 0 || ShAmt >= 4) return 0; - unsigned Opc = TM.getSubtarget().is64Bit() ? - X86::LEA64_32r : X86::LEA32r; + unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc)) .addReg(Dest, RegState::Define | getDeadRegState(isDead)) .addReg(0).addImm(1 << ShAmt) @@ -1244,7 +1245,7 @@ if (ShAmt == 0 || ShAmt >= 4) return 0; if (DisableLEA16) - return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV) : 0; NewMI = BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | getDeadRegState(isDead)) .addReg(0).addImm(1 << ShAmt) @@ -1259,7 +1260,6 @@ if (hasLiveCondCodeDef(MI)) return 0; - bool is64Bit = TM.getSubtarget().is64Bit(); switch (MIOpc) { default: return 0; case X86::INC64r: @@ -1277,7 +1277,7 @@ case X86::INC16r: case X86::INC64_16r: if (DisableLEA16) - return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV) : 0; assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!"); NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | @@ -1299,7 +1299,7 @@ case X86::DEC16r: case X86::DEC64_16r: if (DisableLEA16) - return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV) : 0; assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!"); NewMI = addRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | @@ -1323,7 +1323,7 @@ } case X86::ADD16rr: { if (DisableLEA16) - return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV) : 0; assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); unsigned Src2 = MI->getOperand(2).getReg(); bool isKill2 = MI->getOperand(2).isKill(); @@ -1356,7 +1356,7 @@ case X86::ADD16ri: case X86::ADD16ri8: if (DisableLEA16) - return convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV); + return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MBBI, LV) : 0; assert(MI->getNumOperands() >= 3 && "Unknown add instruction!"); NewMI = addLeaRegOffset(BuildMI(MF, MI->getDebugLoc(), get(X86::LEA16r)) .addReg(Dest, RegState::Define | Modified: llvm/trunk/test/CodeGen/X86/3addr-16bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/3addr-16bit.ll?rev=91223&r1=91222&r2=91223&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/3addr-16bit.ll (original) +++ llvm/trunk/test/CodeGen/X86/3addr-16bit.ll Sat Dec 12 14:03:14 2009 @@ -1,5 +1,7 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -asm-verbose=false | FileCheck %s -check-prefix=32BIT ; RUN: llc < %s -mtriple=x86_64-apple-darwin -asm-verbose=false | FileCheck %s -check-prefix=64BIT +; rdar://7329206 + +; In 32-bit the partial register stall would degrade performance. define zeroext i16 @t1(i16 zeroext %c, i16 zeroext %k) nounwind ssp { entry: From evan.cheng at apple.com Sat Dec 12 14:31:31 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 12 Dec 2009 20:31:31 -0000 Subject: [llvm-commits] [test-suite] r91224 - /test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c Message-ID: <200912122031.nBCKVVPg024902@zion.cs.uiuc.edu> Author: evancheng Date: Sat Dec 12 14:31:30 2009 New Revision: 91224 URL: http://llvm.org/viewvc/llvm-project?rev=91224&view=rev Log: Add a test llvm is doing very poorly on. Added: test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c Added: test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c?rev=91224&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c (added) +++ test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c Sat Dec 12 14:31:30 2009 @@ -0,0 +1,53 @@ +#include +#include +#include + +typedef unsigned short UChar; + +static inline UChar toASCIILower(UChar c) { return c | ((c >= 'A' && c <= 'Z') << 5); } + +static size_t lower_StringImp(const UChar* data, size_t m_length, UChar* output) __attribute__((__noinline__)); +static size_t lower_StringImpl(const UChar* __restrict data, size_t length, UChar* __restrict output) +{ + // Do a faster loop for the case where all the characters are ASCII. + UChar ored = 0; + size_t i; + for (i = 0; i < length; i++) { + UChar c = data[i]; + ored |= c; + output[i] = toASCIILower(c); + } + if (!(ored & ~0x7F)) + return 1; + + return 0; +} + +static UChar staticData[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D', '!', 'H', 'E', 'L', 'L'}; +static const size_t staticDataLength = sizeof(staticData) / sizeof(staticData[0]); + +static void doTest(size_t numberOfIterations) +{ + const size_t numberOfCharacters = numberOfIterations; + const size_t testDataLength = (numberOfCharacters + staticDataLength) / staticDataLength; + UChar* testData = malloc(sizeof(UChar) * testDataLength); + size_t i; + for (i = 0; i < testDataLength; i += staticDataLength) + memcpy(testData + i, staticData, staticDataLength * sizeof(staticData[0])); + + UChar* result = malloc(sizeof(UChar) * testDataLength); + printf("iterations (%ld characters)\n", numberOfIterations, numberOfCharacters); + + memset(result, 0, sizeof(UChar) * testDataLength); + for (i = 0; i < 10000000; i++) + lower_StringImpl(testData, numberOfCharacters, result); +} + +int main(int argc, char **argv) +{ + size_t i; + for (i = 0; i < 32; i++) + doTest(i); + + return 0; +} From daniel at zuster.org Sat Dec 12 15:17:55 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Sat, 12 Dec 2009 21:17:55 -0000 Subject: [llvm-commits] [llvm] r91226 - /llvm/trunk/Makefile Message-ID: <200912122117.nBCLHtjY026423@zion.cs.uiuc.edu> Author: ddunbar Date: Sat Dec 12 15:17:54 2009 New Revision: 91226 URL: http://llvm.org/viewvc/llvm-project?rev=91226&view=rev Log: Update install-clang target for clang-cc removal. Modified: llvm/trunk/Makefile Modified: llvm/trunk/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile?rev=91226&r1=91225&r2=91226&view=diff ============================================================================== --- llvm/trunk/Makefile (original) +++ llvm/trunk/Makefile Sat Dec 12 15:17:54 2009 @@ -66,8 +66,7 @@ endif ifeq ($(MAKECMDGOALS),install-clang) - DIRS := tools/clang/tools/driver tools/clang/tools/clang-cc \ - tools/clang/lib/Headers tools/clang/docs + DIRS := tools/clang/tools/driver tools/clang/lib/Headers tools/clang/docs OPTIONAL_DIRS := NO_INSTALL = 1 endif From eli.friedman at gmail.com Sat Dec 12 15:41:49 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 12 Dec 2009 21:41:49 -0000 Subject: [llvm-commits] [llvm] r91228 - /llvm/trunk/lib/Target/README.txt Message-ID: <200912122141.nBCLfnog027227@zion.cs.uiuc.edu> Author: efriedma Date: Sat Dec 12 15:41:48 2009 New Revision: 91228 URL: http://llvm.org/viewvc/llvm-project?rev=91228&view=rev Log: Remove some stuff that's already implemented. Also, remove the note about merging x >u 5 and x = 10) && (x < 20) by producing (x - -10) u< 10, but only when the comparisons have matching sign. - -This could be converted with a similiar technique. (PR1941) - -define i1 @test(i8 %x) { - %A = icmp uge i8 %x, 5 - %B = icmp slt i8 %x, 20 - %C = and i1 %A, %B - ret i1 %C -} - -//===---------------------------------------------------------------------===// - These functions perform the same computation, but produce different assembly. define i8 @select(i8 %x) readnone nounwind { @@ -884,18 +870,6 @@ //===---------------------------------------------------------------------===// -From GCC Bug 15241: -unsigned int -foo (unsigned int a, unsigned int b) -{ - if (a <= 7 && b <= 7) - baz (); -} -Should combine to "(a|b) <= 7". Currently not optimized with "clang --emit-llvm-bc | opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - From GCC Bug 3756: int pn (int n) @@ -907,19 +881,6 @@ //===---------------------------------------------------------------------===// -From GCC Bug 28685: -int test(int a, int b) -{ - int lt = a < b; - int eq = a == b; - - return (lt || eq); -} -Should combine to "a <= b". Currently not optimized with "clang --emit-llvm-bc | opt -std-compile-opts | llc". - -//===---------------------------------------------------------------------===// - void a(int variable) { if (variable == 4 || variable == 6) @@ -993,12 +954,6 @@ //===---------------------------------------------------------------------===// -int a(unsigned char* b) {return *b > 99;} -There's an unnecessary zext in the generated code with "clang --emit-llvm-bc | opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - int a(unsigned b) {return ((b << 31) | (b << 30)) >> 31;} Should be combined to "((b >> 1) | b) & 1". Currently not optimized with "clang -emit-llvm-bc | opt -std-compile-opts". @@ -1011,12 +966,6 @@ //===---------------------------------------------------------------------===// -unsigned a(unsigned a) {return ((a | 1) & 3) | (a & -4);} -Should combine to "a | 1". Currently not optimized with "clang --emit-llvm-bc | opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - int a(int a, int b, int c) {return (~a & c) | ((c|a) & b);} Should fold to "(~a & c) | (a & b)". Currently not optimized with "clang -emit-llvm-bc | opt -std-compile-opts". From edwintorok at gmail.com Sat Dec 12 15:58:31 2009 From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=) Date: Sat, 12 Dec 2009 23:58:31 +0200 Subject: [llvm-commits] [test-suite] r91224 - /test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c In-Reply-To: <200912122031.nBCKVVPg024902@zion.cs.uiuc.edu> References: <200912122031.nBCKVVPg024902@zion.cs.uiuc.edu> Message-ID: <4B241207.8090905@gmail.com> On 2009-12-12 22:31, Evan Cheng wrote: > Author: evancheng > Date: Sat Dec 12 14:31:30 2009 > New Revision: 91224 > > URL: http://llvm.org/viewvc/llvm-project?rev=91224&view=rev > Log: > Add a test llvm is doing very poorly on. > > Added: > test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c > > Added: test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c?rev=91224&view=auto > > ============================================================================== > --- test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c (added) > +++ test-suite/trunk/SingleSource/Benchmarks/Misc/lowercase.c Sat Dec 12 14:31:30 2009 > @@ -0,0 +1,53 @@ > +#include > +#include > +#include > + > +typedef unsigned short UChar; > + > +static inline UChar toASCIILower(UChar c) { return c | ((c >= 'A' && c <= 'Z') << 5); } > Would a lookup table be faster here? LLVM could precalculate it... Best regards, --Edwin From eli.friedman at gmail.com Sat Dec 12 17:23:43 2009 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 12 Dec 2009 23:23:43 -0000 Subject: [llvm-commits] [llvm] r91230 - /llvm/trunk/lib/Target/README.txt Message-ID: <200912122323.nBCNNhpA030356@zion.cs.uiuc.edu> Author: efriedma Date: Sat Dec 12 17:23:43 2009 New Revision: 91230 URL: http://llvm.org/viewvc/llvm-project?rev=91230&view=rev Log: More info on this transformation. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=91230&r1=91229&r2=91230&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Dec 12 17:23:43 2009 @@ -801,8 +801,21 @@ true(); } -I think this basically amounts to a dag combine to simplify comparisons against -multiply hi's into a comparison against the mullo. +This is equivalent to the following, where 2863311531 is the multiplicative +inverse of 3, and 1431655766 is ((2^32)-1)/3+1: +void bar(unsigned n) { + if (n * 2863311531U < 1431655766U) + true(); +} + +The same transformation can work with an even modulo with the addition of a +rotate: rotate the result of the multiply to the right by the number of bits +which need to be zero for the condition to be true, and shrink the compare RHS +by the same amount. Unless the target supports rotates, though, that +transformation probably isn't worthwhile. + +The transformation can also easily be made to work with non-zero equality +comparisons: just transform, for example, "n % 3 == 1" to "(n-1) % 3 == 0". //===---------------------------------------------------------------------===// From asl at math.spbu.ru Sat Dec 12 19:00:33 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 13 Dec 2009 01:00:33 -0000 Subject: [llvm-commits] [llvm] r91232 - /llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Message-ID: <200912130100.nBD10XwL001124@zion.cs.uiuc.edu> Author: asl Date: Sat Dec 12 19:00:32 2009 New Revision: 91232 URL: http://llvm.org/viewvc/llvm-project?rev=91232&view=rev Log: Do not allow uninitialize access during debug printing Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp?rev=91232&r1=91231&r2=91232&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Sat Dec 12 19:00:32 2009 @@ -86,10 +86,10 @@ void dump() { errs() << "MSP430ISelAddressMode " << this << '\n'; - if (Base.Reg.getNode() != 0) { + if (BaseType == RegBase && Base.Reg.getNode() != 0) { errs() << "Base.Reg "; Base.Reg.getNode()->dump(); - } else { + } else if (BaseType == FrameIndexBase) { errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; } errs() << " Disp " << Disp << '\n'; From asl at math.spbu.ru Sat Dec 12 19:00:59 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 13 Dec 2009 01:00:59 -0000 Subject: [llvm-commits] [llvm] r91233 - in /llvm/trunk: include/llvm/CodeGen/DAGISelHeader.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200912130100.nBD10xVr001158@zion.cs.uiuc.edu> Author: asl Date: Sat Dec 12 19:00:59 2009 New Revision: 91233 URL: http://llvm.org/viewvc/llvm-project?rev=91233&view=rev Log: Fix weird typo which leads to unallocated memory access for nodes with 4 results. Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h?rev=91233&r1=91232&r2=91233&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (original) +++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Sat Dec 12 19:00:59 2009 @@ -110,8 +110,7 @@ DAG.setSubgraphColor(Node, "red"); #endif SDNode *ResNode = Select(SDValue(Node, 0)); - // If node should not be replaced, - // continue with the next one. + // If node should not be replaced, continue with the next one. if (ResNode == Node) continue; // Replace node. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=91233&r1=91232&r2=91233&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Dec 12 19:00:59 2009 @@ -4177,7 +4177,7 @@ I->VTs[2] == VT3 && I->VTs[3] == VT4) return *I; - EVT *Array = Allocator.Allocate(3); + EVT *Array = Allocator.Allocate(4); Array[0] = VT1; Array[1] = VT2; Array[2] = VT3; From chandlerc at gmail.com Sun Dec 13 01:04:48 2009 From: chandlerc at gmail.com (Chandler Carruth) Date: Sun, 13 Dec 2009 07:04:48 -0000 Subject: [llvm-commits] [llvm] r91239 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200912130704.nBD74mOR012132@zion.cs.uiuc.edu> Author: chandlerc Date: Sun Dec 13 01:04:45 2009 New Revision: 91239 URL: http://llvm.org/viewvc/llvm-project?rev=91239&view=rev Log: Don't leave pointers uninitialized in the default constructor. GCC complains about the potential use of these uninitialized members under certain conditions. Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=91239&r1=91238&r2=91239&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Sun Dec 13 01:04:45 2009 @@ -102,7 +102,7 @@ public: typedef std::vector ValVector; - RenamePassData() {} + RenamePassData() : BB(NULL), Pred(NULL), Values() {} RenamePassData(BasicBlock *B, BasicBlock *P, const ValVector &V) : BB(B), Pred(P), Values(V) {} BasicBlock *BB; From edwintorok at gmail.com Sun Dec 13 02:59:41 2009 From: edwintorok at gmail.com (Torok Edwin) Date: Sun, 13 Dec 2009 08:59:41 -0000 Subject: [llvm-commits] [llvm] r91240 - /llvm/trunk/lib/System/Host.cpp Message-ID: <200912130859.nBD8xfDN025361@zion.cs.uiuc.edu> Author: edwin Date: Sun Dec 13 02:59:40 2009 New Revision: 91240 URL: http://llvm.org/viewvc/llvm-project?rev=91240&view=rev Log: Using _MSC_VER there was wrong, better just use the already existing ifdefs for x86 CPU detection for the X86 getHostCPUName too, and create a simple getHostCPUName that returns "generic" for all else. Modified: llvm/trunk/lib/System/Host.cpp Modified: llvm/trunk/lib/System/Host.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Host.cpp?rev=91240&r1=91239&r2=91240&view=diff ============================================================================== --- llvm/trunk/lib/System/Host.cpp (original) +++ llvm/trunk/lib/System/Host.cpp Sun Dec 13 02:59:40 2009 @@ -103,11 +103,8 @@ Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 } } -#endif - std::string sys::getHostCPUName() { -#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) return "generic"; @@ -295,7 +292,9 @@ return "generic"; } } -#endif - +} +#else +std::string sys::getHostCPUName() { return "generic"; } +#endif From jyasskin at google.com Sun Dec 13 14:30:33 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Sun, 13 Dec 2009 20:30:33 -0000 Subject: [llvm-commits] [llvm] r91250 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp unittests/ExecutionEngine/JIT/Makefile Message-ID: <200912132030.nBDKUXmW010546@zion.cs.uiuc.edu> Author: jyasskin Date: Sun Dec 13 14:30:32 2009 New Revision: 91250 URL: http://llvm.org/viewvc/llvm-project?rev=91250&view=rev Log: Reinstate r91208 to fix available_externally linkage for globals, with nlewycky's fix to add -rdynamic so the JIT can look symbols up in Linux builds of the JITTests binary. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp llvm/trunk/unittests/ExecutionEngine/JIT/Makefile Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91250&r1=91249&r2=91250&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sun Dec 13 14:30:32 2009 @@ -681,7 +681,7 @@ if (Ptr) return Ptr; // If the global is external, just remember the address. - if (GV->isDeclaration()) { + if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { #if HAVE___DSO_HANDLE if (GV->getName() == "__dso_handle") return (void*)&__dso_handle; Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91250&r1=91249&r2=91250&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Sun Dec 13 14:30:32 2009 @@ -534,6 +534,31 @@ #endif } +} // anonymous namespace +// This variable is intentionally defined differently in the statically-compiled +// program from the IR input to the JIT to assert that the JIT doesn't use its +// definition. +extern "C" int32_t JITTest_AvailableExternallyGlobal; +int32_t JITTest_AvailableExternallyGlobal = 42; +namespace { + +TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { + TheJIT->DisableLazyCompilation(true); + LoadAssembly("@JITTest_AvailableExternallyGlobal = " + " available_externally global i32 7 " + " " + "define i32 @loader() { " + " %result = load i32* @JITTest_AvailableExternallyGlobal " + " ret i32 %result " + "} "); + Function *loaderIR = M->getFunction("loader"); + + int32_t (*loader)() = reinterpret_cast( + (intptr_t)TheJIT->getPointerToFunction(loaderIR)); + EXPECT_EQ(42, loader()) << "func should return 42 from the external global," + << " not 7 from the IR version."; +} + // This code is copied from JITEventListenerTest, but it only runs once for all // the tests in this directory. Everything seems fine, but that's strange // behavior. Modified: llvm/trunk/unittests/ExecutionEngine/JIT/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/Makefile?rev=91250&r1=91249&r2=91250&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/Makefile (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/Makefile Sun Dec 13 14:30:32 2009 @@ -13,3 +13,6 @@ include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest + +# Permit these tests to use the JIT's symbolic lookup. +LD.Flags += $(RDYNAMIC) From jyasskin at google.com Sun Dec 13 14:33:12 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Sun, 13 Dec 2009 12:33:12 -0800 Subject: [llvm-commits] [llvm] r91209 - in /llvm/trunk: lib/ExecutionEngine/JIT/JIT.cpp unittests/ExecutionEngine/JIT/JITTest.cpp In-Reply-To: References: <200912120618.nBC6Ikix015917@zion.cs.uiuc.edu> Message-ID: Thanks for the patch! I've reapplied the whole thing in r91250. On Fri, Dec 11, 2009 at 11:20 PM, Nick Lewycky wrote: > It was just missing -rdynamic. Patch attached. > > Nick > > 2009/12/11 Jeffrey Yasskin >> >> Author: jyasskin >> Date: Sat Dec 12 00:18:46 2009 >> New Revision: 91209 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=91209&view=rev >> Log: >> Revert r91208. ?Something on Linux prevents the JIT from looking up a >> symbol >> defined in the test, and I don't have time tonight to figure it out. >> >> Modified: >> ? ?llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp >> ? ?llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp >> >> Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=91209&r1=91208&r2=91209&view=diff >> >> >> ============================================================================== >> --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) >> +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat Dec 12 00:18:46 2009 >> @@ -681,7 +681,7 @@ >> ? if (Ptr) return Ptr; >> >> ? // If the global is external, just remember the address. >> - ?if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { >> + ?if (GV->isDeclaration()) { >> ?#if HAVE___DSO_HANDLE >> ? ? if (GV->getName() == "__dso_handle") >> ? ? ? return (void*)&__dso_handle; >> >> Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=91209&r1=91208&r2=91209&view=diff >> >> >> ============================================================================== >> --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) >> +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Sat Dec 12 >> 00:18:46 2009 >> @@ -534,31 +534,6 @@ >> ?#endif >> ?} >> >> -} ?// anonymous namespace >> -// This variable is intentionally defined differently in the >> statically-compiled >> -// program from the IR input to the JIT to assert that the JIT doesn't >> use its >> -// definition. >> -extern "C" int32_t JITTest_AvailableExternallyGlobal; >> -int32_t JITTest_AvailableExternallyGlobal = 42; >> -namespace { >> - >> -TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { >> - ?TheJIT->DisableLazyCompilation(true); >> - ?LoadAssembly("@JITTest_AvailableExternallyGlobal = " >> - ? ? ? ? ? ? ? " ?available_externally global i32 7 " >> - ? ? ? ? ? ? ? " " >> - ? ? ? ? ? ? ? "define i32 @loader() { " >> - ? ? ? ? ? ? ? " ?%result = load i32* @JITTest_AvailableExternallyGlobal >> " >> - ? ? ? ? ? ? ? " ?ret i32 %result " >> - ? ? ? ? ? ? ? "} "); >> - ?Function *loaderIR = M->getFunction("loader"); >> - >> - ?int32_t (*loader)() = reinterpret_cast( >> - ? ?(intptr_t)TheJIT->getPointerToFunction(loaderIR)); >> - ?EXPECT_EQ(42, loader()) << "func should return 42 from the external >> global," >> - ? ? ? ? ? ? ? ? ? ? ? ? ?<< " not 7 from the IR version."; >> -} >> - >> ?// This code is copied from JITEventListenerTest, but it only runs once >> for all >> ?// the tests in this directory. ?Everything seems fine, but that's >> strange >> ?// behavior. >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > From foldr at codedgers.com Sun Dec 13 22:06:38 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Mon, 14 Dec 2009 04:06:38 -0000 Subject: [llvm-commits] [llvm] r91259 - /llvm/trunk/test/LLVMC/Init.td Message-ID: <200912140406.nBE46cSf027380@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 13 22:06:38 2009 New Revision: 91259 URL: http://llvm.org/viewvc/llvm-project?rev=91259&view=rev Log: Add a test for the 'init' option property. Added: llvm/trunk/test/LLVMC/Init.td Added: llvm/trunk/test/LLVMC/Init.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/Init.td?rev=91259&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/Init.td (added) +++ llvm/trunk/test/LLVMC/Init.td Sun Dec 13 22:06:38 2009 @@ -0,0 +1,22 @@ +// Check that (init true/false) and (init "str") work. +// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t +// RUN: grep cl::init("some-string") %t +// RUN: grep cl::init(true) %t + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[ +(switch_option "dummy1", (help "none"), (init true)), +(parameter_option "dummy2", (help "none"), (init "some-string")) +]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd $INFILE"), +(in_language "dummy_lang"), +(out_language "dummy_lang"), +(actions (case + (switch_on "dummy1"), (forward "dummy1"), + (not_empty "dummy2"), (forward "dummy2"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; From grosbach at apple.com Sun Dec 13 22:22:07 2009 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 14 Dec 2009 04:22:07 -0000 Subject: [llvm-commits] [llvm] r91260 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200912140422.nBE4M7wY027945@zion.cs.uiuc.edu> Author: grosbach Date: Sun Dec 13 22:22:04 2009 New Revision: 91260 URL: http://llvm.org/viewvc/llvm-project?rev=91260&view=rev Log: atomic binary operations up to 32-bits wide. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=91260&r1=91259&r2=91260&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sun Dec 13 22:22:04 2009 @@ -3118,11 +3118,69 @@ MachineBasicBlock * ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode) const { - std::string msg; - raw_string_ostream Msg(msg); - Msg << "Cannot yet emit: "; - MI->print(Msg); - llvm_report_error(Msg.str()); + // This also handles ATOMIC_SWAP, indicated by BinOpcode==0. + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction *F = BB->getParent(); + MachineFunction::iterator It = BB; + ++It; + + unsigned dest = MI->getOperand(0).getReg(); + unsigned ptr = MI->getOperand(1).getReg(); + unsigned incr = MI->getOperand(2).getReg(); + DebugLoc dl = MI->getDebugLoc(); + unsigned ldrOpc, strOpc; + switch (Size) { + default: llvm_unreachable("unsupported size for AtomicCmpSwap!"); + case 1: ldrOpc = ARM::LDREXB; strOpc = ARM::STREXB; break; + case 2: ldrOpc = ARM::LDREXH; strOpc = ARM::STREXH; break; + case 4: ldrOpc = ARM::LDREX; strOpc = ARM::STREX; break; + } + + MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, loopMBB); + F->insert(It, exitMBB); + exitMBB->transferSuccessors(BB); + + MachineRegisterInfo &RegInfo = F->getRegInfo(); + unsigned scratch = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); + unsigned scratch2 = (!BinOpcode) ? incr : + RegInfo.createVirtualRegister(ARM::GPRRegisterClass); + + // thisMBB: + // ... + // fallthrough --> loopMBB + BB->addSuccessor(loopMBB); + + // loopMBB: + // ldrex dest, ptr + // add tmp, dest, incr + // strex scratch, tmp, ptr + // cmp scratch, #0 + // bne- loopMBB + // fallthrough --> exitMBB + BB = loopMBB; + AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr)); + if (BinOpcode) + AddDefaultPred(BuildMI(BB, dl, TII->get(BinOpcode), scratch2). + addReg(dest).addReg(incr)).addReg(0); + + AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(scratch2) + .addReg(ptr)); + AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::CMPri)) + .addReg(scratch).addImm(0)); + BuildMI(BB, dl, TII->get(ARM::Bcc)).addMBB(loopMBB).addImm(ARMCC::NE) + .addReg(ARM::CPSR); + + BB->addSuccessor(loopMBB); + BB->addSuccessor(exitMBB); + + // exitMBB: + // ... + BB = exitMBB; + return BB; } MachineBasicBlock * From sabre at nondot.org Sun Dec 13 23:11:03 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 14 Dec 2009 05:11:03 -0000 Subject: [llvm-commits] [llvm] r91268 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Message-ID: <200912140511.nBE5B3Uj029684@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 13 23:11:02 2009 New Revision: 91268 URL: http://llvm.org/viewvc/llvm-project?rev=91268&view=rev Log: revert r91184, because it causes a crash on a .bc file I just sent to Bob. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=91268&r1=91267&r2=91268&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sun Dec 13 23:11:02 2009 @@ -102,27 +102,25 @@ int isSafeAllocaToScalarRepl(AllocaInst *AI); - void isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, - uint64_t ArrayOffset, AllocaInfo &Info); - void isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t &Offset, - uint64_t &ArrayOffset, AllocaInfo &Info); - void isSafeMemAccess(AllocaInst *AI, uint64_t Offset, uint64_t ArrayOffset, - uint64_t MemSize, const Type *MemOpType, bool isStore, - AllocaInfo &Info); - bool TypeHasComponent(const Type *T, uint64_t Offset, uint64_t Size); - unsigned FindElementAndOffset(const Type *&T, uint64_t &Offset); + void isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, + AllocaInfo &Info); + void isSafeElementUse(Value *Ptr, bool isFirstElt, AllocaInst *AI, + AllocaInfo &Info); + void isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocaInst *AI, + unsigned OpNo, AllocaInfo &Info); + void isSafeUseOfBitCastedAllocation(BitCastInst *User, AllocaInst *AI, + AllocaInfo &Info); void DoScalarReplacement(AllocaInst *AI, std::vector &WorkList); void CleanupGEP(GetElementPtrInst *GEP); - void CleanupAllocaUsers(Value *V); + void CleanupAllocaUsers(AllocaInst *AI); AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocaInst *Base); - void RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, - SmallVector &NewElts); - void RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset, - SmallVector &NewElts); - void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, + void RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocaInst *AI, + SmallVector &NewElts); + + void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, AllocaInst *AI, SmallVector &NewElts); void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI, @@ -362,12 +360,176 @@ } } - // Now that we have created the new alloca instructions, rewrite all the - // uses of the old alloca. - RewriteForScalarRepl(AI, AI, 0, ElementAllocas); + // Now that we have created the alloca instructions that we want to use, + // expand the getelementptr instructions to use them. + while (!AI->use_empty()) { + Instruction *User = cast(AI->use_back()); + if (BitCastInst *BCInst = dyn_cast(User)) { + RewriteBitCastUserOfAlloca(BCInst, AI, ElementAllocas); + BCInst->eraseFromParent(); + continue; + } + + // Replace: + // %res = load { i32, i32 }* %alloc + // with: + // %load.0 = load i32* %alloc.0 + // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0 + // %load.1 = load i32* %alloc.1 + // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1 + // (Also works for arrays instead of structs) + if (LoadInst *LI = dyn_cast(User)) { + Value *Insert = UndefValue::get(LI->getType()); + for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) { + Value *Load = new LoadInst(ElementAllocas[i], "load", LI); + Insert = InsertValueInst::Create(Insert, Load, i, "insert", LI); + } + LI->replaceAllUsesWith(Insert); + LI->eraseFromParent(); + continue; + } + + // Replace: + // store { i32, i32 } %val, { i32, i32 }* %alloc + // with: + // %val.0 = extractvalue { i32, i32 } %val, 0 + // store i32 %val.0, i32* %alloc.0 + // %val.1 = extractvalue { i32, i32 } %val, 1 + // store i32 %val.1, i32* %alloc.1 + // (Also works for arrays instead of structs) + if (StoreInst *SI = dyn_cast(User)) { + Value *Val = SI->getOperand(0); + for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) { + Value *Extract = ExtractValueInst::Create(Val, i, Val->getName(), SI); + new StoreInst(Extract, ElementAllocas[i], SI); + } + SI->eraseFromParent(); + continue; + } + + GetElementPtrInst *GEPI = cast(User); + // We now know that the GEP is of the form: GEP , 0, + unsigned Idx = + (unsigned)cast(GEPI->getOperand(2))->getZExtValue(); + + assert(Idx < ElementAllocas.size() && "Index out of range?"); + AllocaInst *AllocaToUse = ElementAllocas[Idx]; + + Value *RepValue; + if (GEPI->getNumOperands() == 3) { + // Do not insert a new getelementptr instruction with zero indices, only + // to have it optimized out later. + RepValue = AllocaToUse; + } else { + // We are indexing deeply into the structure, so we still need a + // getelement ptr instruction to finish the indexing. This may be + // expanded itself once the worklist is rerun. + // + SmallVector NewArgs; + NewArgs.push_back(Constant::getNullValue( + Type::getInt32Ty(AI->getContext()))); + NewArgs.append(GEPI->op_begin()+3, GEPI->op_end()); + RepValue = GetElementPtrInst::Create(AllocaToUse, NewArgs.begin(), + NewArgs.end(), "", GEPI); + RepValue->takeName(GEPI); + } + + // If this GEP is to the start of the aggregate, check for memcpys. + if (Idx == 0 && GEPI->hasAllZeroIndices()) + RewriteBitCastUserOfAlloca(GEPI, AI, ElementAllocas); + + // Move all of the users over to the new GEP. + GEPI->replaceAllUsesWith(RepValue); + // Delete the old GEP + GEPI->eraseFromParent(); + } + + // Finally, delete the Alloca instruction + AI->eraseFromParent(); NumReplaced++; } - + +/// isSafeElementUse - Check to see if this use is an allowed use for a +/// getelementptr instruction of an array aggregate allocation. isFirstElt +/// indicates whether Ptr is known to the start of the aggregate. +void SROA::isSafeElementUse(Value *Ptr, bool isFirstElt, AllocaInst *AI, + AllocaInfo &Info) { + for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); + I != E; ++I) { + Instruction *User = cast(*I); + switch (User->getOpcode()) { + case Instruction::Load: break; + case Instruction::Store: + // Store is ok if storing INTO the pointer, not storing the pointer + if (User->getOperand(0) == Ptr) return MarkUnsafe(Info); + break; + case Instruction::GetElementPtr: { + GetElementPtrInst *GEP = cast(User); + bool AreAllZeroIndices = isFirstElt; + if (GEP->getNumOperands() > 1 && + (!isa(GEP->getOperand(1)) || + !cast(GEP->getOperand(1))->isZero())) + // Using pointer arithmetic to navigate the array. + return MarkUnsafe(Info); + + // Verify that any array subscripts are in range. + for (gep_type_iterator GEPIt = gep_type_begin(GEP), + E = gep_type_end(GEP); GEPIt != E; ++GEPIt) { + // Ignore struct elements, no extra checking needed for these. + if (isa(*GEPIt)) + continue; + + // This GEP indexes an array. Verify that this is an in-range + // constant integer. Specifically, consider A[0][i]. We cannot know that + // the user isn't doing invalid things like allowing i to index an + // out-of-range subscript that accesses A[1]. Because of this, we have + // to reject SROA of any accesses into structs where any of the + // components are variables. + ConstantInt *IdxVal = dyn_cast(GEPIt.getOperand()); + if (!IdxVal) return MarkUnsafe(Info); + + // Are all indices still zero? + AreAllZeroIndices &= IdxVal->isZero(); + + if (const ArrayType *AT = dyn_cast(*GEPIt)) { + if (IdxVal->getZExtValue() >= AT->getNumElements()) + return MarkUnsafe(Info); + } else if (const VectorType *VT = dyn_cast(*GEPIt)) { + if (IdxVal->getZExtValue() >= VT->getNumElements()) + return MarkUnsafe(Info); + } + } + + isSafeElementUse(GEP, AreAllZeroIndices, AI, Info); + if (Info.isUnsafe) return; + break; + } + case Instruction::BitCast: + if (isFirstElt) { + isSafeUseOfBitCastedAllocation(cast(User), AI, Info); + if (Info.isUnsafe) return; + break; + } + DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); + return MarkUnsafe(Info); + case Instruction::Call: + if (MemIntrinsic *MI = dyn_cast(User)) { + if (isFirstElt) { + isSafeMemIntrinsicOnAllocation(MI, AI, I.getOperandNo(), Info); + if (Info.isUnsafe) return; + break; + } + } + DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); + return MarkUnsafe(Info); + default: + DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); + return MarkUnsafe(Info); + } + } + return; // All users look ok :) +} + /// AllUsersAreLoads - Return true if all users of this value are loads. static bool AllUsersAreLoads(Value *Ptr) { for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); @@ -377,116 +539,72 @@ return true; } -/// isSafeForScalarRepl - Check if instruction I is a safe use with regard to -/// performing scalar replacement of alloca AI. The results are flagged in -/// the Info parameter. Offset and ArrayOffset indicate the position within -/// AI that is referenced by this instruction. -void SROA::isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, - uint64_t ArrayOffset, AllocaInfo &Info) { - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI!=E; ++UI) { - Instruction *User = cast(*UI); - - if (BitCastInst *BC = dyn_cast(User)) { - isSafeForScalarRepl(BC, AI, Offset, ArrayOffset, Info); - } else if (GetElementPtrInst *GEPI = dyn_cast(User)) { - uint64_t GEPArrayOffset = ArrayOffset; - uint64_t GEPOffset = Offset; - isSafeGEP(GEPI, AI, GEPOffset, GEPArrayOffset, Info); - if (!Info.isUnsafe) - isSafeForScalarRepl(GEPI, AI, GEPOffset, GEPArrayOffset, Info); - } else if (MemIntrinsic *MI = dyn_cast(UI)) { - ConstantInt *Length = dyn_cast(MI->getLength()); - if (Length) - isSafeMemAccess(AI, Offset, ArrayOffset, Length->getZExtValue(), 0, - UI.getOperandNo() == 1, Info); - else - MarkUnsafe(Info); - } else if (LoadInst *LI = dyn_cast(User)) { - if (!LI->isVolatile()) { - const Type *LIType = LI->getType(); - isSafeMemAccess(AI, Offset, ArrayOffset, TD->getTypeAllocSize(LIType), - LIType, false, Info); - } else - MarkUnsafe(Info); - } else if (StoreInst *SI = dyn_cast(User)) { - // Store is ok if storing INTO the pointer, not storing the pointer - if (!SI->isVolatile() && SI->getOperand(0) != I) { - const Type *SIType = SI->getOperand(0)->getType(); - isSafeMemAccess(AI, Offset, ArrayOffset, TD->getTypeAllocSize(SIType), - SIType, true, Info); - } else - MarkUnsafe(Info); - } else if (isa(UI)) { - // If one user is DbgInfoIntrinsic then check if all users are - // DbgInfoIntrinsics. - if (OnlyUsedByDbgInfoIntrinsics(I)) { - Info.needsCleanup = true; - return; - } - MarkUnsafe(Info); - } else { - DEBUG(errs() << " Transformation preventing inst: " << *User << '\n'); - MarkUnsafe(Info); - } - if (Info.isUnsafe) return; - } -} +/// isSafeUseOfAllocation - Check if this user is an allowed use for an +/// aggregate allocation. +void SROA::isSafeUseOfAllocation(Instruction *User, AllocaInst *AI, + AllocaInfo &Info) { + if (BitCastInst *C = dyn_cast(User)) + return isSafeUseOfBitCastedAllocation(C, AI, Info); + + if (LoadInst *LI = dyn_cast(User)) + if (!LI->isVolatile()) + return;// Loads (returning a first class aggregrate) are always rewritable + + if (StoreInst *SI = dyn_cast(User)) + if (!SI->isVolatile() && SI->getOperand(0) != AI) + return;// Store is ok if storing INTO the pointer, not storing the pointer + + GetElementPtrInst *GEPI = dyn_cast(User); + if (GEPI == 0) + return MarkUnsafe(Info); -/// isSafeGEP - Check if a GEP instruction can be handled for scalar -/// replacement. It is safe when all the indices are constant, in-bounds -/// references, and when the resulting offset corresponds to an element within -/// the alloca type. The results are flagged in the Info parameter. Upon -/// return, Offset is adjusted as specified by the GEP indices. For the -/// special case of a variable index to a 2-element array, ArrayOffset is set -/// to the array element size. -void SROA::isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI, - uint64_t &Offset, uint64_t &ArrayOffset, - AllocaInfo &Info) { - gep_type_iterator GEPIt = gep_type_begin(GEPI), E = gep_type_end(GEPI); - if (GEPIt == E) - return; + gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); - // The first GEP index must be zero. - if (!isa(GEPIt.getOperand()) || - !cast(GEPIt.getOperand())->isZero()) + // The GEP is not safe to transform if not of the form "GEP , 0, ". + if (I == E || + I.getOperand() != Constant::getNullValue(I.getOperand()->getType())) { return MarkUnsafe(Info); - if (++GEPIt == E) - return; + } + + ++I; + if (I == E) return MarkUnsafe(Info); // ran out of GEP indices?? + bool IsAllZeroIndices = true; + // If the first index is a non-constant index into an array, see if we can // handle it as a special case. - const Type *ArrayEltTy = 0; - if (ArrayOffset == 0 && Offset == 0) { - if (const ArrayType *AT = dyn_cast(*GEPIt)) { - if (!isa(GEPIt.getOperand())) { - uint64_t NumElements = AT->getNumElements(); - - // If this is an array index and the index is not constant, we cannot - // promote... that is unless the array has exactly one or two elements - // in it, in which case we CAN promote it, but we have to canonicalize - // this out if this is the only problem. - if ((NumElements != 1 && NumElements != 2) || !AllUsersAreLoads(GEPI)) - return MarkUnsafe(Info); + if (const ArrayType *AT = dyn_cast(*I)) { + if (!isa(I.getOperand())) { + IsAllZeroIndices = 0; + uint64_t NumElements = AT->getNumElements(); + + // If this is an array index and the index is not constant, we cannot + // promote... that is unless the array has exactly one or two elements in + // it, in which case we CAN promote it, but we have to canonicalize this + // out if this is the only problem. + if ((NumElements == 1 || NumElements == 2) && + AllUsersAreLoads(GEPI)) { Info.needsCleanup = true; - ArrayOffset = TD->getTypeAllocSizeInBits(AT->getElementType()); - ArrayEltTy = AT->getElementType(); - ++GEPIt; + return; // Canonicalization required! } + return MarkUnsafe(Info); } } - + // Walk through the GEP type indices, checking the types that this indexes // into. - for (; GEPIt != E; ++GEPIt) { + for (; I != E; ++I) { // Ignore struct elements, no extra checking needed for these. - if (isa(*GEPIt)) + if (isa(*I)) continue; + + ConstantInt *IdxVal = dyn_cast(I.getOperand()); + if (!IdxVal) return MarkUnsafe(Info); - ConstantInt *IdxVal = dyn_cast(GEPIt.getOperand()); - if (!IdxVal) - return MarkUnsafe(Info); - - if (const ArrayType *AT = dyn_cast(*GEPIt)) { + // Are all indices still zero? + IsAllZeroIndices &= IdxVal->isZero(); + + if (const ArrayType *AT = dyn_cast(*I)) { // This GEP indexes an array. Verify that this is an in-range constant // integer. Specifically, consider A[0][i]. We cannot know that the user // isn't doing invalid things like allowing i to index an out-of-range @@ -494,254 +612,144 @@ // of any accesses into structs where any of the components are variables. if (IdxVal->getZExtValue() >= AT->getNumElements()) return MarkUnsafe(Info); - } else { - const VectorType *VT = dyn_cast(*GEPIt); - assert(VT && "unexpected type in GEP type iterator"); + } else if (const VectorType *VT = dyn_cast(*I)) { if (IdxVal->getZExtValue() >= VT->getNumElements()) return MarkUnsafe(Info); } } - - // All the indices are safe. Now compute the offset due to this GEP and - // check if the alloca has a component element at that offset. - if (ArrayOffset == 0) { - SmallVector Indices(GEPI->op_begin() + 1, GEPI->op_end()); - Offset += TD->getIndexedOffset(GEPI->getPointerOperandType(), - &Indices[0], Indices.size()); - } else { - // Both array elements have the same type, so it suffices to check one of - // them. Copy the GEP indices starting from the array index, but replace - // that variable index with a constant zero. - SmallVector Indices(GEPI->op_begin() + 2, GEPI->op_end()); - Indices[0] = Constant::getNullValue(Type::getInt32Ty(GEPI->getContext())); - const Type *ArrayEltPtr = PointerType::getUnqual(ArrayEltTy); - Offset += TD->getIndexedOffset(ArrayEltPtr, &Indices[0], Indices.size()); - } - if (!TypeHasComponent(AI->getAllocatedType(), Offset, 0)) - MarkUnsafe(Info); -} - -/// isSafeMemAccess - Check if a load/store/memcpy operates on the entire AI -/// alloca or has an offset and size that corresponds to a component element -/// within it. The offset checked here may have been formed from a GEP with a -/// pointer bitcasted to a different type. -void SROA::isSafeMemAccess(AllocaInst *AI, uint64_t Offset, - uint64_t ArrayOffset, uint64_t MemSize, - const Type *MemOpType, bool isStore, - AllocaInfo &Info) { - // Check if this is a load/store of the entire alloca. - if (Offset == 0 && ArrayOffset == 0 && - MemSize == TD->getTypeAllocSize(AI->getAllocatedType())) { - bool UsesAggregateType = (MemOpType == AI->getAllocatedType()); - // This is safe for MemIntrinsics (where MemOpType is 0), integer types - // (which are essentially the same as the MemIntrinsics, especially with - // regard to copying padding between elements), or references using the - // aggregate type of the alloca. - if (!MemOpType || isa(MemOpType) || UsesAggregateType) { - if (!UsesAggregateType) { - if (isStore) - Info.isMemCpyDst = true; - else - Info.isMemCpySrc = true; - } - return; - } - } - // Check if the offset/size correspond to a component within the alloca type. - const Type *T = AI->getAllocatedType(); - if (TypeHasComponent(T, Offset, MemSize) && - (ArrayOffset == 0 || TypeHasComponent(T, Offset + ArrayOffset, MemSize))) - return; - - return MarkUnsafe(Info); + + // If there are any non-simple uses of this getelementptr, make sure to reject + // them. + return isSafeElementUse(GEPI, IsAllZeroIndices, AI, Info); } -/// TypeHasComponent - Return true if T has a component type with the -/// specified offset and size. If Size is zero, do not check the size. -bool SROA::TypeHasComponent(const Type *T, uint64_t Offset, uint64_t Size) { - const Type *EltTy; - uint64_t EltSize; - if (const StructType *ST = dyn_cast(T)) { - const StructLayout *Layout = TD->getStructLayout(ST); - unsigned EltIdx = Layout->getElementContainingOffset(Offset); - EltTy = ST->getContainedType(EltIdx); - EltSize = TD->getTypeAllocSize(EltTy); - Offset -= Layout->getElementOffset(EltIdx); - } else if (const ArrayType *AT = dyn_cast(T)) { - EltTy = AT->getElementType(); - EltSize = TD->getTypeAllocSize(EltTy); - Offset %= EltSize; - } else { - return false; +/// isSafeMemIntrinsicOnAllocation - Check if the specified memory +/// intrinsic can be promoted by SROA. At this point, we know that the operand +/// of the memintrinsic is a pointer to the beginning of the allocation. +void SROA::isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocaInst *AI, + unsigned OpNo, AllocaInfo &Info) { + // If not constant length, give up. + ConstantInt *Length = dyn_cast(MI->getLength()); + if (!Length) return MarkUnsafe(Info); + + // If not the whole aggregate, give up. + if (Length->getZExtValue() != + TD->getTypeAllocSize(AI->getType()->getElementType())) + return MarkUnsafe(Info); + + // We only know about memcpy/memset/memmove. + if (!isa(MI)) + return MarkUnsafe(Info); + + // Otherwise, we can transform it. Determine whether this is a memcpy/set + // into or out of the aggregate. + if (OpNo == 1) + Info.isMemCpyDst = true; + else { + assert(OpNo == 2); + Info.isMemCpySrc = true; } - if (Offset == 0 && (Size == 0 || EltSize == Size)) - return true; - // Check if the component spans multiple elements. - if (Offset + Size > EltSize) - return false; - return TypeHasComponent(EltTy, Offset, Size); } -/// RewriteForScalarRepl - Alloca AI is being split into NewElts, so rewrite -/// the instruction I, which references it, to use the separate elements. -/// Offset indicates the position within AI that is referenced by this -/// instruction. -void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, - SmallVector &NewElts) { - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ) { - Instruction *User = cast(*UI++); +/// isSafeUseOfBitCastedAllocation - Check if all users of this bitcast +/// from an alloca are safe for SROA of that alloca. +void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocaInst *AI, + AllocaInfo &Info) { + for (Value::use_iterator UI = BC->use_begin(), E = BC->use_end(); + UI != E; ++UI) { + if (BitCastInst *BCU = dyn_cast(UI)) { + isSafeUseOfBitCastedAllocation(BCU, AI, Info); + } else if (MemIntrinsic *MI = dyn_cast(UI)) { + isSafeMemIntrinsicOnAllocation(MI, AI, UI.getOperandNo(), Info); + } else if (StoreInst *SI = dyn_cast(UI)) { + if (SI->isVolatile()) + return MarkUnsafe(Info); + + // If storing the entire alloca in one chunk through a bitcasted pointer + // to integer, we can transform it. This happens (for example) when you + // cast a {i32,i32}* to i64* and store through it. This is similar to the + // memcpy case and occurs in various "byval" cases and emulated memcpys. + if (isa(SI->getOperand(0)->getType()) && + TD->getTypeAllocSize(SI->getOperand(0)->getType()) == + TD->getTypeAllocSize(AI->getType()->getElementType())) { + Info.isMemCpyDst = true; + continue; + } + return MarkUnsafe(Info); + } else if (LoadInst *LI = dyn_cast(UI)) { + if (LI->isVolatile()) + return MarkUnsafe(Info); - if (BitCastInst *BC = dyn_cast(User)) { - if (BC->getOperand(0) == AI) - BC->setOperand(0, NewElts[0]); - // If the bitcast type now matches the operand type, it will be removed - // after processing its uses. - RewriteForScalarRepl(BC, AI, Offset, NewElts); - } else if (GetElementPtrInst *GEPI = dyn_cast(User)) { - RewriteGEP(GEPI, AI, Offset, NewElts); - } else if (MemIntrinsic *MI = dyn_cast(User)) { - ConstantInt *Length = dyn_cast(MI->getLength()); - uint64_t MemSize = Length->getZExtValue(); - if (Offset == 0 && - MemSize == TD->getTypeAllocSize(AI->getAllocatedType())) - RewriteMemIntrinUserOfAlloca(MI, I, AI, NewElts); - } else if (LoadInst *LI = dyn_cast(User)) { - const Type *LIType = LI->getType(); - if (LIType == AI->getAllocatedType()) { - // Replace: - // %res = load { i32, i32 }* %alloc - // with: - // %load.0 = load i32* %alloc.0 - // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0 - // %load.1 = load i32* %alloc.1 - // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1 - // (Also works for arrays instead of structs) - Value *Insert = UndefValue::get(LIType); - for (unsigned i = 0, e = NewElts.size(); i != e; ++i) { - Value *Load = new LoadInst(NewElts[i], "load", LI); - Insert = InsertValueInst::Create(Insert, Load, i, "insert", LI); - } - LI->replaceAllUsesWith(Insert); - LI->eraseFromParent(); - } else if (isa(LIType) && - TD->getTypeAllocSize(LIType) == - TD->getTypeAllocSize(AI->getAllocatedType())) { - // If this is a load of the entire alloca to an integer, rewrite it. - RewriteLoadUserOfWholeAlloca(LI, AI, NewElts); + // If loading the entire alloca in one chunk through a bitcasted pointer + // to integer, we can transform it. This happens (for example) when you + // cast a {i32,i32}* to i64* and load through it. This is similar to the + // memcpy case and occurs in various "byval" cases and emulated memcpys. + if (isa(LI->getType()) && + TD->getTypeAllocSize(LI->getType()) == + TD->getTypeAllocSize(AI->getType()->getElementType())) { + Info.isMemCpySrc = true; + continue; } - } else if (StoreInst *SI = dyn_cast(User)) { - Value *Val = SI->getOperand(0); - const Type *SIType = Val->getType(); - if (SIType == AI->getAllocatedType()) { - // Replace: - // store { i32, i32 } %val, { i32, i32 }* %alloc - // with: - // %val.0 = extractvalue { i32, i32 } %val, 0 - // store i32 %val.0, i32* %alloc.0 - // %val.1 = extractvalue { i32, i32 } %val, 1 - // store i32 %val.1, i32* %alloc.1 - // (Also works for arrays instead of structs) - for (unsigned i = 0, e = NewElts.size(); i != e; ++i) { - Value *Extract = ExtractValueInst::Create(Val, i, Val->getName(), SI); - new StoreInst(Extract, NewElts[i], SI); - } - SI->eraseFromParent(); - } else if (isa(SIType) && - TD->getTypeAllocSize(SIType) == - TD->getTypeAllocSize(AI->getAllocatedType())) { - // If this is a store of the entire alloca from an integer, rewrite it. - RewriteStoreUserOfWholeAlloca(SI, AI, NewElts); + return MarkUnsafe(Info); + } else if (isa(UI)) { + // If one user is DbgInfoIntrinsic then check if all users are + // DbgInfoIntrinsics. + if (OnlyUsedByDbgInfoIntrinsics(BC)) { + Info.needsCleanup = true; + return; } + else + MarkUnsafe(Info); } - } - // Delete unused instructions and identity bitcasts. - if (I->use_empty()) - I->eraseFromParent(); - else if (BitCastInst *BC = dyn_cast(I)) { - if (BC->getDestTy() == BC->getSrcTy()) { - BC->replaceAllUsesWith(BC->getOperand(0)); - BC->eraseFromParent(); + else { + return MarkUnsafe(Info); } + if (Info.isUnsafe) return; } } -/// FindElementAndOffset - Return the index of the element containing Offset -/// within the specified type, which must be either a struct or an array. -/// Sets T to the type of the element and Offset to the offset within that -/// element. -unsigned SROA::FindElementAndOffset(const Type *&T, uint64_t &Offset) { - unsigned Idx = 0; - if (const StructType *ST = dyn_cast(T)) { - const StructLayout *Layout = TD->getStructLayout(ST); - Idx = Layout->getElementContainingOffset(Offset); - T = ST->getContainedType(Idx); - Offset -= Layout->getElementOffset(Idx); - } else { - const ArrayType *AT = dyn_cast(T); - assert(AT && "unexpected type for scalar replacement"); - T = AT->getElementType(); - uint64_t EltSize = TD->getTypeAllocSize(T); - Idx = (unsigned)(Offset / EltSize); - Offset -= Idx * EltSize; - } - return Idx; -} - -/// RewriteGEP - Check if this GEP instruction moves the pointer across -/// elements of the alloca that are being split apart, and if so, rewrite -/// the GEP to be relative to the new element. -void SROA::RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset, - SmallVector &NewElts) { - Instruction *Val = GEPI; - - uint64_t OldOffset = Offset; - SmallVector Indices(GEPI->op_begin() + 1, GEPI->op_end()); - Offset += TD->getIndexedOffset(GEPI->getPointerOperandType(), - &Indices[0], Indices.size()); - - const Type *T = AI->getAllocatedType(); - unsigned OldIdx = FindElementAndOffset(T, OldOffset); - if (GEPI->getOperand(0) == AI) - OldIdx = ~0U; // Force the GEP to be rewritten. - - T = AI->getAllocatedType(); - uint64_t EltOffset = Offset; - unsigned Idx = FindElementAndOffset(T, EltOffset); - - // If this GEP moves the pointer across elements of the alloca that are - // being split, then it needs to be rewritten. - if (Idx != OldIdx) { - const Type *i32Ty = Type::getInt32Ty(AI->getContext()); - SmallVector NewArgs; - NewArgs.push_back(Constant::getNullValue(i32Ty)); - while (EltOffset != 0) { - unsigned EltIdx = FindElementAndOffset(T, EltOffset); - NewArgs.push_back(ConstantInt::get(i32Ty, EltIdx)); - } - if (NewArgs.size() > 1) { - Val = GetElementPtrInst::CreateInBounds(NewElts[Idx], NewArgs.begin(), - NewArgs.end(), "", GEPI); - Val->takeName(GEPI); - if (Val->getType() != GEPI->getType()) - Val = new BitCastInst(Val, GEPI->getType(), Val->getNameStr(), GEPI); - } else { - Val = NewElts[Idx]; - // Insert a new bitcast. If the types match, it will be removed after - // handling all of its uses. - Val = new BitCastInst(Val, GEPI->getType(), Val->getNameStr(), GEPI); - Val->takeName(GEPI); +/// RewriteBitCastUserOfAlloca - BCInst (transitively) bitcasts AI, or indexes +/// to its first element. Transform users of the cast to use the new values +/// instead. +void SROA::RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocaInst *AI, + SmallVector &NewElts) { + Value::use_iterator UI = BCInst->use_begin(), UE = BCInst->use_end(); + while (UI != UE) { + Instruction *User = cast(*UI++); + if (BitCastInst *BCU = dyn_cast(User)) { + RewriteBitCastUserOfAlloca(BCU, AI, NewElts); + if (BCU->use_empty()) BCU->eraseFromParent(); + continue; } - GEPI->replaceAllUsesWith(Val); - GEPI->eraseFromParent(); - } + if (MemIntrinsic *MI = dyn_cast(User)) { + // This must be memcpy/memmove/memset of the entire aggregate. + // Split into one per element. + RewriteMemIntrinUserOfAlloca(MI, BCInst, AI, NewElts); + continue; + } + + if (StoreInst *SI = dyn_cast(User)) { + // If this is a store of the entire alloca from an integer, rewrite it. + RewriteStoreUserOfWholeAlloca(SI, AI, NewElts); + continue; + } - RewriteForScalarRepl(Val, AI, Offset, NewElts); + if (LoadInst *LI = dyn_cast(User)) { + // If this is a load of the entire alloca to an integer, rewrite it. + RewriteLoadUserOfWholeAlloca(LI, AI, NewElts); + continue; + } + + // Otherwise it must be some other user of a gep of the first pointer. Just + // leave these alone. + continue; + } } /// RewriteMemIntrinUserOfAlloca - MI is a memcpy/memset/memmove from or to AI. /// Rewrite it to copy or set the elements of the scalarized memory. -void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, +void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, AllocaInst *AI, SmallVector &NewElts) { @@ -753,10 +761,10 @@ LLVMContext &Context = MI->getContext(); unsigned MemAlignment = MI->getAlignment(); if (MemTransferInst *MTI = dyn_cast(MI)) { // memmove/memcopy - if (Inst == MTI->getRawDest()) + if (BCInst == MTI->getRawDest()) OtherPtr = MTI->getRawSource(); else { - assert(Inst == MTI->getRawSource()); + assert(BCInst == MTI->getRawSource()); OtherPtr = MTI->getRawDest(); } } @@ -790,7 +798,7 @@ // Process each element of the aggregate. Value *TheFn = MI->getOperand(0); const Type *BytePtrTy = MI->getRawDest()->getType(); - bool SROADest = MI->getRawDest() == Inst; + bool SROADest = MI->getRawDest() == BCInst; Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext())); @@ -802,9 +810,9 @@ if (OtherPtr) { Value *Idx[2] = { Zero, ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) }; - OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx, Idx + 2, + OtherElt = GetElementPtrInst::Create(OtherPtr, Idx, Idx + 2, OtherPtr->getNameStr()+"."+Twine(i), - MI); + MI); uint64_t EltOffset; const PointerType *OtherPtrTy = cast(OtherPtr->getType()); if (const StructType *ST = @@ -929,9 +937,15 @@ // Extract each element out of the integer according to its structure offset // and store the element value to the individual alloca. Value *SrcVal = SI->getOperand(0); - const Type *AllocaEltTy = AI->getAllocatedType(); + const Type *AllocaEltTy = AI->getType()->getElementType(); uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); + // If this isn't a store of an integer to the whole alloca, it may be a store + // to the first element. Just ignore the store in this case and normal SROA + // will handle it. + if (!isa(SrcVal->getType()) || + TD->getTypeAllocSizeInBits(SrcVal->getType()) != AllocaSizeBits) + return; // Handle tail padding by extending the operand if (TD->getTypeSizeInBits(SrcVal->getType()) != AllocaSizeBits) SrcVal = new ZExtInst(SrcVal, @@ -1045,9 +1059,16 @@ SmallVector &NewElts) { // Extract each element out of the NewElts according to its structure offset // and form the result value. - const Type *AllocaEltTy = AI->getAllocatedType(); + const Type *AllocaEltTy = AI->getType()->getElementType(); uint64_t AllocaSizeBits = TD->getTypeAllocSizeInBits(AllocaEltTy); + // If this isn't a load of the whole alloca to an integer, it may be a load + // of the first element. Just ignore the load in this case and normal SROA + // will handle it. + if (!isa(LI->getType()) || + TD->getTypeAllocSizeInBits(LI->getType()) != AllocaSizeBits) + return; + DEBUG(errs() << "PROMOTING LOAD OF WHOLE ALLOCA: " << *AI << '\n' << *LI << '\n'); @@ -1121,6 +1142,7 @@ LI->eraseFromParent(); } + /// HasPadding - Return true if the specified type has any structure or /// alignment padding, false otherwise. static bool HasPadding(const Type *Ty, const TargetData &TD) { @@ -1170,10 +1192,14 @@ // the users are safe to transform. AllocaInfo Info; - isSafeForScalarRepl(AI, AI, 0, 0, Info); - if (Info.isUnsafe) { - DEBUG(errs() << "Cannot transform: " << *AI << '\n'); - return 0; + for (Value::use_iterator I = AI->use_begin(), E = AI->use_end(); + I != E; ++I) { + isSafeUseOfAllocation(cast(*I), AI, Info); + if (Info.isUnsafe) { + DEBUG(errs() << "Cannot transform: " << *AI << "\n due to user: " + << **I << '\n'); + return 0; + } } // Okay, we know all the users are promotable. If the aggregate is a memcpy @@ -1182,7 +1208,7 @@ // types, but may actually be used. In these cases, we refuse to promote the // struct. if (Info.isMemCpySrc && Info.isMemCpyDst && - HasPadding(AI->getAllocatedType(), *TD)) + HasPadding(AI->getType()->getElementType(), *TD)) return 0; // If we require cleanup, return 1, otherwise return 3. @@ -1219,15 +1245,15 @@ // Insert the new GEP instructions, which are properly indexed. SmallVector Indices(GEPI->op_begin()+1, GEPI->op_end()); Indices[1] = Constant::getNullValue(Type::getInt32Ty(GEPI->getContext())); - Value *ZeroIdx = GetElementPtrInst::CreateInBounds(GEPI->getOperand(0), - Indices.begin(), - Indices.end(), - GEPI->getName()+".0",GEPI); + Value *ZeroIdx = GetElementPtrInst::Create(GEPI->getOperand(0), + Indices.begin(), + Indices.end(), + GEPI->getName()+".0", GEPI); Indices[1] = ConstantInt::get(Type::getInt32Ty(GEPI->getContext()), 1); - Value *OneIdx = GetElementPtrInst::CreateInBounds(GEPI->getOperand(0), - Indices.begin(), - Indices.end(), - GEPI->getName()+".1", GEPI); + Value *OneIdx = GetElementPtrInst::Create(GEPI->getOperand(0), + Indices.begin(), + Indices.end(), + GEPI->getName()+".1", GEPI); // Replace all loads of the variable index GEP with loads from both // indexes and a select. while (!GEPI->use_empty()) { @@ -1238,24 +1264,22 @@ LI->replaceAllUsesWith(R); LI->eraseFromParent(); } + GEPI->eraseFromParent(); } + /// CleanupAllocaUsers - If SROA reported that it can promote the specified /// allocation, but only if cleaned up, perform the cleanups required. -void SROA::CleanupAllocaUsers(Value *V) { +void SROA::CleanupAllocaUsers(AllocaInst *AI) { // At this point, we know that the end result will be SROA'd and promoted, so // we can insert ugly code if required so long as sroa+mem2reg will clean it // up. - for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); + for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E; ) { User *U = *UI++; - if (isa(U)) { - CleanupAllocaUsers(U); - } else if (GetElementPtrInst *GEPI = dyn_cast(U)) { + if (GetElementPtrInst *GEPI = dyn_cast(U)) CleanupGEP(GEPI); - CleanupAllocaUsers(GEPI); - if (GEPI->use_empty()) GEPI->eraseFromParent(); - } else { + else { Instruction *I = cast(U); SmallVector DbgInUses; if (!isa(I) && OnlyUsedByDbgInfoIntrinsics(I, &DbgInUses)) { @@ -1371,7 +1395,7 @@ // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); - uint64_t GEPOffset = TD->getIndexedOffset(GEP->getPointerOperandType(), + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), &Indices[0], Indices.size()); // See if all uses can be converted. if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, SawVec,Offset+GEPOffset, @@ -1433,7 +1457,7 @@ if (GetElementPtrInst *GEP = dyn_cast(User)) { // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); - uint64_t GEPOffset = TD->getIndexedOffset(GEP->getPointerOperandType(), + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), &Indices[0], Indices.size()); ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8); GEP->eraseFromParent(); Modified: llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll?rev=91268&r1=91267&r2=91268&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll Sun Dec 13 23:11:02 2009 @@ -1,68 +0,0 @@ -; RUN: opt < %s -scalarrepl -S | FileCheck %s -; Radar 7441282 - -target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" -target triple = "thumbv7-apple-darwin10" - -%struct.__neon_int16x8x2_t = type { <8 x i16>, <8 x i16> } -%struct.int16x8_t = type { <8 x i16> } -%struct.int16x8x2_t = type { [2 x %struct.int16x8_t] } -%union..0anon = type { %struct.int16x8x2_t } - -define arm_apcscc void @test(<8 x i16> %tmp.0, %struct.int16x8x2_t* %dst) nounwind { -; CHECK: @test -; CHECK-NOT: alloca -; CHECK: "alloca point" -entry: - %tmp_addr = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=3] - %dst_addr = alloca %struct.int16x8x2_t* ; <%struct.int16x8x2_t**> [#uses=2] - %__rv = alloca %union..0anon ; <%union..0anon*> [#uses=2] - %__bx = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] - %__ax = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] - %tmp2 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] - %0 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - %1 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - store <8 x i16> %tmp.0, <8 x i16>* %1 - store %struct.int16x8x2_t* %dst, %struct.int16x8x2_t** %dst_addr - %2 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %3 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %4 = load <8 x i16>* %3, align 16 ; <<8 x i16>> [#uses=1] - store <8 x i16> %4, <8 x i16>* %2, align 16 - %5 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %6 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %7 = load <8 x i16>* %6, align 16 ; <<8 x i16>> [#uses=1] - store <8 x i16> %7, <8 x i16>* %5, align 16 - %8 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %9 = load <8 x i16>* %8, align 16 ; <<8 x i16>> [#uses=2] - %10 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - %11 = load <8 x i16>* %10, align 16 ; <<8 x i16>> [#uses=2] - %12 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] - %13 = bitcast %struct.int16x8x2_t* %12 to %struct.__neon_int16x8x2_t* ; <%struct.__neon_int16x8x2_t*> [#uses=2] - %14 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> ; <<8 x i16>> [#uses=1] - %15 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] - store <8 x i16> %14, <8 x i16>* %15 - %16 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> ; <<8 x i16>> [#uses=1] - %17 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 1 ; <<8 x i16>*> [#uses=1] - store <8 x i16> %16, <8 x i16>* %17 - %18 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] - %19 = bitcast %struct.int16x8x2_t* %0 to i8* ; [#uses=1] - %20 = bitcast %struct.int16x8x2_t* %18 to i8* ; [#uses=1] - call void @llvm.memcpy.i32(i8* %19, i8* %20, i32 32, i32 16) - %tmp21 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; [#uses=1] - %21 = bitcast %struct.int16x8x2_t* %0 to i8* ; [#uses=1] - call void @llvm.memcpy.i32(i8* %tmp21, i8* %21, i32 32, i32 16) - %22 = load %struct.int16x8x2_t** %dst_addr, align 4 ; <%struct.int16x8x2_t*> [#uses=1] - %23 = bitcast %struct.int16x8x2_t* %22 to i8* ; [#uses=1] - %tmp22 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; [#uses=1] - call void @llvm.memcpy.i32(i8* %23, i8* %tmp22, i32 32, i32 16) - br label %return - -; CHECK: store <8 x i16> -; CHECK: store <8 x i16> - -return: ; preds = %entry - ret void -} - -declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind