From dpatel at apple.com Mon Jun 11 10:41:10 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 10:41:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200706111541.l5BFfAXl030164@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.213 -> 1.214 --- Log message: Use DominatorTree instead of ETForest. --- Diffs of the changes: (+16 -16) Verifier.cpp | 32 ++++++++++++++++---------------- 1 files changed, 16 insertions(+), 16 deletions(-) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.213 llvm/lib/VMCore/Verifier.cpp:1.214 --- llvm/lib/VMCore/Verifier.cpp:1.213 Thu Jun 7 01:12:03 2007 +++ llvm/lib/VMCore/Verifier.cpp Mon Jun 11 10:40:48 2007 @@ -76,7 +76,7 @@ VerifierFailureAction action; // What to do if verification fails. Module *Mod; // Module we are verifying right now - ETForest *EF; // ET-Forest, caution can be null! + DominatorTree *DT; // Dominator Tree, caution can be null! std::stringstream msgs; // A stringstream to collect messages /// InstInThisBlock - when verifying a basic block, keep track of all of the @@ -88,20 +88,20 @@ Verifier() : FunctionPass((intptr_t)&ID), Broken(false), RealPass(true), action(AbortProcessAction), - EF(0), msgs( std::ios::app | std::ios::out ) {} + DT(0), msgs( std::ios::app | std::ios::out ) {} Verifier( VerifierFailureAction ctn ) : FunctionPass((intptr_t)&ID), - Broken(false), RealPass(true), action(ctn), EF(0), + Broken(false), RealPass(true), action(ctn), DT(0), msgs( std::ios::app | std::ios::out ) {} Verifier(bool AB ) : FunctionPass((intptr_t)&ID), Broken(false), RealPass(true), - action( AB ? AbortProcessAction : PrintMessageAction), EF(0), + action( AB ? AbortProcessAction : PrintMessageAction), DT(0), msgs( std::ios::app | std::ios::out ) {} - Verifier(ETForest &ef) + Verifier(DominatorTree &dt) : FunctionPass((intptr_t)&ID), Broken(false), RealPass(false), action(PrintMessageAction), - EF(&ef), msgs( std::ios::app | std::ios::out ) {} + DT(&dt), msgs( std::ios::app | std::ios::out ) {} bool doInitialization(Module &M) { @@ -118,7 +118,7 @@ bool runOnFunction(Function &F) { // Get dominator information if we are being run by PassManager - if (RealPass) EF = &getAnalysis(); + if (RealPass) DT = &getAnalysis(); Mod = F.getParent(); @@ -158,7 +158,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); if (RealPass) - AU.addRequired(); + AU.addRequired(); } /// abortIfBroken - If the module is broken and we are supposed to abort on @@ -879,7 +879,7 @@ for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE; ++UI) Assert1(*UI != (User*)&I || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Only PHI nodes may reference their own value!", &I); } @@ -948,7 +948,7 @@ // dominates all of it's predecessors (other than the invoke) or if // the invoke value is only used by a phi in the successor. if (!OpBlock->getSinglePredecessor() && - EF->dominates(&BB->getParent()->getEntryBlock(), BB)) { + DT->dominates(&BB->getParent()->getEntryBlock(), BB)) { // The first case we allow is if the use is a PHI operand in the // normal block, and if that PHI operand corresponds to the invoke's // block. @@ -965,7 +965,7 @@ Bad = false; for (pred_iterator PI = pred_begin(OpBlock), E = pred_end(OpBlock); PI != E; ++PI) { - if (*PI != II->getParent() && !EF->dominates(OpBlock, *PI)) { + if (*PI != II->getParent() && !DT->dominates(OpBlock, *PI)) { Bad = true; break; } @@ -979,20 +979,20 @@ // If they are in the same basic block, make sure that the definition // comes before the use. Assert2(InstsInThisBlock.count(Op) || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } // Definition must dominate use unless use is unreachable! - Assert2(EF->dominates(OpBlock, BB) || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + Assert2(DT->dominates(OpBlock, BB) || + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } else { // PHI nodes are more difficult than other nodes because they actually // "use" the value in the predecessor basic blocks they correspond to. BasicBlock *PredBB = cast(I.getOperand(i+1)); - Assert2(EF->dominates(OpBlock, PredBB) || - !EF->dominates(&BB->getParent()->getEntryBlock(), PredBB), + Assert2(DT->dominates(OpBlock, PredBB) || + !DT->dominates(&BB->getParent()->getEntryBlock(), PredBB), "Instruction does not dominate all uses!", Op, &I); } } else if (isa(I.getOperand(i))) { From resistor at mac.com Mon Jun 11 11:25:39 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 11 Jun 2007 11:25:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706111625.l5BGPdqv031236@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.28 -> 1.29 --- Log message: Handle functions with multiple exit blocks properly. --- Diffs of the changes: (+6 -0) GVNPRE.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.28 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.29 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.28 Sat Jun 9 13:35:31 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Mon Jun 11 11:25:17 2007 @@ -526,6 +526,9 @@ df_begin(PDT.getRootNode()), E = df_end(PDT.getRootNode()); PDI != E; ++PDI) { BasicBlock* BB = PDI->getBlock(); + if (BB == 0) + continue; + DOUT << "Block: " << BB->getName() << "\n"; DOUT << "TMP_GEN: "; dump(generatedTemporaries[BB]); @@ -635,6 +638,9 @@ E = df_end(DT.getRootNode()); DI != E; ++DI) { BasicBlock* BB = DI->getBlock(); + if (BB == 0) + continue; + std::set& new_set = new_sets[BB]; std::set& availOut = availableOut[BB]; std::set& anticIn = anticipatedIn[BB]; From dpatel at apple.com Mon Jun 11 16:18:23 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 16:18:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/LoopSimplify.cpp Message-ID: <200706112118.l5BLINHE005490@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: LoopSimplify.cpp updated: 1.100 -> 1.101 --- Log message: Simplify. Dominator Tree is required so always available. --- Diffs of the changes: (+26 -31) LoopSimplify.cpp | 57 +++++++++++++++++++++++++------------------------------ 1 files changed, 26 insertions(+), 31 deletions(-) Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp diff -u llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.100 llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.101 --- llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.100 Thu Jun 7 20:50:32 2007 +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp Mon Jun 11 16:18:00 2007 @@ -693,9 +693,8 @@ return false; } -/// UpdateDomInfoForRevectoredPreds - This method is used to update the four -/// different kinds of dominator information (immediate dominators, -/// dominator trees, et-forest and dominance frontiers) after a new block has +/// UpdateDomInfoForRevectoredPreds - This method is used to update +/// dominator trees and dominance frontiers after a new block has /// been added to the CFG. /// /// This only supports the case when an existing block (known as "NewBBSucc"), @@ -756,38 +755,34 @@ } } - BasicBlock *NewBBIDom = 0; // Update DominatorTree information if it is active. - if (DominatorTree *DT = getAnalysisToUpdate()) { - // If we don't have ImmediateDominator info around, calculate the idom as - // above. - if (!NewBBIDom) { - unsigned i = 0; - for (i = 0; i < PredBlocks.size(); ++i) - if (DT->dominates(&PredBlocks[i]->getParent()->getEntryBlock(), - PredBlocks[i])) { - NewBBIDom = PredBlocks[i]; - break; - } - assert(i != PredBlocks.size() && "No reachable preds?"); - for (i = i + 1; i < PredBlocks.size(); ++i) { - if (DT->dominates(&PredBlocks[i]->getParent()->getEntryBlock(), - PredBlocks[i])) - NewBBIDom = DT->nearestCommonDominator(NewBBIDom, PredBlocks[i]); - } - assert(NewBBIDom && "No immediate dominator found??"); - } - // Create the new dominator tree node... and set the idom of NewBB. - DomTreeNode *NewBBNode = DT->addNewBlock(NewBB, NewBBIDom); - - // If NewBB strictly dominates other blocks, then it is now the immediate - // dominator of NewBBSucc. Update the dominator tree as appropriate. - if (NewBBDominatesNewBBSucc) { - DomTreeNode *NewBBSuccNode = DT->getNode(NewBBSucc); - DT->changeImmediateDominator(NewBBSuccNode, NewBBNode); + // Find NewBB's immediate dominator and create new dominator tree node for NewBB. + BasicBlock *NewBBIDom = 0; + unsigned i = 0; + for (i = 0; i < PredBlocks.size(); ++i) + if (DT.dominates(&PredBlocks[i]->getParent()->getEntryBlock(), + PredBlocks[i])) { + NewBBIDom = PredBlocks[i]; + break; } + assert(i != PredBlocks.size() && "No reachable preds?"); + for (i = i + 1; i < PredBlocks.size(); ++i) { + if (DT.dominates(&PredBlocks[i]->getParent()->getEntryBlock(), + PredBlocks[i])) + NewBBIDom = DT.nearestCommonDominator(NewBBIDom, PredBlocks[i]); + } + assert(NewBBIDom && "No immediate dominator found??"); + + // Create the new dominator tree node... and set the idom of NewBB. + DomTreeNode *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); + + // If NewBB strictly dominates other blocks, then it is now the immediate + // dominator of NewBBSucc. Update the dominator tree as appropriate. + if (NewBBDominatesNewBBSucc) { + DomTreeNode *NewBBSuccNode = DT.getNode(NewBBSucc); + DT.changeImmediateDominator(NewBBSuccNode, NewBBNode); } // Update dominance frontier information... From dpatel at apple.com Mon Jun 11 16:25:54 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 16:25:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/LoopSimplify.cpp Message-ID: <200706112125.l5BLPsAd005649@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: LoopSimplify.cpp updated: 1.101 -> 1.102 --- Log message: simplify --- Diffs of the changes: (+3 -4) LoopSimplify.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp diff -u llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.101 llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.102 --- llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.101 Mon Jun 11 16:18:00 2007 +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp Mon Jun 11 16:25:31 2007 @@ -708,10 +708,9 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB, std::vector &PredBlocks) { assert(!PredBlocks.empty() && "No predblocks??"); - assert(succ_begin(NewBB) != succ_end(NewBB) && - ++succ_begin(NewBB) == succ_end(NewBB) && - "NewBB should have a single successor!"); - BasicBlock *NewBBSucc = *succ_begin(NewBB); + assert(NewBB->getTerminator()->getNumSuccessors() == 1 + && "NewBB should have a single successor!"); + BasicBlock *NewBBSucc = NewBB->getTerminator()->getSuccessor(0); DominatorTree &DT = getAnalysis(); // The newly inserted basic block will dominate existing basic blocks iff the From dpatel at apple.com Mon Jun 11 16:45:53 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 16:45:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/LoopSimplify.cpp Message-ID: <200706112145.l5BLjrDw006042@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: LoopSimplify.cpp updated: 1.102 -> 1.103 --- Log message: Simplify. --- Diffs of the changes: (+2 -4) LoopSimplify.cpp | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp diff -u llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.102 llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.103 --- llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.102 Mon Jun 11 16:25:31 2007 +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp Mon Jun 11 16:45:31 2007 @@ -761,15 +761,13 @@ BasicBlock *NewBBIDom = 0; unsigned i = 0; for (i = 0; i < PredBlocks.size(); ++i) - if (DT.dominates(&PredBlocks[i]->getParent()->getEntryBlock(), - PredBlocks[i])) { + if (DT.isReachableFromEntry(PredBlocks[i])) { NewBBIDom = PredBlocks[i]; break; } assert(i != PredBlocks.size() && "No reachable preds?"); for (i = i + 1; i < PredBlocks.size(); ++i) { - if (DT.dominates(&PredBlocks[i]->getParent()->getEntryBlock(), - PredBlocks[i])) + if (DT.isReachableFromEntry(PredBlocks[i])) NewBBIDom = DT.nearestCommonDominator(NewBBIDom, PredBlocks[i]); } assert(NewBBIDom && "No immediate dominator found??"); From evan.cheng at apple.com Mon Jun 11 17:26:44 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 11 Jun 2007 17:26:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706112226.l5BMQiW1006823@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.43 -> 1.44 --- Log message: Restructure code to reduce ifcvt compile time cost. --- Diffs of the changes: (+193 -155) IfConversion.cpp | 348 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 193 insertions(+), 155 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.43 llvm/lib/CodeGen/IfConversion.cpp:1.44 --- llvm/lib/CodeGen/IfConversion.cpp:1.43 Sat Jun 9 19:19:17 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Mon Jun 11 17:26:22 2007 @@ -55,17 +55,13 @@ namespace { class IfConverter : public MachineFunctionPass { enum BBICKind { - ICNotAnalyzed, // BB has not been analyzed. - ICReAnalyze, // BB must be re-analyzed. ICNotClassfied, // BB data valid, but not classified. ICSimple, // BB is entry of an one split, no rejoin sub-CFG. ICSimpleFalse, // Same as ICSimple, but on the false path. ICTriangle, // BB is entry of a triangle sub-CFG. ICTriangleFalse, // Same as ICTriangle, but on the false path. ICTriangleFRev, // Same as ICTriangleFalse, but false path rev condition. - ICDiamond, // BB is entry of a diamond sub-CFG. - ICChild, // BB is part of the sub-CFG that'll be predicated. - ICDead // BB cannot be if-converted again. + ICDiamond // BB is entry of a diamond sub-CFG. }; /// BBInfo - One per MachineBasicBlock, this is used to cache the result @@ -76,29 +72,41 @@ /// instruction can clobber the 'would-be' predicate. /// /// Kind - Type of block. See BBICKind. - /// NonPredSize - Number of non-predicated instructions. - /// IsAnalyzable - True if AnalyzeBranch() returns false. - /// ModifyPredicate - True if BB would modify the predicate (e.g. has + /// IsDone - True if BB is not to be considered for ifcvt. + /// IsBeingAnalyzed - True if BB is currently being analyzed. + /// IsAnalyzed - True if BB has been analyzed (info is still valid). + /// IsEnqueued - True if BB has been enqueued to be ifcvt'ed. + /// IsBrAnalyzable - True if AnalyzeBranch() returns false. + /// HasFallThrough - True if BB may fallthrough to the following BB. + /// IsUnpredicable - True if BB is known to be unpredicable. + /// ClobbersPredicate- True if BB would modify the predicate (e.g. has /// cmp, call, etc.) + /// NonPredSize - Number of non-predicated instructions. /// BB - Corresponding MachineBasicBlock. /// TrueBB / FalseBB- See AnalyzeBranch(). /// BrCond - Conditions for end of block conditional branches. /// Predicate - Predicate used in the BB. struct BBInfo { BBICKind Kind; + bool IsDone : 1; + bool IsBeingAnalyzed : 1; + bool IsAnalyzed : 1; + bool IsEnqueued : 1; + bool IsBrAnalyzable : 1; + bool HasFallThrough : 1; + bool IsUnpredicable : 1; + bool ClobbersPred : 1; unsigned NonPredSize; - bool IsAnalyzable; - bool HasFallThrough; - bool ModifyPredicate; MachineBasicBlock *BB; MachineBasicBlock *TrueBB; MachineBasicBlock *FalseBB; MachineBasicBlock *TailBB; std::vector BrCond; std::vector Predicate; - BBInfo() : Kind(ICNotAnalyzed), NonPredSize(0), - IsAnalyzable(false), HasFallThrough(false), - ModifyPredicate(false), + BBInfo() : Kind(ICNotClassfied), IsDone(false), IsBeingAnalyzed(false), + IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false), + HasFallThrough(false), IsUnpredicable(false), + ClobbersPred(false), NonPredSize(0), BB(0), TrueBB(0), FalseBB(0), TailBB(0) {} }; @@ -127,7 +135,7 @@ bool FalseBranch = false) const; bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI) const; void ScanInstructions(BBInfo &BBI); - void AnalyzeBlock(MachineBasicBlock *BB); + BBInfo &AnalyzeBlock(MachineBasicBlock *BB); bool FeasibilityAnalysis(BBInfo &BBI, std::vector &Cond, bool isTriangle = false, bool RevBranch = false); bool AttemptRestructuring(BBInfo &BBI); @@ -145,7 +153,7 @@ // blockAlwaysFallThrough - Block ends without a terminator. bool blockAlwaysFallThrough(BBInfo &BBI) const { - return BBI.IsAnalyzable && BBI.TrueBB == NULL; + return BBI.IsBrAnalyzable && BBI.TrueBB == NULL; } // IfcvtCandidateCmp - Used to sort if-conversion candidates. @@ -192,15 +200,15 @@ BBInfo &BBI = *Candidates.back(); Candidates.pop_back(); + // If the block has been evicted out of the queue or it has already been + // marked dead (due to it being predicated), then skip it. + if (!BBI.IsEnqueued || BBI.IsDone) + continue; + bool RetVal = false; switch (BBI.Kind) { default: assert(false && "Unexpected!"); break; - case ICReAnalyze: - // One or more of 'children' have been modified, abort! - case ICDead: - // Block has been already been if-converted, abort! - break; case ICSimple: case ICSimpleFalse: { bool isFalse = BBI.Kind == ICSimpleFalse; @@ -304,6 +312,9 @@ /// ValidSimple - Returns true if the 'true' block (along with its /// predecessor) forms a valid simple shape for ifcvt. bool IfConverter::ValidSimple(BBInfo &TrueBBI) const { + if (TrueBBI.IsBeingAnalyzed) + return false; + return !blockAlwaysFallThrough(TrueBBI) && TrueBBI.BrCond.size() == 0 && TrueBBI.BB->pred_size() == 1; } @@ -312,6 +323,9 @@ /// with their common predecessor) forms a valid triangle shape for ifcvt. bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, bool FalseBranch) const { + if (TrueBBI.IsBeingAnalyzed) + return false; + if (TrueBBI.BB->pred_size() != 1) return false; @@ -328,6 +342,9 @@ /// ValidDiamond - Returns true if the 'true' and 'false' blocks (along /// with their common predecessor) forms a valid diamond shape for ifcvt. bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI) const { + if (TrueBBI.IsBeingAnalyzed || FalseBBI.IsBeingAnalyzed) + return false; + MachineBasicBlock *TT = TrueBBI.TrueBB; MachineBasicBlock *FT = FalseBBI.TrueBB; @@ -337,7 +354,7 @@ FT = getNextBlock(FalseBBI.BB); if (TT != FT) return false; - if (TT == NULL && (TrueBBI.IsAnalyzable || FalseBBI.IsAnalyzable)) + if (TT == NULL && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable)) return false; // FIXME: Allow false block to have an early exit? return (TrueBBI.BB->pred_size() == 1 && @@ -345,59 +362,155 @@ !TrueBBI.FalseBB && !FalseBBI.FalseBB); } +/// ScanInstructions - Scan all the instructions in the block to determine if +/// the block is predicable. In most cases, that means all the instructions +/// in the block has M_PREDICABLE flag. Also checks if the block contains any +/// instruction which can clobber a predicate (e.g. condition code register). +/// If so, the block is not predicable unless it's the last instruction. +void IfConverter::ScanInstructions(BBInfo &BBI) { + if (BBI.IsDone) + return; + + // First analyze the end of BB branches. + BBI.TrueBB = BBI.FalseBB; + BBI.BrCond.clear(); + BBI.IsBrAnalyzable = + !TII->AnalyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond); + BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == NULL; + + if (BBI.BrCond.size()) { + // No false branch. This BB must end with a conditional branch and a + // fallthrough. + if (!BBI.FalseBB) + BBI.FalseBB = findFalseBlock(BBI.BB, BBI.TrueBB); + assert(BBI.FalseBB && "Expected to find the fallthrough block!"); + } + + // Then scan all the instructions. + BBI.NonPredSize = 0; + BBI.ClobbersPred = false; + bool SeenCondBr = false; + for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); + I != E; ++I) { + const TargetInstrDescriptor *TID = I->getInstrDescriptor(); + bool isPredicated = TII->isPredicated(I); + bool isCondBr = BBI.IsBrAnalyzable && + (TID->Flags & M_BRANCH_FLAG) != 0 && (TID->Flags & M_BARRIER_FLAG) == 0; + + if (!isPredicated && !isCondBr) + BBI.NonPredSize++; + + if (BBI.ClobbersPred && !isPredicated) { + // Predicate modification instruction should end the block (except for + // already predicated instructions and end of block branches). + if (isCondBr) { + SeenCondBr = true; + + // Conditional branches is not predicable. But it may be eliminated. + continue; + } + + // Predicate may have been modified, the subsequent (currently) + // unpredocated instructions cannot be correctly predicated. + BBI.IsUnpredicable = true; + return; + } + + if (TID->Flags & M_CLOBBERS_PRED) + BBI.ClobbersPred = true; + + if (!I->isPredicable()) { + BBI.IsUnpredicable = true; + return; + } + } +} + +/// FeasibilityAnalysis - Determine if the block is a suitable candidate to be +/// predicated by the specified predicate. +bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, + std::vector &Pred, + bool isTriangle, bool RevBranch) { + // Forget about it if it's unpredicable. + if (BBI.IsUnpredicable) + return false; + + // If the block is dead, or it is going to be the entry block of a sub-CFG + // that will be if-converted, then it cannot be predicated. + if (BBI.IsDone || BBI.IsEnqueued) + return false; + + // Check predication threshold. + if (BBI.NonPredSize == 0 || BBI.NonPredSize > TLI->getIfCvtBlockSizeLimit()) + return false; + + // If it is already predicated, check if its predicate subsumes the new + // predicate. + if (BBI.Predicate.size() && !TII->SubsumesPredicate(BBI.Predicate, Pred)) + return false; + + if (BBI.BrCond.size()) { + if (!isTriangle) + return false; + + // Test predicate subsumsion. + std::vector RevPred(Pred); + std::vector Cond(BBI.BrCond); + if (RevBranch) { + if (TII->ReverseBranchCondition(Cond)) + return false; + } + if (TII->ReverseBranchCondition(RevPred) || + !TII->SubsumesPredicate(Cond, RevPred)) + return false; + } + + return true; +} + /// AnalyzeBlock - Analyze the structure of the sub-CFG starting from /// the specified block. Record its successors and whether it looks like an /// if-conversion candidate. -void IfConverter::AnalyzeBlock(MachineBasicBlock *BB) { +IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB) { BBInfo &BBI = BBAnalysis[BB->getNumber()]; - if (BBI.Kind == ICReAnalyze) { - BBI.BrCond.clear(); - BBI.TrueBB = BBI.FalseBB = NULL; - } else { - if (BBI.Kind != ICNotAnalyzed) - return; // Already analyzed. - BBI.BB = BB; - BBI.NonPredSize = std::distance(BB->begin(), BB->end()); - } + if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) + return BBI; - // Look for 'root' of a simple (non-nested) triangle or diamond. + BBI.BB = BB; + BBI.IsBeingAnalyzed = true; BBI.Kind = ICNotClassfied; - BBI.IsAnalyzable = - !TII->AnalyzeBranch(*BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond); - BBI.HasFallThrough = BBI.IsAnalyzable && BBI.FalseBB == NULL; - // Unanalyable or ends with fallthrough or unconditional branch. - if (!BBI.IsAnalyzable || BBI.BrCond.size() == 0) - return; - // Do not ifcvt if either path is a back edge to the entry block. - if (BBI.TrueBB == BB || BBI.FalseBB == BB) - return; - AnalyzeBlock(BBI.TrueBB); - BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; + ScanInstructions(BBI); - // No false branch. This BB must end with a conditional branch and a - // fallthrough. - if (!BBI.FalseBB) - BBI.FalseBB = findFalseBlock(BB, BBI.TrueBB); - assert(BBI.FalseBB && "Expected to find the fallthrough block!"); + // Unanalyable or ends with fallthrough or unconditional branch. + if (!BBI.IsBrAnalyzable || BBI.BrCond.size() == 0) { + BBI.IsBeingAnalyzed = false; + BBI.IsAnalyzed = true; + return BBI; + } - AnalyzeBlock(BBI.FalseBB); - BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; + // Do not ifcvt if either path is a back edge to the entry block. + if (BBI.TrueBB == BB || BBI.FalseBB == BB) { + BBI.IsBeingAnalyzed = false; + BBI.IsAnalyzed = true; + return BBI; + } - // If both paths are dead, then forget about it. - if (TrueBBI.Kind == ICDead && FalseBBI.Kind == ICDead) { - BBI.Kind = ICDead; - return; + BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB); + BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB); + + if (TrueBBI.IsDone && FalseBBI.IsDone) { + BBI.IsBeingAnalyzed = false; + BBI.IsAnalyzed = true; + return BBI; } - // Look for more opportunities to if-convert a triangle. Try to restructure - // the CFG to form a triangle with the 'false' path. std::vector RevCond(BBI.BrCond); bool CanRevCond = !TII->ReverseBranchCondition(RevCond); if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI) && - !(TrueBBI.ModifyPredicate && FalseBBI.ModifyPredicate) && + !(TrueBBI.ClobbersPred && FalseBBI.ClobbersPred) && FeasibilityAnalysis(TrueBBI, BBI.BrCond) && FeasibilityAnalysis(FalseBBI, RevCond)) { // Diamond: @@ -409,7 +522,6 @@ // TailBB // Note TailBB can be empty. BBI.Kind = ICDiamond; - TrueBBI.Kind = FalseBBI.Kind = ICChild; BBI.TailBB = TrueBBI.TrueBB; } else { // FIXME: Consider duplicating if BB is small. @@ -423,7 +535,6 @@ // | / // FBB BBI.Kind = ICTriangle; - TrueBBI.Kind = ICChild; } else if (ValidSimple(TrueBBI) && FeasibilityAnalysis(TrueBBI, BBI.BrCond)) { // Simple (split, no rejoin): @@ -434,93 +545,24 @@ // | // FBB BBI.Kind = ICSimple; - TrueBBI.Kind = ICChild; } else if (CanRevCond) { // Try the other path... if (ValidTriangle(FalseBBI, TrueBBI) && FeasibilityAnalysis(FalseBBI, RevCond, true)) { BBI.Kind = ICTriangleFalse; - FalseBBI.Kind = ICChild; } else if (ValidTriangle(FalseBBI, TrueBBI, true) && FeasibilityAnalysis(FalseBBI, RevCond, true, true)) { BBI.Kind = ICTriangleFRev; - FalseBBI.Kind = ICChild; } else if (ValidSimple(FalseBBI) && FeasibilityAnalysis(FalseBBI, RevCond)) { BBI.Kind = ICSimpleFalse; - FalseBBI.Kind = ICChild; - } - } - } - return; -} - -/// FeasibilityAnalysis - Determine if the block is predicable. In most -/// cases, that means all the instructions in the block has M_PREDICABLE flag. -/// Also checks if the block contains any instruction which can clobber a -/// predicate (e.g. condition code register). If so, the block is not -/// predicable unless it's the last instruction. -bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, - std::vector &Pred, - bool isTriangle, bool RevBranch) { - // If the block is dead, or it is going to be the entry block of a sub-CFG - // that will be if-converted, then it cannot be predicated. - if (BBI.Kind != ICNotAnalyzed && - BBI.Kind != ICNotClassfied && - BBI.Kind != ICChild) - return false; - - // Check predication threshold. - if (BBI.NonPredSize == 0 || BBI.NonPredSize > TLI->getIfCvtBlockSizeLimit()) - return false; - - // If it is already predicated, check if its predicate subsumes the new - // predicate. - if (BBI.Predicate.size() && !TII->SubsumesPredicate(BBI.Predicate, Pred)) - return false; - - bool SeenPredMod = false; - bool SeenCondBr = false; - for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); - I != E; ++I) { - const TargetInstrDescriptor *TID = I->getInstrDescriptor(); - if (SeenPredMod) { - // Predicate modification instruction should end the block (except for - // already predicated instructions and end of block branches). - if (!TII->isPredicated(I)) { - // This is the 'true' block of a triangle, i.e. its 'true' block is - // the same as the 'false' block of the entry. So false positive - // is ok. - if (isTriangle && !SeenCondBr && BBI.IsAnalyzable && - (TID->Flags & M_BRANCH_FLAG) != 0 && - (TID->Flags & M_BARRIER_FLAG) == 0) { - // This is the first conditional branch, test predicate subsumsion. - std::vector RevPred(Pred); - std::vector Cond(BBI.BrCond); - if (RevBranch) { - if (TII->ReverseBranchCondition(Cond)) - return false; - } - if (TII->ReverseBranchCondition(RevPred) || - !TII->SubsumesPredicate(Cond, RevPred)) - return false; - SeenCondBr = true; - continue; // Conditional branches is not predicable. - } - return false; } } - - if (TID->Flags & M_CLOBBERS_PRED) { - BBI.ModifyPredicate = true; - SeenPredMod = true; - } - - if (!I->isPredicable()) - return false; } - return true; + BBI.IsBeingAnalyzed = false; + BBI.IsAnalyzed = true; + return BBI; } /// AttemptRestructuring - Restructure the sub-CFG rooted in the given block to @@ -561,8 +603,7 @@ for (idf_ext_iterator I=idf_ext_begin(Roots[i],Visited), E = idf_ext_end(Roots[i], Visited); I != E; ++I) { MachineBasicBlock *BB = *I; - AnalyzeBlock(BB); - BBInfo &BBI = BBAnalysis[BB->getNumber()]; + BBInfo &BBI = AnalyzeBlock(BB); switch (BBI.Kind) { case ICSimple: case ICSimpleFalse: @@ -602,8 +643,10 @@ for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) { BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()]; - if (PBBI.Kind == ICNotClassfied) - PBBI.Kind = ICReAnalyze; + if (!PBBI.IsDone && PBBI.Kind == ICNotClassfied) { + assert(PBBI.IsEnqueued && "Unexpected"); + PBBI.IsAnalyzed = false; + } } } @@ -672,12 +715,10 @@ RemoveExtraEdges(BBI); // Update block info. BB can be iteratively if-converted. - if (IterIfcvt) - BBI.Kind = ICReAnalyze; - else - BBI.Kind = ICDead; + if (!IterIfcvt) + BBI.IsDone = true; ReTryPreds(BBI.BB); - CvtBBI->Kind = ICDead; + CvtBBI->IsDone = true; // FIXME: Must maintain LiveIns. return true; @@ -703,7 +744,8 @@ if (PBB == BBI.BB) continue; BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; - PBBI.Kind = ICReAnalyze; + if (PBBI.IsEnqueued) + PBBI.IsEnqueued = false; } } std::swap(CvtBBI, NextBBI); @@ -751,14 +793,12 @@ RemoveExtraEdges(BBI); // Update block info. BB can be iteratively if-converted. - if (IterIfcvt) - BBI.Kind = ICReAnalyze; - else - BBI.Kind = ICDead; + if (!IterIfcvt) + BBI.IsDone = true; ReTryPreds(BBI.BB); - CvtBBI->Kind = ICDead; + CvtBBI->IsDone = true; if (FalseBBDead) - NextBBI->Kind = ICDead; + NextBBI->IsDone = true; // FIXME: Must maintain LiveIns. return true; @@ -822,8 +862,8 @@ bool NeedBr1 = !BBI1->TrueBB && BBI1->BB->succ_size(); bool NeedBr2 = !BBI2->TrueBB && BBI2->BB->succ_size(); - if ((TrueBBI.ModifyPredicate && !FalseBBI.ModifyPredicate) || - (!TrueBBI.ModifyPredicate && !FalseBBI.ModifyPredicate && + if ((TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred) || + (!TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred && NeedBr1 && !NeedBr2)) { std::swap(BBI1, BBI2); std::swap(Cond1, Cond2); @@ -878,15 +918,13 @@ CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); BBInfo TailBBI = BBAnalysis[BBI.TailBB->getNumber()]; MergeBlocks(*CvtBBI, TailBBI); - TailBBI.Kind = ICDead; + TailBBI.IsDone = true; } RemoveExtraEdges(BBI); // Update block info. - BBI.Kind = ICDead; - TrueBBI.Kind = ICDead; - FalseBBI.Kind = ICDead; + BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true; // FIXME: Must maintain LiveIns. return true; @@ -953,7 +991,7 @@ ToBBI.NonPredSize += FromBBI.NonPredSize; FromBBI.NonPredSize = 0; - ToBBI.ModifyPredicate |= FromBBI.ModifyPredicate; + ToBBI.ClobbersPred |= FromBBI.ClobbersPred; ToBBI.HasFallThrough = FromBBI.HasFallThrough; std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), From lauro.venancio at gmail.com Mon Jun 11 18:16:39 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Mon, 11 Jun 2007 18:16:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IntrinsicLowering.cpp Message-ID: <200706112316.l5BNGdNn007716@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IntrinsicLowering.cpp updated: 1.86 -> 1.87 --- Log message: Fix a typo in bswap lowering. --- Diffs of the changes: (+1 -1) IntrinsicLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.86 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.87 --- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.86 Fri Jun 1 23:10:33 2007 +++ llvm/lib/CodeGen/IntrinsicLowering.cpp Mon Jun 11 18:16:16 2007 @@ -144,7 +144,7 @@ "bswap.and2", IP); Tmp4 = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.or1", IP); Tmp2 = BinaryOperator::createOr(Tmp2, Tmp1, "bswap.or2", IP); - V = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.i32", IP); + V = BinaryOperator::createOr(Tmp4, Tmp2, "bswap.i32", IP); break; } case 64: { From dpatel at apple.com Mon Jun 11 18:31:45 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 18:31:45 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200706112331.l5BNVjri008035@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.100 -> 1.101 --- Log message: Add and use DominatorTreeBase::findNearestCommonDominator(). --- Diffs of the changes: (+4 -0) Dominators.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.100 llvm/include/llvm/Analysis/Dominators.h:1.101 --- llvm/include/llvm/Analysis/Dominators.h:1.100 Fri Jun 8 12:59:02 2007 +++ llvm/include/llvm/Analysis/Dominators.h Mon Jun 11 18:31:22 2007 @@ -234,6 +234,10 @@ return dominates(getNode(A), getNode(B)); } + /// findNearestCommonDominator - Find nearest common dominator basic block + /// for basic block A and B. If there is no such block then return NULL. + BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B); + // dominates - Return true if A dominates B. This performs the // special checks necessary if A and B are in the same basic block. bool dominates(Instruction *A, Instruction *B); From dpatel at apple.com Mon Jun 11 18:31:52 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 18:31:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/LoopSimplify.cpp Message-ID: <200706112331.l5BNVqnS008070@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: LoopSimplify.cpp updated: 1.103 -> 1.104 --- Log message: Add and use DominatorTreeBase::findNearestCommonDominator(). --- Diffs of the changes: (+1 -1) LoopSimplify.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp diff -u llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.103 llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.104 --- llvm/lib/Transforms/Utils/LoopSimplify.cpp:1.103 Mon Jun 11 16:45:31 2007 +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp Mon Jun 11 18:31:22 2007 @@ -768,7 +768,7 @@ assert(i != PredBlocks.size() && "No reachable preds?"); for (i = i + 1; i < PredBlocks.size(); ++i) { if (DT.isReachableFromEntry(PredBlocks[i])) - NewBBIDom = DT.nearestCommonDominator(NewBBIDom, PredBlocks[i]); + NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]); } assert(NewBBIDom && "No immediate dominator found??"); From dpatel at apple.com Mon Jun 11 18:31:54 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 18:31:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706112331.l5BNVsuL008075@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.109 -> 1.110 --- Log message: Add and use DominatorTreeBase::findNearestCommonDominator(). --- Diffs of the changes: (+45 -0) Dominators.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 45 insertions(+) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.109 llvm/lib/VMCore/Dominators.cpp:1.110 --- llvm/lib/VMCore/Dominators.cpp:1.109 Thu Jun 7 20:50:32 2007 +++ llvm/lib/VMCore/Dominators.cpp Mon Jun 11 18:31:22 2007 @@ -23,6 +23,7 @@ #include "llvm/Instructions.h" #include "llvm/Support/Streams.h" #include +#include using namespace llvm; namespace llvm { @@ -369,6 +370,50 @@ RootNode = 0; } +/// findNearestCommonDominator - Find nearest common dominator basic block +/// for basic block A and B. If there is no such block then return NULL. +BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, BasicBlock *B) { + + assert (!isPostDominator() && "This is not implemented for post dominators"); + assert (A->getParent() == B->getParent() && "Two blocks are not in same function"); + + // If either A or B is a entry block then it is nearest common dominator. + BasicBlock &Entry = A->getParent()->getEntryBlock(); + if (A == &Entry || B == &Entry) + return &Entry; + + // If A and B are same then A is nearest common dominator. + DomTreeNode *NodeA = getNode(A); + if (A != 0 && A == B) + return A; + + DomTreeNode *NodeB = getNode(B); + + // Collect NodeA dominators set. + std::set NodeADoms; + NodeADoms.insert(NodeA); + DomTreeNode *IDomA = NodeA->getIDom(); + while(IDomA) { + NodeADoms.insert(IDomA); + IDomA = IDomA->getIDom(); + } + + // If B dominates A then B is nearest common dominator. + if (NodeADoms.count(NodeB) != 0) + return B; + + // Walk NodeB immediate dominators chain and find common dominator node. + DomTreeNode *IDomB = NodeB->getIDom(); + while(IDomB) { + if (NodeADoms.count(IDomB) != 0) + return IDomB->getBlock(); + + IDomB = IDomB->getIDom(); + } + + return NULL; +} + void DomTreeNode::setIDom(DomTreeNode *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { From dpatel at apple.com Mon Jun 11 19:15:03 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:15:03 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200706120015.l5C0F3K0009116@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.101 -> 1.102 --- Log message: Maintain DFS number in DomTreeNode itself. This means now ETNodes are not useful anymore. --- Diffs of the changes: (+17 -3) Dominators.h | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.101 llvm/include/llvm/Analysis/Dominators.h:1.102 --- llvm/include/llvm/Analysis/Dominators.h:1.101 Mon Jun 11 18:31:22 2007 +++ llvm/include/llvm/Analysis/Dominators.h Mon Jun 11 19:14:41 2007 @@ -65,6 +65,8 @@ DomTreeNode *IDom; ETNode *ETN; std::vector Children; + int DFSNumIn, DFSNumOut; + public: typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; @@ -80,12 +82,22 @@ inline const std::vector &getChildren() const { return Children; } inline DomTreeNode(BasicBlock *BB, DomTreeNode *iDom, ETNode *E) - : TheBB(BB), IDom(iDom), ETN(E) { + : TheBB(BB), IDom(iDom), ETN(E), DFSNumIn(-1), DFSNumOut(-1) { if (IDom) ETN->setFather(IDom->getETNode()); } inline DomTreeNode *addChild(DomTreeNode *C) { Children.push_back(C); return C; } void setIDom(DomTreeNode *NewIDom); + + // Return true if this node is dominated by other. Use this only if DFS info is valid. + bool DominatedBy(const DomTreeNode *other) const { + return this->DFSNumIn >= other->DFSNumIn && + this->DFSNumOut <= other->DFSNumOut; + } + + /// assignDFSNumber - Assign In and Out numbers while walking dominator tree + /// in dfs order. + void assignDFSNumber(int num); }; //===----------------------------------------------------------------------===// @@ -214,14 +226,16 @@ ETNode *NodeB = B->getETNode(); if (DFSInfoValid) - return NodeB->DominatedBy(NodeA); + return B->DominatedBy(A); + //return NodeB->DominatedBy(NodeA); // If we end up with too many slow queries, just update the // DFS numbers on the theory that we are going to keep querying. SlowQueries++; if (SlowQueries > 32) { updateDFSNumbers(); - return NodeB->DominatedBy(NodeA); + return B->DominatedBy(A); + //return NodeB->DominatedBy(NodeA); } //return NodeB->DominatedBySlow(NodeA); return dominatedBySlowTreeWalk(A, B); From dpatel at apple.com Mon Jun 11 19:15:09 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:15:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706120015.l5C0F9Wq009122@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.110 -> 1.111 --- Log message: Maintain DFS number in DomTreeNode itself. This means now ETNodes are not useful anymore. --- Diffs of the changes: (+37 -3) Dominators.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 files changed, 37 insertions(+), 3 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.110 llvm/lib/VMCore/Dominators.cpp:1.111 --- llvm/lib/VMCore/Dominators.cpp:1.110 Mon Jun 11 18:31:22 2007 +++ llvm/lib/VMCore/Dominators.cpp Mon Jun 11 19:14:41 2007 @@ -319,9 +319,11 @@ BasicBlock *BB = *I; DomTreeNode *BBNode = getNode(BB); if (BBNode) { - ETNode *ETN = BBNode->getETNode(); - if (ETN && !ETN->hasFather()) - ETN->assignDFSNumber(dfsnum); + if (!BBNode->getIDom()) + BBNode->assignDFSNumber(dfsnum); + //ETNode *ETN = BBNode->getETNode(); + //if (ETN && !ETN->hasFather()) + // ETN->assignDFSNumber(dfsnum); } } SlowQueries = 0; @@ -414,6 +416,38 @@ return NULL; } +/// assignDFSNumber - Assign In and Out numbers while walking dominator tree +/// in dfs order. +void DomTreeNode::assignDFSNumber(int num) { + std::vector workStack; + std::set visitedNodes; + + workStack.push_back(this); + visitedNodes.insert(this); + this->DFSNumIn = num++; + + while (!workStack.empty()) { + DomTreeNode *Node = workStack.back(); + + bool visitChild = false; + for (std::vector::iterator DI = Node->begin(), + E = Node->end(); DI != E && !visitChild; ++DI) { + DomTreeNode *Child = *DI; + if (visitedNodes.count(Child) == 0) { + visitChild = true; + Child->DFSNumIn = num++; + workStack.push_back(Child); + visitedNodes.insert(Child); + } + } + if (!visitChild) { + // If we reach here means all children are visited + Node->DFSNumOut = num++; + workStack.pop_back(); + } + } +} + void DomTreeNode::setIDom(DomTreeNode *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { From dpatel at apple.com Mon Jun 11 19:36:00 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:36:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706120036.l5C0a0xm009541@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.111 -> 1.112 --- Log message: Check immediate dominators first while searching for nearset common dominator. Fix 80 col violations. --- Diffs of the changes: (+18 -6) Dominators.cpp | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.111 llvm/lib/VMCore/Dominators.cpp:1.112 --- llvm/lib/VMCore/Dominators.cpp:1.111 Mon Jun 11 19:14:41 2007 +++ llvm/lib/VMCore/Dominators.cpp Mon Jun 11 19:35:38 2007 @@ -23,7 +23,6 @@ #include "llvm/Instructions.h" #include "llvm/Support/Streams.h" #include -#include using namespace llvm; namespace llvm { @@ -363,7 +362,8 @@ // DominatorTreeBase::reset - Free all of the tree node memory. // void DominatorTreeBase::reset() { - for (DomTreeNodeMapType::iterator I = DomTreeNodes.begin(), E = DomTreeNodes.end(); I != E; ++I) + for (DomTreeNodeMapType::iterator I = DomTreeNodes.begin(), + E = DomTreeNodes.end(); I != E; ++I) delete I->second; DomTreeNodes.clear(); IDoms.clear(); @@ -374,10 +374,13 @@ /// findNearestCommonDominator - Find nearest common dominator basic block /// for basic block A and B. If there is no such block then return NULL. -BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, BasicBlock *B) { +BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, + BasicBlock *B) { - assert (!isPostDominator() && "This is not implemented for post dominators"); - assert (A->getParent() == B->getParent() && "Two blocks are not in same function"); + assert (!isPostDominator() + && "This is not implemented for post dominators"); + assert (A->getParent() == B->getParent() + && "Two blocks are not in same function"); // If either A or B is a entry block then it is nearest common dominator. BasicBlock &Entry = A->getParent()->getEntryBlock(); @@ -391,8 +394,17 @@ DomTreeNode *NodeB = getNode(B); + // If B immediately dominates A then B is nearest common dominator. + if (NodeA->getIDom() == NodeB) + return B; + + // If A immediately dominates B then A is nearest common dominator. + if (NodeB->getIDom() == NodeA) + return A; + // Collect NodeA dominators set. - std::set NodeADoms; + // SmallPtrSet NodeADoms; + std::set NodeADoms; NodeADoms.insert(NodeA); DomTreeNode *IDomA = NodeA->getIDom(); while(IDomA) { From dpatel at apple.com Mon Jun 11 19:41:14 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:41:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706120041.l5C0fEUM009639@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.112 -> 1.113 --- Log message: Use SmallPtrSet instaed of std::set --- Diffs of the changes: (+1 -2) Dominators.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.112 llvm/lib/VMCore/Dominators.cpp:1.113 --- llvm/lib/VMCore/Dominators.cpp:1.112 Mon Jun 11 19:35:38 2007 +++ llvm/lib/VMCore/Dominators.cpp Mon Jun 11 19:40:51 2007 @@ -403,8 +403,7 @@ return A; // Collect NodeA dominators set. - // SmallPtrSet NodeADoms; - std::set NodeADoms; + SmallPtrSet NodeADoms; NodeADoms.insert(NodeA); DomTreeNode *IDomA = NodeA->getIDom(); while(IDomA) { From llvm at cs.uiuc.edu Mon Jun 11 19:48:28 2007 From: llvm at cs.uiuc.edu (LLVM) Date: Mon, 11 Jun 2007 19:48:28 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/ Message-ID: <200706120048.l5C0mS81009767@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: --- Log message: Directory /var/cvs/llvm/llvm/test/Transforms/GVNPRE added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From resistor at mac.com Mon Jun 11 19:49:55 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 11 Jun 2007 19:49:55 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/basic.ll dg.exp Message-ID: <200706120049.l5C0ntao009808@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: basic.ll added (r1.1) dg.exp added (r1.1) --- Log message: Add a GVN-PRE basic regression test. --- Diffs of the changes: (+41 -0) basic.ll | 38 ++++++++++++++++++++++++++++++++++++++ dg.exp | 3 +++ 2 files changed, 41 insertions(+) Index: llvm/test/Transforms/GVNPRE/basic.ll diff -c /dev/null llvm/test/Transforms/GVNPRE/basic.ll:1.1 *** /dev/null Mon Jun 11 19:49:43 2007 --- llvm/test/Transforms/GVNPRE/basic.ll Mon Jun 11 19:49:33 2007 *************** *** 0 **** --- 1,38 ---- + ; RUN: llvm-as | opt -gvnpre | llvm-dis | not grep {%t3 =} + ; RUN: llvm-as | opt -gvnpre | llvm-dis | not grep {%t9 =} + + define i32 @main() { + block1: + %t1 = bitcast i32 0 to i32 ; [#uses=5] + br label %block2 + + block2: ; preds = %block6, %block1 + %t2 = phi i32 [ %t1, %block1 ], [ %t3, %block6 ] ; [#uses=3] + %t3 = add i32 %t2, 1 ; [#uses=5] + br i1 false, label %block3, label %block7 + + block3: ; preds = %block2 + br i1 true, label %block4, label %block5 + + block4: ; preds = %block3 + %t4 = add i32 %t2, %t3 ; [#uses=1] + %t5 = bitcast i32 %t4 to i32 ; [#uses=1] + %t6 = add i32 %t1, %t5 ; [#uses=0] + br label %block6 + + block5: ; preds = %block3 + %t7 = add i32 %t3, 1 ; [#uses=1] + br label %block6 + + block6: ; preds = %block5, %block4 + %t8 = phi i32 [ %t1, %block4 ], [ %t7, %block5 ] ; [#uses=1] + %t9 = add i32 %t2, %t3 ; [#uses=2] + %t10 = add i32 %t9, %t8 ; [#uses=0] + %t11 = bitcast i32 12 to i32 ; [#uses=1] + %t12 = add i32 %t9, %t11 ; [#uses=1] + %t13 = add i32 %t12, %t3 ; [#uses=0] + br label %block2 + + block7: ; preds = %block2 + ret i32 %t1 + } Index: llvm/test/Transforms/GVNPRE/dg.exp diff -c /dev/null llvm/test/Transforms/GVNPRE/dg.exp:1.1 *** /dev/null Mon Jun 11 19:49:55 2007 --- llvm/test/Transforms/GVNPRE/dg.exp Mon Jun 11 19:49:33 2007 *************** *** 0 **** --- 1,3 ---- + load_lib llvm.exp + + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] From resistor at mac.com Mon Jun 11 19:51:09 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 11 Jun 2007 19:51:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706120051.l5C0p9r3009847@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.29 -> 1.30 --- Log message: Fix a few more bugs, including an instance of walking in reverse topological rather than topological order. This fixes a testcase extracted from llvm-test. --- Diffs of the changes: (+49 -31) GVNPRE.cpp | 80 +++++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 49 insertions(+), 31 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.29 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.30 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.29 Mon Jun 11 11:25:17 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Mon Jun 11 19:50:47 2007 @@ -43,14 +43,21 @@ if (BinaryOperator* rightBO = dyn_cast(right)) return cmpBinaryOperator(leftBO, rightBO); else - return left < right; + if (isa(right)) { + return false; + } else { + return true; + } } else if (CmpInst* leftCmp = dyn_cast(left)) { if (CmpInst* rightCmp = dyn_cast(right)) return cmpComparison(leftCmp, rightCmp); else - return left < right; + return true; } else { - return left < right; + if (isa(right) || isa(right)) + return false; + else + return left < right; } } @@ -92,7 +99,7 @@ typedef std::map ValueTable; ValueTable VN; std::set MS; - std::set createdExpressions; + std::vector createdExpressions; virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -109,9 +116,9 @@ Value* find_leader(std::set& vals, Value* v); Value* phi_translate(std::set& set, - Value* V, BasicBlock* pred); - void phi_translate_set(std::set& anticIn, BasicBlock* B, - std::set& out); + Value* V, BasicBlock* pred, BasicBlock* succ); + void phi_translate_set(std::set& anticIn, BasicBlock* pred, + BasicBlock* succ, std::set& out); void topo_sort(std::set& set, std::vector& vec); @@ -162,7 +169,7 @@ } Value* GVNPRE::phi_translate(std::set& set, - Value* V, BasicBlock* pred) { + Value* V, BasicBlock* pred, BasicBlock* succ) { if (V == 0) return 0; @@ -170,7 +177,7 @@ Value* newOp1 = isa(BO->getOperand(0)) ? phi_translate(set, find_leader(set, BO->getOperand(0)), - pred) + pred, succ) : BO->getOperand(0); if (newOp1 == 0) return 0; @@ -178,7 +185,7 @@ Value* newOp2 = isa(BO->getOperand(1)) ? phi_translate(set, find_leader(set, BO->getOperand(1)), - pred) + pred, succ) : BO->getOperand(1); if (newOp2 == 0) return 0; @@ -192,7 +199,7 @@ nextValueNumber++; if (!find_leader(set, newVal)) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; - createdExpressions.insert(newVal); + createdExpressions.push_back(newVal); return newVal; } else { ValueTable::iterator I = VN.find(newVal); @@ -208,13 +215,13 @@ } } } else if (PHINode* P = dyn_cast(V)) { - if (P->getParent() == pred->getTerminator()->getSuccessor(0)) + if (P->getParent() == succ) return P->getIncomingValueForBlock(pred); } else if (CmpInst* C = dyn_cast(V)) { Value* newOp1 = isa(C->getOperand(0)) ? phi_translate(set, find_leader(set, C->getOperand(0)), - pred) + pred, succ) : C->getOperand(0); if (newOp1 == 0) return 0; @@ -222,7 +229,7 @@ Value* newOp2 = isa(C->getOperand(1)) ? phi_translate(set, find_leader(set, C->getOperand(1)), - pred) + pred, succ) : C->getOperand(1); if (newOp2 == 0) return 0; @@ -237,7 +244,7 @@ nextValueNumber++; if (!find_leader(set, newVal)) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; - createdExpressions.insert(newVal); + createdExpressions.push_back(newVal); return newVal; } else { ValueTable::iterator I = VN.find(newVal); @@ -257,11 +264,12 @@ return V; } -void GVNPRE::phi_translate_set(std::set& anticIn, BasicBlock* B, - std::set& out) { +void GVNPRE::phi_translate_set(std::set& anticIn, + BasicBlock* pred, BasicBlock* succ, + std::set& out) { for (std::set::iterator I = anticIn.begin(), E = anticIn.end(); I != E; ++I) { - Value* V = phi_translate(anticIn, *I, B); + Value* V = phi_translate(anticIn, *I, pred, succ); if (V != 0) out.insert(V); } @@ -544,10 +552,12 @@ if (BB->getTerminator()->getNumSuccessors() == 1) { if (visited.find(BB->getTerminator()->getSuccessor(0)) == visited.end()) - phi_translate_set(MS, BB, anticOut); + phi_translate_set(MS, BB, BB->getTerminator()->getSuccessor(0), + anticOut); else - phi_translate_set( - anticipatedIn[BB->getTerminator()->getSuccessor(0)], BB, anticOut); + phi_translate_set(anticipatedIn[BB->getTerminator()->getSuccessor(0)], + BB, BB->getTerminator()->getSuccessor(0), + anticOut); } else if (BB->getTerminator()->getNumSuccessors() > 1) { BasicBlock* first = BB->getTerminator()->getSuccessor(0); anticOut.insert(anticipatedIn[first].begin(), @@ -673,9 +683,8 @@ dump_unique(anticIn); DOUT << "\n"; - while (!workList.empty()) { - Value* e = workList.back(); - workList.pop_back(); + for (unsigned i = 0; i < workList.size(); ++i) { + Value* e = workList[i]; if (isa(e) || isa(e)) { if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0) @@ -687,7 +696,7 @@ for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { - Value *e2 = phi_translate(anticIn, e, *PI); + Value *e2 = phi_translate(anticIn, e, *PI, BB); Value *e3 = find_leader(availableOut[*PI], e2); if (e3 == 0) { @@ -720,13 +729,21 @@ Value* s1 = 0; if (isa(U->getOperand(0))) - s1 = find_leader(availableOut[*PI], U->getOperand(0)); + s1 = find_leader(availableOut[*PI], + phi_translate(availableOut[*PI], + U->getOperand(0), + *PI, BB) + ); else s1 = U->getOperand(0); Value* s2 = 0; if (isa(U->getOperand(1))) - s2 = find_leader(availableOut[*PI], U->getOperand(1)); + s2 = find_leader(availableOut[*PI], + phi_translate(availableOut[*PI], + U->getOperand(1), + *PI, BB) + ); else s2 = U->getOperand(1); @@ -842,7 +859,6 @@ while (!replace.empty()) { std::pair rep = replace.back(); replace.pop_back(); - rep.first->replaceAllUsesWith(rep.second); } @@ -851,9 +867,11 @@ (*I)->eraseFromParent(); // Phase 4: Cleanup - for (std::set::iterator I = createdExpressions.begin(), - E = createdExpressions.end(); I != E; ++I) { - delete *I; + while (!createdExpressions.empty()) { + Instruction* I = createdExpressions.back(); + createdExpressions.pop_back(); + + delete I; } return false; From dpatel at apple.com Mon Jun 11 19:55:03 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:55:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706120055.l5C0t3Lf009939@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.113 -> 1.114 --- Log message: Break DominatorTree from ETNode. Remove unused PostETForest. --- Diffs of the changes: (+3 -19) Dominators.cpp | 22 +++------------------- 1 files changed, 3 insertions(+), 19 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.113 llvm/lib/VMCore/Dominators.cpp:1.114 --- llvm/lib/VMCore/Dominators.cpp:1.113 Mon Jun 11 19:40:51 2007 +++ llvm/lib/VMCore/Dominators.cpp Mon Jun 11 19:54:38 2007 @@ -235,9 +235,7 @@ BasicBlock* Root = Roots[0]; // Add a node for the root... - ETNode *ERoot = new ETNode(Root); - ETNodes[Root] = ERoot; - DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0, ERoot); + DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0); Vertex.push_back(0); @@ -292,9 +290,7 @@ // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode - ETNode *ET = new ETNode(I); - ETNodes[I] = ET; - DomTreeNode *C = new DomTreeNode(I, IDomNode, ET); + DomTreeNode *C = new DomTreeNode(I, IDomNode); DomTreeNodes[I] = C; BBNode = IDomNode->addChild(C); } @@ -320,9 +316,6 @@ if (BBNode) { if (!BBNode->getIDom()) BBNode->assignDFSNumber(dfsnum); - //ETNode *ETN = BBNode->getETNode(); - //if (ETN && !ETN->hasFather()) - // ETN->assignDFSNumber(dfsnum); } } SlowQueries = 0; @@ -472,13 +465,6 @@ // Switch to new dominator IDom = NewIDom; IDom->Children.push_back(this); - - if (!ETN->hasFather()) - ETN->setFather(IDom->getETNode()); - else if (ETN->getFather()->getData() != IDom->getBlock()) { - ETN->Split(); - ETN->setFather(IDom->getETNode()); - } } } @@ -493,9 +479,7 @@ // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode - ETNode *ET = new ETNode(BB); - ETNodes[BB] = ET; - DomTreeNode *C = new DomTreeNode(BB, IDomNode, ET); + DomTreeNode *C = new DomTreeNode(BB, IDomNode); DomTreeNodes[BB] = C; return BBNode = IDomNode->addChild(C); } From dpatel at apple.com Mon Jun 11 19:55:10 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:55:10 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h PostDominators.h Message-ID: <200706120055.l5C0tA3f009947@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.102 -> 1.103 PostDominators.h updated: 1.23 -> 1.24 --- Log message: Break DominatorTree from ETNode. Remove unused PostETForest. --- Diffs of the changes: (+4 -54) Dominators.h | 34 ++++------------------------------ PostDominators.h | 24 ------------------------ 2 files changed, 4 insertions(+), 54 deletions(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.102 llvm/include/llvm/Analysis/Dominators.h:1.103 --- llvm/include/llvm/Analysis/Dominators.h:1.102 Mon Jun 11 19:14:41 2007 +++ llvm/include/llvm/Analysis/Dominators.h Mon Jun 11 19:54:38 2007 @@ -63,7 +63,6 @@ class DomTreeNode { BasicBlock *TheBB; DomTreeNode *IDom; - ETNode *ETN; std::vector Children; int DFSNumIn, DFSNumOut; @@ -78,14 +77,10 @@ inline BasicBlock *getBlock() const { return TheBB; } inline DomTreeNode *getIDom() const { return IDom; } - inline ETNode *getETNode() const { return ETN; } inline const std::vector &getChildren() const { return Children; } - inline DomTreeNode(BasicBlock *BB, DomTreeNode *iDom, ETNode *E) - : TheBB(BB), IDom(iDom), ETN(E), DFSNumIn(-1), DFSNumOut(-1) { - if (IDom) - ETN->setFather(IDom->getETNode()); - } + inline DomTreeNode(BasicBlock *BB, DomTreeNode *iDom) + : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { } inline DomTreeNode *addChild(DomTreeNode *C) { Children.push_back(C); return C; } void setIDom(DomTreeNode *NewIDom); @@ -111,9 +106,6 @@ DomTreeNodeMapType DomTreeNodes; DomTreeNode *RootNode; - typedef std::map ETMapType; - ETMapType ETNodes; - bool DFSInfoValid; unsigned int SlowQueries; // Information record used during immediate dominators computation. @@ -197,17 +189,6 @@ void updateDFSNumbers(); - /// Return the nearest common dominator of A and B. - BasicBlock *nearestCommonDominator(BasicBlock *A, BasicBlock *B) const { - ETNode *NodeA = getNode(A)->getETNode(); - ETNode *NodeB = getNode(B)->getETNode(); - - ETNode *Common = NodeA->NCA(NodeB); - if (!Common) - return NULL; - return Common->getData(); - } - /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. const bool isReachableFromEntry(BasicBlock* A); @@ -222,12 +203,8 @@ if (A == 0 || B == 0) return false; - ETNode *NodeA = A->getETNode(); - ETNode *NodeB = B->getETNode(); - if (DFSInfoValid) return B->DominatedBy(A); - //return NodeB->DominatedBy(NodeA); // If we end up with too many slow queries, just update the // DFS numbers on the theory that we are going to keep querying. @@ -235,9 +212,8 @@ if (SlowQueries > 32) { updateDFSNumbers(); return B->DominatedBy(A); - //return NodeB->DominatedBy(NodeA); } - //return NodeB->DominatedBySlow(NodeA); + return dominatedBySlowTreeWalk(A, B); } @@ -268,10 +244,8 @@ DomTreeNode *IDomNode = getNode(DomBB); assert(IDomNode && "Not immediate dominator specified for block!"); DFSInfoValid = false; - ETNode *E = new ETNode(BB); - ETNodes[BB] = E; return DomTreeNodes[BB] = - IDomNode->addChild(new DomTreeNode(BB, IDomNode, E)); + IDomNode->addChild(new DomTreeNode(BB, IDomNode)); } /// changeImmediateDominator - This method is used to update the dominator Index: llvm/include/llvm/Analysis/PostDominators.h diff -u llvm/include/llvm/Analysis/PostDominators.h:1.23 llvm/include/llvm/Analysis/PostDominators.h:1.24 --- llvm/include/llvm/Analysis/PostDominators.h:1.23 Sun Jun 3 19:32:21 2007 +++ llvm/include/llvm/Analysis/PostDominators.h Mon Jun 11 19:54:38 2007 @@ -51,30 +51,6 @@ }; -/// PostETForest Class - Concrete subclass of ETForestBase that is used to -/// compute a forwards post-dominator ET-Forest. -struct PostETForest : public ETForestBase { - static char ID; - PostETForest() : ETForestBase((intptr_t)&ID, true) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } - - virtual bool runOnFunction(Function &F) { - reset(); // Reset from the last time we were run... - PostDominatorTree &DT = getAnalysis(); - Roots = DT.getRoots(); - calculate(DT); - return false; - } - - void calculate(const PostDominatorTree &DT); - ETNode *getNodeForBlock(BasicBlock *BB); -}; - - /// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is /// used to compute the a post-dominance frontier. /// From dpatel at apple.com Mon Jun 11 19:55:10 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 11 Jun 2007 19:55:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PostDominators.cpp Message-ID: <200706120055.l5C0tA8E009952@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PostDominators.cpp updated: 1.73 -> 1.74 --- Log message: Break DominatorTree from ETNode. Remove unused PostETForest. --- Diffs of the changes: (+5 -78) PostDominators.cpp | 83 +++-------------------------------------------------- 1 files changed, 5 insertions(+), 78 deletions(-) Index: llvm/lib/Analysis/PostDominators.cpp diff -u llvm/lib/Analysis/PostDominators.cpp:1.73 llvm/lib/Analysis/PostDominators.cpp:1.74 --- llvm/lib/Analysis/PostDominators.cpp:1.73 Thu Jun 7 12:47:21 2007 +++ llvm/lib/Analysis/PostDominators.cpp Mon Jun 11 19:54:38 2007 @@ -24,7 +24,6 @@ char PostDominatorTree::ID = 0; char PostDominanceFrontier::ID = 0; -char PostETForest::ID = 0; static RegisterPass F("postdomtree", "Post-Dominator Tree Construction", true); @@ -165,9 +164,7 @@ // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) // which postdominates all real exits if there are multiple exit blocks. BasicBlock *Root = Roots.size() == 1 ? Roots[0] : 0; - ETNode *ERoot = new ETNode(Root); - ETNodes[Root] = ERoot; - DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0, ERoot); + DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0); // Loop over all of the reachable blocks in the function... for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) @@ -179,9 +176,7 @@ // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode - ETNode *ET = new ETNode(I); - ETNodes[I] = ET; - DomTreeNode *C = new DomTreeNode(I, IPDomNode, ET); + DomTreeNode *C = new DomTreeNode(I, IPDomNode); DomTreeNodes[I] = C; BBNode = IPDomNode->addChild(C); } @@ -197,8 +192,8 @@ for (unsigned i = 0, e = Roots.size(); i != e; ++i) for (idf_iterator I = idf_begin(Roots[i]), E = idf_end(Roots[i]); I != E; ++I) { - if (!getNodeForBlock(*I)->getETNode()->hasFather()) - getNodeForBlock(*I)->getETNode()->assignDFSNumber(dfsnum); + if (!getNodeForBlock(*I)->getIDom()) + getNodeForBlock(*I)->assignDFSNumber(dfsnum); } DFSInfoValid = true; } @@ -215,80 +210,12 @@ // Add a new tree node for this BasicBlock, and link it as a child of // IDomNode - ETNode *ET = new ETNode(BB); - ETNodes[BB] = ET; - DomTreeNode *C = new DomTreeNode(BB, IPDomNode, ET); + DomTreeNode *C = new DomTreeNode(BB, IPDomNode); DomTreeNodes[BB] = C; return BBNode = IPDomNode->addChild(C); } //===----------------------------------------------------------------------===// -// PostETForest Implementation -//===----------------------------------------------------------------------===// - -static RegisterPass -G("postetforest", "Post-ET-Forest Construction", true); - -ETNode *PostETForest::getNodeForBlock(BasicBlock *BB) { - ETNode *&BBNode = Nodes[BB]; - if (BBNode) return BBNode; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate dominator. - DomTreeNode *node = getAnalysis().getNode(BB); - - // If we are unreachable, we may not have an immediate dominator. - if (!node) - return 0; - else if (!node->getIDom()) - return BBNode = new ETNode(BB); - else { - ETNode *IDomNode = getNodeForBlock(node->getIDom()->getBlock()); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - BBNode = new ETNode(BB); - BBNode->setFather(IDomNode); - return BBNode; - } -} - -void PostETForest::calculate(const PostDominatorTree &DT) { - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - Nodes[Roots[i]] = new ETNode(Roots[i]); // Add a node for the root - - // Iterate over all nodes in inverse depth first order. - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - for (idf_iterator I = idf_begin(Roots[i]), - E = idf_end(Roots[i]); I != E; ++I) { - BasicBlock *BB = *I; - ETNode *&BBNode = Nodes[BB]; - if (!BBNode) { - ETNode *IDomNode = NULL; - DomTreeNode *node = DT.getNode(BB); - if (node && node->getIDom()) - IDomNode = getNodeForBlock(node->getIDom()->getBlock()); - - // Add a new ETNode for this BasicBlock, and set it's parent - // to it's immediate dominator. - BBNode = new ETNode(BB); - if (IDomNode) - BBNode->setFather(IDomNode); - } - } - - int dfsnum = 0; - // Iterate over all nodes in depth first order... - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - for (idf_iterator I = idf_begin(Roots[i]), - E = idf_end(Roots[i]); I != E; ++I) { - if (!getNodeForBlock(*I)->hasFather()) - getNodeForBlock(*I)->assignDFSNumber(dfsnum); - } - DFSInfoValid = true; -} - -//===----------------------------------------------------------------------===// // PostDominanceFrontier Implementation //===----------------------------------------------------------------------===// From resistor at mac.com Mon Jun 11 23:41:11 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 11 Jun 2007 23:41:11 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/basic.ll Message-ID: <200706120441.l5C4fBlL014340@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: basic.ll updated: 1.1 -> 1.2 --- Log message: Make the run line for this test correct. Thanks to Chris for spotting it. --- Diffs of the changes: (+2 -2) basic.ll | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/test/Transforms/GVNPRE/basic.ll diff -u llvm/test/Transforms/GVNPRE/basic.ll:1.1 llvm/test/Transforms/GVNPRE/basic.ll:1.2 --- llvm/test/Transforms/GVNPRE/basic.ll:1.1 Mon Jun 11 19:49:33 2007 +++ llvm/test/Transforms/GVNPRE/basic.ll Mon Jun 11 23:40:48 2007 @@ -1,5 +1,5 @@ -; RUN: llvm-as | opt -gvnpre | llvm-dis | not grep {%t3 =} -; RUN: llvm-as | opt -gvnpre | llvm-dis | not grep {%t9 =} +; RUN: llvm-as < %s | opt -gvnpre | llvm-dis | not grep {%t3 =} +; RUN: llvm-as < %s | opt -gvnpre | llvm-dis | not grep {%t9 =} define i32 @main() { block1: From dpatel at apple.com Tue Jun 12 00:49:53 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 12 Jun 2007 00:49:53 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200706120549.l5C5nr52015597@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.103 -> 1.104 --- Log message: Make DFS number manipulation methods private. --- Diffs of the changes: (+5 -1) Dominators.h | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.103 llvm/include/llvm/Analysis/Dominators.h:1.104 --- llvm/include/llvm/Analysis/Dominators.h:1.103 Mon Jun 11 19:54:38 2007 +++ llvm/include/llvm/Analysis/Dominators.h Tue Jun 12 00:49:31 2007 @@ -59,13 +59,16 @@ //===----------------------------------------------------------------------===// // DomTreeNode - Dominator Tree Node - +class DominatorTreeBase; +class PostDominatorTree; class DomTreeNode { BasicBlock *TheBB; DomTreeNode *IDom; std::vector Children; int DFSNumIn, DFSNumOut; + friend class DominatorTreeBase; + friend class PostDominatorTree; public: typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; @@ -84,6 +87,7 @@ inline DomTreeNode *addChild(DomTreeNode *C) { Children.push_back(C); return C; } void setIDom(DomTreeNode *NewIDom); +private: // Return true if this node is dominated by other. Use this only if DFS info is valid. bool DominatedBy(const DomTreeNode *other) const { return this->DFSNumIn >= other->DFSNumIn && From dalej at apple.com Tue Jun 12 11:50:59 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 12 Jun 2007 11:50:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200706121650.l5CGoxxk009816@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: CodeGenPrepare.cpp updated: 1.11 -> 1.12 --- Log message: Sink CmpInst's to their uses to reduce register pressure. --- Diffs of the changes: (+61 -3) CodeGenPrepare.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 61 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp diff -u llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp:1.11 llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp:1.12 --- llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp:1.11 Mon May 7 20:01:04 2007 +++ llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Jun 12 11:50:17 2007 @@ -317,7 +317,7 @@ /// OptimizeNoopCopyExpression - If the specified cast instruction is a noop /// copy (e.g. it's casting from one pointer type to another, int->uint, or /// int->sbyte on PPC), sink it into user blocks to reduce the number of virtual -/// registers that must be created and coallesced. +/// registers that must be created and coalesced. /// /// Return true if any changes are made. static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI){ @@ -348,7 +348,7 @@ BasicBlock *DefBB = CI->getParent(); /// InsertedCasts - Only insert a cast in each block once. - std::map InsertedCasts; + DenseMap InsertedCasts; bool MadeChange = false; for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); @@ -383,7 +383,7 @@ MadeChange = true; } - // Replace a use of the cast with a use of the new casat. + // Replace a use of the cast with a use of the new cast. TheUse = InsertedCast; } @@ -394,6 +394,62 @@ return MadeChange; } +/// OptimizeCmpExpression - sink the given CmpInst into user blocks to reduce +/// the number of virtual registers that must be created and coalesced. This is +/// a clear win except on targets with multiple condition code registers (powerPC), +/// where it might lose; some adjustment may be wanted there. +/// +/// Return true if any changes are made. +static bool OptimizeCmpExpression(CmpInst *CI){ + + BasicBlock *DefBB = CI->getParent(); + + /// InsertedCmp - Only insert a cmp in each block once. + DenseMap InsertedCmps; + + bool MadeChange = false; + for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); + UI != E; ) { + Use &TheUse = UI.getUse(); + Instruction *User = cast(*UI); + + // Preincrement use iterator so we don't invalidate it. + ++UI; + + // Don't bother for PHI nodes. + if (isa(User)) + continue; + + // Figure out which BB this cmp is used in. + BasicBlock *UserBB = User->getParent(); + + // If this user is in the same block as the cmp, don't change the cmp. + if (UserBB == DefBB) continue; + + // If we have already inserted a cmp into this block, use it. + CmpInst *&InsertedCmp = InsertedCmps[UserBB]; + + if (!InsertedCmp) { + BasicBlock::iterator InsertPt = UserBB->begin(); + while (isa(InsertPt)) ++InsertPt; + + InsertedCmp = + CmpInst::create(CI->getOpcode(), CI->getPredicate(), CI->getOperand(0), + CI->getOperand(1), "", InsertPt); + MadeChange = true; + } + + // Replace a use of the cmp with a use of the new cmp. + TheUse = InsertedCmp; + } + + // If we removed all uses, nuke the cmp. + if (CI->use_empty()) + CI->eraseFromParent(); + + return MadeChange; +} + /// EraseDeadInstructions - Erase any dead instructions static void EraseDeadInstructions(Value *V) { Instruction *I = dyn_cast(V); @@ -894,6 +950,8 @@ if (TLI) MadeChange |= OptimizeNoopCopyExpression(CI, *TLI); + } else if (CmpInst *CI = dyn_cast(I)) { + MadeChange |= OptimizeCmpExpression(CI); } else if (LoadInst *LI = dyn_cast(I)) { if (TLI) MadeChange |= OptimizeLoadStoreInst(I, I->getOperand(0), LI->getType(), From resistor at mac.com Tue Jun 12 11:56:22 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 12 Jun 2007 11:56:22 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/2007-06-12-NoExit.ll Message-ID: <200706121656.l5CGuMvC009963@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: 2007-06-12-NoExit.ll added (r1.1) --- Log message: Testcase where GVNPRE crashes on functions with no exit nodes. --- Diffs of the changes: (+9 -0) 2007-06-12-NoExit.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Transforms/GVNPRE/2007-06-12-NoExit.ll diff -c /dev/null llvm/test/Transforms/GVNPRE/2007-06-12-NoExit.ll:1.1 *** /dev/null Tue Jun 12 11:56:10 2007 --- llvm/test/Transforms/GVNPRE/2007-06-12-NoExit.ll Tue Jun 12 11:56:00 2007 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | opt -gvnpre | llvm-dis + + define void @_Z4sortI3Lit16LessThan_defaultIS0_EEvPT_iT0_() { + entry: + br label %cond_false + + cond_false: ; preds = %cond_false, %entry + br label %cond_false + } From resistor at mac.com Tue Jun 12 11:58:13 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 12 Jun 2007 11:58:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706121658.l5CGwDhG010037@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.30 -> 1.31 --- Log message: Refactor some code, and fix test/Transforms/GVNPRE/2007-06-12-NoExit.ll by being more careful when using post-dominator information. --- Diffs of the changes: (+69 -47) GVNPRE.cpp | 116 ++++++++++++++++++++++++++++++++++++------------------------- 1 files changed, 69 insertions(+), 47 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.30 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.31 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.30 Mon Jun 11 19:50:47 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Tue Jun 12 11:57:50 2007 @@ -131,6 +131,9 @@ std::set& currTemps, std::set& currAvail, std::map > availOut); + void cleanup(); + void elimination(std::map >& availOut); }; @@ -482,6 +485,61 @@ } } +void GVNPRE::elimination(std::map >& availableOut) { + DOUT << "\n\nPhase 3: Elimination\n\n"; + + std::vector > replace; + std::vector erase; + + DominatorTree& DT = getAnalysis(); + + for (df_iterator DI = df_begin(DT.getRootNode()), + E = df_end(DT.getRootNode()); DI != E; ++DI) { + BasicBlock* BB = DI->getBlock(); + + DOUT << "Block: " << BB->getName() << "\n"; + dump_unique(availableOut[BB]); + DOUT << "\n\n"; + + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); + BI != BE; ++BI) { + + if (isa(BI) || isa(BI)) { + Value *leader = find_leader(availableOut[BB], BI); + + if (leader != 0) + if (Instruction* Instr = dyn_cast(leader)) + if (Instr->getParent() != 0 && Instr != BI) { + replace.push_back(std::make_pair(BI, leader)); + erase.push_back(BI); + ++NumEliminated; + } + } + } + } + + while (!replace.empty()) { + std::pair rep = replace.back(); + replace.pop_back(); + rep.first->replaceAllUsesWith(rep.second); + } + + for (std::vector::iterator I = erase.begin(), E = erase.end(); + I != E; ++I) + (*I)->eraseFromParent(); +} + + +void GVNPRE::cleanup() { + while (!createdExpressions.empty()) { + Instruction* I = createdExpressions.back(); + createdExpressions.pop_back(); + + delete I; + } +} + bool GVNPRE::runOnFunction(Function &F) { VN.clear(); MS.clear(); @@ -517,7 +575,15 @@ dump_unique(MS); DOUT << "\n"; + // If function has no exit blocks, only perform GVN PostDominatorTree &PDT = getAnalysis(); + if (PDT[&F.getEntryBlock()] == 0) { + elimination(availableOut); + cleanup(); + + return true; + } + // Phase 1, Part 2: calculate ANTIC_IN @@ -634,7 +700,6 @@ DOUT << "\n"; } - // Phase 2: Insert DOUT<< "\nPhase 2: Insertion\n"; @@ -826,53 +891,10 @@ } // Phase 3: Eliminate - DOUT << "\n\nPhase 3: Elimination\n\n"; - - std::vector > replace; - std::vector erase; - - for (df_iterator DI = df_begin(DT.getRootNode()), - E = df_end(DT.getRootNode()); DI != E; ++DI) { - BasicBlock* BB = DI->getBlock(); - - DOUT << "Block: " << BB->getName() << "\n"; - dump_unique(availableOut[BB]); - DOUT << "\n\n"; - - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); - BI != BE; ++BI) { - - if (isa(BI) || isa(BI)) { - Value *leader = find_leader(availableOut[BB], BI); - - if (leader != 0) - if (Instruction* Instr = dyn_cast(leader)) - if (Instr->getParent() != 0 && Instr != BI) { - replace.push_back(std::make_pair(BI, leader)); - erase.push_back(BI); - ++NumEliminated; - } - } - } - } - - while (!replace.empty()) { - std::pair rep = replace.back(); - replace.pop_back(); - rep.first->replaceAllUsesWith(rep.second); - } - - for (std::vector::iterator I = erase.begin(), E = erase.end(); - I != E; ++I) - (*I)->eraseFromParent(); + elimination(availableOut); // Phase 4: Cleanup - while (!createdExpressions.empty()) { - Instruction* I = createdExpressions.back(); - createdExpressions.pop_back(); - - delete I; - } + cleanup(); - return false; + return true; } From sabre at nondot.org Tue Jun 12 12:00:49 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jun 2007 12:00:49 -0500 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200706121700.l5CH0nMT010144@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.252 -> 1.253 --- Log message: modernize example --- Diffs of the changes: (+6 -6) LangRef.html | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.252 llvm/docs/LangRef.html:1.253 --- llvm/docs/LangRef.html:1.252 Fri Jun 8 11:52:14 2007 +++ llvm/docs/LangRef.html Tue Jun 12 12:00:26 2007 @@ -378,21 +378,21 @@
; Declare the string constant as a global constant...
-%.LC0 = internal constant [13 x i8 ] c"hello world\0A\00"          ; [13 x i8 ]*
+@.LC0 = internal constant [13 x i8] c"hello world\0A\00"          ; [13 x i8]*
 
 ; External declaration of the puts function
-declare i32 %puts(i8 *)                                            ; i32(i8 *)* 
+declare i32 @puts(i8 *)                                            ; i32(i8 *)* 
 
 ; Definition of main function
-define i32 %main() {                                                 ; i32()* 
+define i32 @main() {                                                 ; i32()* 
         ; Convert [13x i8 ]* to i8  *...
         %cast210 = getelementptr [13 x i8 ]* %.LC0, i64 0, i64 0 ; i8 *
 
         ; Call puts function to write out the string to stdout...
         call i32 %puts(i8 * %cast210)                              ; i32
+ href="#i_call">call i32 @puts(i8 * %cast210)                              ; i32
         ret i32 0
}
@@ -4830,7 +4830,7 @@ Chris Lattner
The LLVM Compiler Infrastructure
- Last modified: $Date: 2007/06/08 16:52:14 $ + Last modified: $Date: 2007/06/12 17:00:26 $ From sabre at nondot.org Tue Jun 12 12:01:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jun 2007 12:01:38 -0500 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200706121701.l5CH1cNM010259@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.253 -> 1.254 --- Log message: one final bugfix --- Diffs of the changes: (+2 -2) LangRef.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.253 llvm/docs/LangRef.html:1.254 --- llvm/docs/LangRef.html:1.253 Tue Jun 12 12:00:26 2007 +++ llvm/docs/LangRef.html Tue Jun 12 12:01:15 2007 @@ -388,7 +388,7 @@ define i32 @main() { ; i32()* ; Convert [13x i8 ]* to i8 *... %cast210 = getelementptr [13 x i8 ]* %.LC0, i64 0, i64 0 ; i8 * + href="#i_getelementptr">getelementptr [13 x i8 ]* @.LC0, i64 0, i64 0 ; i8 * ; Call puts function to write out the string to stdout... Chris Lattner
The LLVM Compiler Infrastructure
- Last modified: $Date: 2007/06/12 17:00:26 $ + Last modified: $Date: 2007/06/12 17:01:15 $ From dpatel at apple.com Tue Jun 12 12:18:19 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 12 Jun 2007 12:18:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706121718.l5CHIJb4010664@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.114 -> 1.115 --- Log message: Check A dominates B and vise versa first while searching for nearest common dominator. --- Diffs of the changes: (+4 -8) Dominators.cpp | 12 ++++-------- 1 files changed, 4 insertions(+), 8 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.114 llvm/lib/VMCore/Dominators.cpp:1.115 --- llvm/lib/VMCore/Dominators.cpp:1.114 Mon Jun 11 19:54:38 2007 +++ llvm/lib/VMCore/Dominators.cpp Tue Jun 12 12:17:57 2007 @@ -387,12 +387,12 @@ DomTreeNode *NodeB = getNode(B); - // If B immediately dominates A then B is nearest common dominator. - if (NodeA->getIDom() == NodeB) + // If B dominates A then B is nearest common dominator. + if (dominates(B,A)) return B; - // If A immediately dominates B then A is nearest common dominator. - if (NodeB->getIDom() == NodeA) + // If A dominates B then A is nearest common dominator. + if (dominates(A,B)) return A; // Collect NodeA dominators set. @@ -404,10 +404,6 @@ IDomA = IDomA->getIDom(); } - // If B dominates A then B is nearest common dominator. - if (NodeADoms.count(NodeB) != 0) - return B; - // Walk NodeB immediate dominators chain and find common dominator node. DomTreeNode *IDomB = NodeB->getIDom(); while(IDomB) { From dpatel at apple.com Tue Jun 12 12:31:18 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 12 Jun 2007 12:31:18 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200706121731.l5CHVIUH011005@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.104 -> 1.105 --- Log message: Protect updateDFSNumbers() --- Diffs of the changes: (+3 -2) Dominators.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.104 llvm/include/llvm/Analysis/Dominators.h:1.105 --- llvm/include/llvm/Analysis/Dominators.h:1.104 Tue Jun 12 00:49:31 2007 +++ llvm/include/llvm/Analysis/Dominators.h Tue Jun 12 12:30:56 2007 @@ -131,6 +131,8 @@ // Info - Collection of information used during the computation of idoms. std::map Info; + void updateDFSNumbers(); + public: DominatorTreeBase(intptr_t ID, bool isPostDom) : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {} @@ -191,13 +193,12 @@ return IDom != 0; } - void updateDFSNumbers(); /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. const bool isReachableFromEntry(BasicBlock* A); - /// dominates - Returns true iff this dominates N. Note that this is not a + /// dominates - Returns true iff A dominates B. Note that this is not a /// constant time operation! /// inline bool dominates(const DomTreeNode *A, DomTreeNode *B) { From dpatel at apple.com Tue Jun 12 12:35:41 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 12 Jun 2007 12:35:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706121735.l5CHZfv7011098@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.115 -> 1.116 --- Log message: Remove redundant check. --- Diffs of the changes: (+3 -7) Dominators.cpp | 10 +++------- 1 files changed, 3 insertions(+), 7 deletions(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.115 llvm/lib/VMCore/Dominators.cpp:1.116 --- llvm/lib/VMCore/Dominators.cpp:1.115 Tue Jun 12 12:17:57 2007 +++ llvm/lib/VMCore/Dominators.cpp Tue Jun 12 12:35:20 2007 @@ -380,13 +380,6 @@ if (A == &Entry || B == &Entry) return &Entry; - // If A and B are same then A is nearest common dominator. - DomTreeNode *NodeA = getNode(A); - if (A != 0 && A == B) - return A; - - DomTreeNode *NodeB = getNode(B); - // If B dominates A then B is nearest common dominator. if (dominates(B,A)) return B; @@ -395,6 +388,9 @@ if (dominates(A,B)) return A; + DomTreeNode *NodeA = getNode(A); + DomTreeNode *NodeB = getNode(B); + // Collect NodeA dominators set. SmallPtrSet NodeADoms; NodeADoms.insert(NodeA); From dpatel at apple.com Tue Jun 12 12:50:48 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 12 Jun 2007 12:50:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200706121750.l5CHomg8011401@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.116 -> 1.117 --- Log message: isReachableFromEntry() is not suitable for post dominator. --- Diffs of the changes: (+2 -0) Dominators.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.116 llvm/lib/VMCore/Dominators.cpp:1.117 --- llvm/lib/VMCore/Dominators.cpp:1.116 Tue Jun 12 12:35:20 2007 +++ llvm/lib/VMCore/Dominators.cpp Tue Jun 12 12:50:25 2007 @@ -325,6 +325,8 @@ /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. const bool DominatorTreeBase::isReachableFromEntry(BasicBlock* A) { + assert (!isPostDominator() + && "This is not implemented for post dominators"); return dominates(&A->getParent()->getEntryBlock(), A); } From lauro.venancio at gmail.com Tue Jun 12 15:19:00 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Tue, 12 Jun 2007 17:19:00 -0300 Subject: [llvm-commits] proposed patch: shift when shift amount >= bit width Message-ID: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> The attached patch unify the handle of shifts when the shift amount is greater or equal the bit width. Nowadays, LLVM evaluates shl(i32 X,32) to 0 in some places and to undef in other places. For compatibility purpose, this patch implements the gcc behavior. This fix the miscompilation of the file ffmpeg/libavformat/mpeg.c. Proposed behavior: === shl(X,N) ===== if (N=bitwidth(X)) result = 0; === Lshr(X,N) ===== if (N> N if (N>=bitwidth(X)) result = 0; === Ashr(X,N) ===== if (N> N if (N>=bitwidth(X) && X<0) result = -1; if (N>=bitwidth(X) && X>=0) result = 0; Lauro -------------- next part -------------- A non-text attachment was scrubbed... Name: shift.patch Type: text/x-patch Size: 14755 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070612/7654832a/attachment.bin From llvm at cs.uiuc.edu Tue Jun 12 17:41:53 2007 From: llvm at cs.uiuc.edu (LLVM) Date: Tue, 12 Jun 2007 17:41:53 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/Output/ Message-ID: <200706122241.l5CMfrLD017110@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE/Output: --- Log message: Directory /var/cvs/llvm/llvm/test/Transforms/GVNPRE/Output added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From resistor at mac.com Tue Jun 12 17:42:58 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 12 Jun 2007 17:42:58 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll Message-ID: <200706122242.l5CMgwpe017149@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: 2007-06-12-PhiTranslate.ll added (r1.1) --- Log message: Add a test where phi translation was producing a null result. --- Diffs of the changes: (+19 -0) 2007-06-12-PhiTranslate.ll | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll diff -c /dev/null llvm/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll:1.1 *** /dev/null Tue Jun 12 17:42:45 2007 --- llvm/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll Tue Jun 12 17:42:35 2007 *************** *** 0 **** --- 1,19 ---- + ; RUN: llvm-as < %s | opt -gvnpre | llvm-dis + + define void @strength_test5(i32* %data) { + entry: + br i1 false, label %cond_next16.preheader, label %cond_true + + cond_true: ; preds = %entry + %tmp12 = icmp sgt i32 0, 0 ; [#uses=1] + br i1 %tmp12, label %return, label %cond_next16.preheader + + cond_next16.preheader: ; preds = %cond_true, %entry + %i.01.1.ph = phi i32 [ 1, %entry ], [ 1, %cond_true ] ; [#uses=1] + %i.01.1 = add i32 0, %i.01.1.ph ; [#uses=0] + %indvar.next = add i32 0, 1 ; [#uses=0] + ret void + + return: ; preds = %cond_true + ret void + } From resistor at mac.com Tue Jun 12 17:44:19 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 12 Jun 2007 17:44:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706122244.l5CMiJq1017190@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.31 -> 1.32 --- Log message: Fix test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll --- Diffs of the changes: (+39 -38) GVNPRE.cpp | 77 ++++++++++++++++++++++++++++++------------------------------- 1 files changed, 39 insertions(+), 38 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.31 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.32 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.31 Tue Jun 12 11:57:50 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Tue Jun 12 17:43:57 2007 @@ -101,6 +101,9 @@ std::set MS; std::vector createdExpressions; + std::map > availableOut; + std::map > anticipatedIn; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); @@ -115,8 +118,7 @@ bool add(Value* V, uint32_t number); Value* find_leader(std::set& vals, Value* v); - Value* phi_translate(std::set& set, - Value* V, BasicBlock* pred, BasicBlock* succ); + Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ); void phi_translate_set(std::set& anticIn, BasicBlock* pred, BasicBlock* succ, std::set& out); @@ -132,8 +134,7 @@ std::set& currAvail, std::map > availOut); void cleanup(); - void elimination(std::map >& availOut); + void elimination(); }; @@ -160,6 +161,9 @@ } Value* GVNPRE::find_leader(std::set& vals, Value* v) { + if (!isa(v)) + return v; + for (std::set::iterator I = vals.begin(), E = vals.end(); I != E; ++I) { assert(VN.find(v) != VN.end() && "Value not numbered?"); @@ -171,24 +175,23 @@ return 0; } -Value* GVNPRE::phi_translate(std::set& set, - Value* V, BasicBlock* pred, BasicBlock* succ) { +Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) { if (V == 0) return 0; if (BinaryOperator* BO = dyn_cast(V)) { Value* newOp1 = isa(BO->getOperand(0)) - ? phi_translate(set, - find_leader(set, BO->getOperand(0)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], BO->getOperand(0)), + pred, succ) : BO->getOperand(0); if (newOp1 == 0) return 0; Value* newOp2 = isa(BO->getOperand(1)) - ? phi_translate(set, - find_leader(set, BO->getOperand(1)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], BO->getOperand(1)), + pred, succ) : BO->getOperand(1); if (newOp2 == 0) return 0; @@ -200,7 +203,9 @@ if (add(newVal, nextValueNumber)) nextValueNumber++; - if (!find_leader(set, newVal)) { + + Value* leader = find_leader(availableOut[pred], newVal); + if (leader == 0) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; createdExpressions.push_back(newVal); return newVal; @@ -214,7 +219,7 @@ MS.erase(newVal); delete newVal; - return 0; + return leader; } } } else if (PHINode* P = dyn_cast(V)) { @@ -222,17 +227,17 @@ return P->getIncomingValueForBlock(pred); } else if (CmpInst* C = dyn_cast(V)) { Value* newOp1 = isa(C->getOperand(0)) - ? phi_translate(set, - find_leader(set, C->getOperand(0)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], C->getOperand(0)), + pred, succ) : C->getOperand(0); if (newOp1 == 0) return 0; Value* newOp2 = isa(C->getOperand(1)) - ? phi_translate(set, - find_leader(set, C->getOperand(1)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], C->getOperand(1)), + pred, succ) : C->getOperand(1); if (newOp2 == 0) return 0; @@ -245,7 +250,9 @@ if (add(newVal, nextValueNumber)) nextValueNumber++; - if (!find_leader(set, newVal)) { + + Value* leader = find_leader(availableOut[pred], newVal); + if (leader == 0) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; createdExpressions.push_back(newVal); return newVal; @@ -259,7 +266,7 @@ MS.erase(newVal); delete newVal; - return 0; + return leader; } } } @@ -272,7 +279,7 @@ std::set& out) { for (std::set::iterator I = anticIn.begin(), E = anticIn.end(); I != E; ++I) { - Value* V = phi_translate(anticIn, *I, pred, succ); + Value* V = phi_translate(*I, pred, succ); if (V != 0) out.insert(V); } @@ -485,8 +492,7 @@ } } -void GVNPRE::elimination(std::map >& availableOut) { +void GVNPRE::elimination() { DOUT << "\n\nPhase 3: Elimination\n\n"; std::vector > replace; @@ -544,12 +550,13 @@ VN.clear(); MS.clear(); createdExpressions.clear(); + availableOut.clear(); + anticipatedIn.clear(); std::map > generatedExpressions; std::map > generatedPhis; std::map > generatedTemporaries; - std::map > availableOut; - std::map > anticipatedIn; + DominatorTree &DT = getAnalysis(); @@ -578,7 +585,7 @@ // If function has no exit blocks, only perform GVN PostDominatorTree &PDT = getAnalysis(); if (PDT[&F.getEntryBlock()] == 0) { - elimination(availableOut); + elimination(); cleanup(); return true; @@ -761,7 +768,7 @@ for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { - Value *e2 = phi_translate(anticIn, e, *PI, BB); + Value *e2 = phi_translate(e, *PI, BB); Value *e3 = find_leader(availableOut[*PI], e2); if (e3 == 0) { @@ -795,20 +802,14 @@ Value* s1 = 0; if (isa(U->getOperand(0))) s1 = find_leader(availableOut[*PI], - phi_translate(availableOut[*PI], - U->getOperand(0), - *PI, BB) - ); + phi_translate(U->getOperand(0), *PI, BB)); else s1 = U->getOperand(0); Value* s2 = 0; if (isa(U->getOperand(1))) s2 = find_leader(availableOut[*PI], - phi_translate(availableOut[*PI], - U->getOperand(1), - *PI, BB) - ); + phi_translate(U->getOperand(1), *PI, BB)); else s2 = U->getOperand(1); @@ -891,7 +892,7 @@ } // Phase 3: Eliminate - elimination(availableOut); + elimination(); // Phase 4: Cleanup cleanup(); From evan.cheng at apple.com Tue Jun 12 18:54:27 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 12 Jun 2007 18:54:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706122354.l5CNsRvM018710@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.44 -> 1.45 --- Log message: Now if-converting all 4 variants of triangles. --- Diffs of the changes: (+40 -24) IfConversion.cpp | 64 ++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 40 insertions(+), 24 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.44 llvm/lib/CodeGen/IfConversion.cpp:1.45 --- llvm/lib/CodeGen/IfConversion.cpp:1.44 Mon Jun 11 17:26:22 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Tue Jun 12 18:54:05 2007 @@ -36,6 +36,8 @@ cl::init(false), cl::Hidden); cl::opt DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden); + cl::opt DisableTriangleR("disable-ifcvt-triangle-rev", + cl::init(false), cl::Hidden); cl::opt DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden); cl::opt DisableTriangleFR("disable-ifcvt-triangle-false-rev", @@ -47,6 +49,7 @@ STATISTIC(NumSimple, "Number of simple if-conversions performed"); STATISTIC(NumSimpleFalse, "Number of simple (F) if-conversions performed"); STATISTIC(NumTriangle, "Number of triangle if-conversions performed"); +STATISTIC(NumTriangleRev, "Number of triangle (R) if-conversions performed"); STATISTIC(NumTriangleFalse,"Number of triangle (F) if-conversions performed"); STATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed"); STATISTIC(NumDiamonds, "Number of diamond if-conversions performed"); @@ -59,6 +62,7 @@ ICSimple, // BB is entry of an one split, no rejoin sub-CFG. ICSimpleFalse, // Same as ICSimple, but on the false path. ICTriangle, // BB is entry of a triangle sub-CFG. + ICTriangleRev, // Same as ICTriangle, but true path rev condition. ICTriangleFalse, // Same as ICTriangle, but on the false path. ICTriangleFRev, // Same as ICTriangleFalse, but false path rev condition. ICDiamond // BB is entry of a diamond sub-CFG. @@ -225,27 +229,33 @@ break; } case ICTriangle: + case ICTriangleRev: case ICTriangleFalse: case ICTriangleFRev: { - bool isFalse = BBI.Kind == ICTriangleFalse; - bool isFalseRev = BBI.Kind == ICTriangleFRev; - if (DisableTriangle && !isFalse && !isFalseRev) break; - if (DisableTriangleF && isFalse) break; - if (DisableTriangleFR && isFalseRev) break; + bool isFalse = BBI.Kind == ICTriangleFalse; + bool isRev = (BBI.Kind == ICTriangleRev || BBI.Kind == ICTriangleFRev); + if (DisableTriangle && !isFalse && !isRev) break; + if (DisableTriangleR && !isFalse && isRev) break; + if (DisableTriangleF && isFalse && !isRev) break; + if (DisableTriangleFR && isFalse && isRev) break; DOUT << "Ifcvt (Triangle"; if (isFalse) DOUT << " false"; - if (isFalseRev) - DOUT << " false/rev"; + if (isRev) + DOUT << " rev"; DOUT << "): BB#" << BBI.BB->getNumber() << " (T:" << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber() << ") "; RetVal = IfConvertTriangle(BBI); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; if (RetVal) { - if (isFalseRev) NumTriangleFRev++; - else if (isFalse) NumTriangleFalse++; - else NumTriangle++; + if (isFalse) { + if (isRev) NumTriangleFRev++; + else NumTriangleFalse++; + } else { + if (isRev) NumTriangleRev++; + else NumTriangle++; + } } break; } @@ -535,6 +545,9 @@ // | / // FBB BBI.Kind = ICTriangle; + } else if (ValidTriangle(TrueBBI, FalseBBI, true) && + FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) { + BBI.Kind = ICTriangleRev; } else if (ValidSimple(TrueBBI) && FeasibilityAnalysis(TrueBBI, BBI.BrCond)) { // Simple (split, no rejoin): @@ -608,6 +621,9 @@ case ICSimple: case ICSimpleFalse: case ICTriangle: + case ICTriangleRev: + case ICTriangleFalse: + case ICTriangleFRev: case ICDiamond: Candidates.push_back(&BBI); break; @@ -734,23 +750,23 @@ std::vector Cond(BBI.BrCond); if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) { - if (BBI.Kind == ICTriangleFRev) { - ReverseBranchCondition(*NextBBI); - // False BB has been changed, modify its predecessors (except for this - // one) so they don't get ifcvt'ed based on bad intel. - for (MachineBasicBlock::pred_iterator PI = NextBBI->BB->pred_begin(), - E = NextBBI->BB->pred_end(); PI != E; ++PI) { - MachineBasicBlock *PBB = *PI; - if (PBB == BBI.BB) - continue; - BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; - if (PBBI.IsEnqueued) - PBBI.IsEnqueued = false; - } - } std::swap(CvtBBI, NextBBI); TII->ReverseBranchCondition(Cond); } + if (BBI.Kind == ICTriangleRev || BBI.Kind == ICTriangleFRev) { + ReverseBranchCondition(*CvtBBI); + // BB has been changed, modify its predecessors (except for this + // one) so they don't get ifcvt'ed based on bad intel. + for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(), + E = CvtBBI->BB->pred_end(); PI != E; ++PI) { + MachineBasicBlock *PBB = *PI; + if (PBB == BBI.BB) + continue; + BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; + if (PBBI.IsEnqueued) + PBBI.IsEnqueued = false; + } + } // Predicate the 'true' block after removing its branch. TrueBBI.NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); From evan.cheng at apple.com Tue Jun 12 19:04:22 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 12 Jun 2007 19:04:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706130004.l5D04ML6018902@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.45 -> 1.46 --- Log message: Typo --- Diffs of the changes: (+1 -1) IfConversion.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.45 llvm/lib/CodeGen/IfConversion.cpp:1.46 --- llvm/lib/CodeGen/IfConversion.cpp:1.45 Tue Jun 12 18:54:05 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Tue Jun 12 19:04:00 2007 @@ -769,7 +769,7 @@ } // Predicate the 'true' block after removing its branch. - TrueBBI.NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); + CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); PredicateBlock(*CvtBBI, Cond); // If 'true' block has a 'false' successor, add an exit branch to it. From clattner at apple.com Wed Jun 13 00:33:32 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 12 Jun 2007 22:33:32 -0700 Subject: [llvm-commits] Fix PR1224 differently In-Reply-To: <200706091621.23470.baldrick@free.fr> References: <200706091621.23470.baldrick@free.fr> Message-ID: <86FDCD1B-FA9C-4908-BA2A-89CC22C31209@apple.com> Looks fine to me, please apply, -Chris On Jun 9, 2007, at 7:21 AM, Duncan Sands wrote: > The fix that was applied for PR1224 stops the compiler > crashing but breaks exception handling. The problem > described in PR1224 is that invoke is a terminator that > can produce a value. The value may be needed in other > blocks. The code that writes to registers values needed > in other blocks runs before terminators are lowered (in > this case invoke) so asserted because the value was not > yet available. The fix that was applied was to do invoke > lowering earlier, before writing values to registers. > > The problem this causes is that the code to copy values > to registers can be output after the invoke call. If > an exception is raised and control is passed to the > landing pad then this copy-code will never execute. If > the value is needed in some code path reached via the > landing pad then that code will get something bogus. > > The attached patch reverts the original fix and simply > skips invoke values in the general copying to registers > code. The invoke value is instead copied to a register > in the invoke lowering code. I had a testcase but I > accidentally deleted it... > > Ciao, > > Duncan. > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Wed Jun 13 00:33:53 2007 From: clattner at apple.com (clattner at apple.com) Date: Tue, 12 Jun 2007 22:33:53 -0700 (PDT) Subject: [llvm-commits] [128368] From Duncan: Message-ID: <20070613053353.F28C2860FD37@src> Revision: 128368 Author: clattner Date: 2007-06-12 22:33:53 -0700 (Tue, 12 Jun 2007) Log Message: ----------- >From Duncan: "When I got rid of the inreg attribute for static chain parameters, I simply deleted the attribute adding code while I should have pushed a attribute of "none" - this results in attributes for other parameters being applied to the wrong parameters (off by one)." Modified Paths: -------------- apple-local/branches/llvm/gcc/llvm-types.cpp Modified: apple-local/branches/llvm/gcc/llvm-types.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-types.cpp 2007-06-12 15:31:10 UTC (rev 128367) +++ apple-local/branches/llvm/gcc/llvm-types.cpp 2007-06-13 05:33:53 UTC (rev 128368) @@ -1013,7 +1013,11 @@ PAWI.index = Idx++; PAWI.attrs = ParamAttr::StructRet; Attrs.push_back(PAWI); } - + + if (static_chain) + // Skip over the static chain. + Idx++; + for (tree Args = TYPE_ARG_TYPES(type); Args && TREE_VALUE(Args) != void_type_node; Args = TREE_CHAIN(Args)) { tree Ty = TREE_VALUE(Args); From baldrick at free.fr Wed Jun 13 00:51:53 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 13 Jun 2007 00:51:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706130551.l5D5pr8R011495@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.458 -> 1.459 --- Log message: The fix that was applied for PR1224: http://llvm.org/PR1224 stops the compiler crashing but breaks exception handling. The problem described in PR1224: http://llvm.org/PR1224 is that invoke is a terminator that can produce a value. The value may be needed in other blocks. The code that writes to registers values needed in other blocks runs before terminators are lowered (in this case invoke) so asserted because the value was not yet available. The fix that was applied was to do invoke lowering earlier, before writing values to registers. The problem this causes is that the code to copy values to registers can be output after the invoke call. If an exception is raised and control is passed to the landing pad then this copy-code will never execute. If the value is needed in some code path reached via the landing pad then that code will get something bogus. So revert the original fix and simply skip invoke values in the general copying to registers code. Instead copy the invoke value to a register in the invoke lowering code. --- Diffs of the changes: (+25 -33) SelectionDAGISel.cpp | 58 +++++++++++++++++++++------------------------------ 1 files changed, 25 insertions(+), 33 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.458 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.459 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.458 Thu Jun 7 16:07:15 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jun 13 00:51:31 2007 @@ -566,7 +566,6 @@ // These all get lowered before this pass. void visitInvoke(InvokeInst &I); - void visitInvoke(InvokeInst &I, bool AsTerminator); void visitUnwind(UnwindInst &I); void visitScalarBinary(User &I, unsigned OpCode); @@ -1332,29 +1331,31 @@ } void SelectionDAGLowering::visitInvoke(InvokeInst &I) { - assert(0 && "Should never be visited directly"); -} -void SelectionDAGLowering::visitInvoke(InvokeInst &I, bool AsTerminator) { // Retrieve successors. MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)]; + MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; - if (!AsTerminator) { - MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; - - LowerCallTo(I, I.getCalledValue()->getType(), - I.getCallingConv(), - false, - getValue(I.getOperand(0)), - 3, LandingPad); - - // Update successor info - CurMBB->addSuccessor(Return); - CurMBB->addSuccessor(LandingPad); - } else { - // Drop into normal successor. - DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(), - DAG.getBasicBlock(Return))); + LowerCallTo(I, I.getCalledValue()->getType(), + I.getCallingConv(), + false, + getValue(I.getOperand(0)), + 3, LandingPad); + + // If the value of the invoke is used outside of its defining block, make it + // available as a virtual register. + if (!I.use_empty()) { + DenseMap::iterator VMI = FuncInfo.ValueMap.find(&I); + if (VMI != FuncInfo.ValueMap.end()) + DAG.setRoot(CopyValueToVirtualRegister(&I, VMI->second)); } + + // Drop into normal successor. + DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(), + DAG.getBasicBlock(Return))); + + // Update successor info + CurMBB->addSuccessor(Return); + CurMBB->addSuccessor(LandingPad); } void SelectionDAGLowering::visitUnwind(UnwindInst &I) { @@ -4546,15 +4547,11 @@ for (BasicBlock::iterator I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I) SDL.visit(*I); - - // Lower call part of invoke. - InvokeInst *Invoke = dyn_cast(LLVMBB->getTerminator()); - if (Invoke) SDL.visitInvoke(*Invoke, false); - + // Ensure that all instructions which are used outside of their defining - // blocks are available as virtual registers. + // blocks are available as virtual registers. Invoke is handled elsewhere. for (BasicBlock::iterator I = LLVMBB->begin(), E = LLVMBB->end(); I != E;++I) - if (!I->use_empty() && !isa(I)) { + if (!I->use_empty() && !isa(I) && !isa(I)) { DenseMap::iterator VMI =FuncInfo.ValueMap.find(I); if (VMI != FuncInfo.ValueMap.end()) UnorderedChains.push_back( @@ -4662,12 +4659,7 @@ } // Lower the terminator after the copies are emitted. - if (Invoke) { - // Just the branch part of invoke. - SDL.visitInvoke(*Invoke, true); - } else { - SDL.visit(*LLVMBB->getTerminator()); - } + SDL.visit(*LLVMBB->getTerminator()); // Copy over any CaseBlock records that may now exist due to SwitchInst // lowering, as well as any jump table information. From djg at cray.com Wed Jun 13 09:55:39 2007 From: djg at cray.com (Dan Gohman) Date: Wed, 13 Jun 2007 09:55:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706131455.l5DEtdMn032322@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.459 -> 1.460 --- Log message: When creating CopyFromReg nodes, always use legal types. And use the correct types for the result vector, even though it is currently bitcasted to a different type immediately. --- Diffs of the changes: (+6 -6) SelectionDAGISel.cpp | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.459 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.460 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.459 Wed Jun 13 00:51:31 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jun 13 09:55:16 2007 @@ -772,7 +772,7 @@ // If the register was promoted, use TRUNCATE or FP_ROUND as appropriate. for (unsigned i = 0; i != NE; ++i) { SDOperand Op = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, - PTyElementVT); + PTyLegalElementVT); if (MVT::isFloatingPoint(PTyElementVT)) Op = DAG.getNode(ISD::FP_ROUND, PTyElementVT, Op); else @@ -782,17 +782,17 @@ } else { // If the register was expanded, use BUILD_PAIR. assert((NE & 1) == 0 && "Must expand into a multiple of 2 elements!"); - for (unsigned i = 0; i != NE/2; ++i) { + for (unsigned i = 0; i != NE; ++i) { SDOperand Op0 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, - PTyElementVT); + PTyLegalElementVT); SDOperand Op1 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, - PTyElementVT); - Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, VT, Op0, Op1)); + PTyLegalElementVT); + Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, PTyElementVT, Op0, Op1)); } } Ops.push_back(DAG.getConstant(NE, MVT::i32)); - Ops.push_back(DAG.getValueType(PTyLegalElementVT)); + Ops.push_back(DAG.getValueType(PTyElementVT)); N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0], Ops.size()); // Finally, use a VBIT_CONVERT to make this available as the appropriate From djg at cray.com Wed Jun 13 10:12:30 2007 From: djg at cray.com (Dan Gohman) Date: Wed, 13 Jun 2007 10:12:30 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200706131512.l5DFCUQk032745@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.191 -> 1.192 --- Log message: Introduce new SelectionDAG node opcodes VEXTRACT_SUBVECTOR and VCONCAT_VECTORS. Use these for CopyToReg and CopyFromReg legalizing in the case that the full register is to be split into subvectors instead of scalars. This replaces uses of VBIT_CONVERT to present values as vector-of-vector types in order to make whole subvectors accessible via BUILD_VECTOR and EXTRACT_VECTOR_ELT. This is in preparation for adding extended ValueType values, where having vector-of-vector types is undesirable. --- Diffs of the changes: (+13 -0) SelectionDAGNodes.h | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.191 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.192 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.191 Thu May 24 09:36:03 2007 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Jun 13 10:12:02 2007 @@ -267,6 +267,19 @@ /// element number IDX. EXTRACT_VECTOR_ELT, + /// VCONCAT_VECTORS(VECTOR0, VECTOR1, ..., COUNT,TYPE) - Given a number of + /// values of MVT::Vector type with the same length and element type, this + /// produces a concatenated MVT::Vector result value, with length equal to + /// the sum of the input vectors. This can only be used before + /// legalization. + VCONCAT_VECTORS, + + /// VEXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an + /// MVT::Vector value) starting with the (potentially variable) + /// element number IDX, which must be a multiple of the result vector + /// length. This can only be used before legalization. + VEXTRACT_SUBVECTOR, + /// VVECTOR_SHUFFLE(VEC1, VEC2, SHUFFLEVEC, COUNT,TYPE) - Returns a vector, /// of the same type as VEC1/VEC2. SHUFFLEVEC is a VBUILD_VECTOR of /// constant int values that indicate which value each result element will From djg at cray.com Wed Jun 13 10:12:34 2007 From: djg at cray.com (Dan Gohman) Date: Wed, 13 Jun 2007 10:12:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200706131512.l5DFCY9c032755@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.495 -> 1.496 SelectionDAG.cpp updated: 1.405 -> 1.406 SelectionDAGISel.cpp updated: 1.460 -> 1.461 --- Log message: Introduce new SelectionDAG node opcodes VEXTRACT_SUBVECTOR and VCONCAT_VECTORS. Use these for CopyToReg and CopyFromReg legalizing in the case that the full register is to be split into subvectors instead of scalars. This replaces uses of VBIT_CONVERT to present values as vector-of-vector types in order to make whole subvectors accessible via BUILD_VECTOR and EXTRACT_VECTOR_ELT. This is in preparation for adding extended ValueType values, where having vector-of-vector types is undesirable. --- Diffs of the changes: (+83 -21) LegalizeDAG.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ SelectionDAG.cpp | 2 + SelectionDAGISel.cpp | 39 ++++++++++++++----------------- 3 files changed, 83 insertions(+), 21 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.495 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.496 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.495 Mon Jun 4 11:17:33 2007 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jun 13 10:12:02 2007 @@ -225,6 +225,7 @@ SDOperand &Lo, SDOperand &Hi); SDOperand LowerVEXTRACT_VECTOR_ELT(SDOperand Op); + SDOperand LowerVEXTRACT_SUBVECTOR(SDOperand Op); SDOperand ExpandEXTRACT_VECTOR_ELT(SDOperand Op); SDOperand getIntPtrConstant(uint64_t Val) { @@ -1178,6 +1179,10 @@ Result = LegalizeOp(LowerVEXTRACT_VECTOR_ELT(Op)); break; + case ISD::VEXTRACT_SUBVECTOR: + Result = LegalizeOp(LowerVEXTRACT_SUBVECTOR(Op)); + break; + case ISD::CALLSEQ_START: { SDNode *CallEnd = FindCallEndFromCallStart(Node); @@ -3561,6 +3566,9 @@ case ISD::VEXTRACT_VECTOR_ELT: Result = PromoteOp(LowerVEXTRACT_VECTOR_ELT(Op)); break; + case ISD::VEXTRACT_SUBVECTOR: + Result = PromoteOp(LowerVEXTRACT_SUBVECTOR(Op)); + break; case ISD::EXTRACT_VECTOR_ELT: Result = PromoteOp(ExpandEXTRACT_VECTOR_ELT(Op)); break; @@ -3622,6 +3630,37 @@ } } +/// LowerVEXTRACT_SUBVECTOR - Lower a VEXTRACT_SUBVECTOR operation. For now +/// we assume the operation can be split if it is not already legal. +SDOperand SelectionDAGLegalize::LowerVEXTRACT_SUBVECTOR(SDOperand Op) { + // We know that operand #0 is the Vec vector. For now we assume the index + // is a constant and that the extracted result is a supported hardware type. + SDOperand Vec = Op.getOperand(0); + SDOperand Idx = LegalizeOp(Op.getOperand(1)); + + SDNode *InVal = Vec.Val; + unsigned NumElems = cast(*(InVal->op_end()-2))->getValue(); + + if (NumElems == MVT::getVectorNumElements(Op.getValueType())) { + // This must be an access of the desired vector length. Return it. + return PackVectorOp(Vec, Op.getValueType()); + } + + ConstantSDNode *CIdx = cast(Idx); + SDOperand Lo, Hi; + SplitVectorOp(Vec, Lo, Hi); + if (CIdx->getValue() < NumElems/2) { + Vec = Lo; + } else { + Vec = Hi; + Idx = DAG.getConstant(CIdx->getValue() - NumElems/2, Idx.getValueType()); + } + + // It's now an extract from the appropriate high or low part. Recurse. + Op = DAG.UpdateNodeOperands(Op, Vec, Idx); + return LowerVEXTRACT_SUBVECTOR(Op); +} + /// ExpandEXTRACT_VECTOR_ELT - Expand an EXTRACT_VECTOR_ELT operation into /// memory traffic. SDOperand SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDOperand Op) { @@ -5501,6 +5540,21 @@ Hi = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &HiOps[0], HiOps.size()); break; } + case ISD::VCONCAT_VECTORS: { + unsigned NewNumSubvectors = (Node->getNumOperands() - 2) / 2; + SmallVector LoOps(Node->op_begin(), + Node->op_begin()+NewNumSubvectors); + LoOps.push_back(NewNumEltsNode); + LoOps.push_back(TypeNode); + Lo = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &LoOps[0], LoOps.size()); + + SmallVector HiOps(Node->op_begin()+NewNumSubvectors, + Node->op_end()-2); + HiOps.push_back(NewNumEltsNode); + HiOps.push_back(TypeNode); + Hi = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &HiOps[0], HiOps.size()); + break; + } case ISD::VADD: case ISD::VSUB: case ISD::VMUL: @@ -5655,6 +5709,11 @@ } } break; + case ISD::VCONCAT_VECTORS: + assert(Node->getOperand(0).getValueType() == NewVT && + "Concat of non-legal vectors not yet supported!"); + Result = Node->getOperand(0); + break; case ISD::VINSERT_VECTOR_ELT: if (!MVT::isVector(NewVT)) { // Returning a scalar? Must be the inserted element. @@ -5665,6 +5724,10 @@ Node->getOperand(1), Node->getOperand(2)); } break; + case ISD::VEXTRACT_SUBVECTOR: + Result = PackVectorOp(Node->getOperand(0), NewVT); + assert(Result.getValueType() == NewVT); + break; case ISD::VVECTOR_SHUFFLE: if (!MVT::isVector(NewVT)) { // Returning a scalar? Figure out if it is the LHS or RHS and return it. Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.405 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.406 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.405 Mon Jun 4 10:49:41 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Jun 13 10:12:02 2007 @@ -2865,6 +2865,8 @@ case ISD::VINSERT_VECTOR_ELT: return "vinsert_vector_elt"; case ISD::EXTRACT_VECTOR_ELT: return "extract_vector_elt"; case ISD::VEXTRACT_VECTOR_ELT: return "vextract_vector_elt"; + case ISD::VCONCAT_VECTORS: return "vconcat_vectors"; + case ISD::VEXTRACT_SUBVECTOR: return "vextract_subvector"; case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector"; case ISD::VBUILD_VECTOR: return "vbuild_vector"; case ISD::VECTOR_SHUFFLE: return "vector_shuffle"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.460 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.461 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.460 Wed Jun 13 09:55:16 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jun 13 10:12:02 2007 @@ -761,7 +761,7 @@ unsigned NE = TLI.getVectorTypeBreakdown(PTy, PTyElementVT, PTyLegalElementVT); - // Build a VBUILD_VECTOR with the input registers. + // Build a VBUILD_VECTOR or VCONCAT_VECTORS with the input registers. SmallVector Ops; if (PTyElementVT == PTyLegalElementVT) { // If the value types are legal, just VBUILD the CopyFromReg nodes. @@ -791,16 +791,15 @@ } } - Ops.push_back(DAG.getConstant(NE, MVT::i32)); - Ops.push_back(DAG.getValueType(PTyElementVT)); - N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0], Ops.size()); - - // Finally, use a VBIT_CONVERT to make this available as the appropriate - // vector type. - N = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, N, - DAG.getConstant(PTy->getNumElements(), - MVT::i32), - DAG.getValueType(TLI.getValueType(PTy->getElementType()))); + if (MVT::isVector(PTyElementVT)) { + Ops.push_back(DAG.getConstant(NE * MVT::getVectorNumElements(PTyElementVT), MVT::i32)); + Ops.push_back(DAG.getValueType(MVT::getVectorBaseType(PTyElementVT))); + N = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &Ops[0], Ops.size()); + } else { + Ops.push_back(DAG.getConstant(NE, MVT::i32)); + Ops.push_back(DAG.getValueType(PTyElementVT)); + N = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0], Ops.size()); + } } return N; @@ -4426,21 +4425,19 @@ MVT::ValueType PTyElementVT, PTyLegalElementVT; unsigned NE = TLI.getVectorTypeBreakdown(cast(V->getType()), PTyElementVT, PTyLegalElementVT); + uint64_t SrcVL = cast(*(Op.Val->op_end()-2))->getValue(); - // Insert a VBIT_CONVERT of the input vector to a "N x PTyElementVT" - // MVT::Vector type. - Op = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Op, - DAG.getConstant(NE, MVT::i32), - DAG.getValueType(PTyElementVT)); - // Loop over all of the elements of the resultant vector, - // VEXTRACT_VECTOR_ELT'ing them, converting them to PTyLegalElementVT, then - // copying them into output registers. + // VEXTRACT_VECTOR_ELT'ing or VEXTRACT_SUBVECTOR'ing them, converting them + // to PTyLegalElementVT, then copying them into output registers. SmallVector OutChains; SDOperand Root = getRoot(); for (unsigned i = 0; i != NE; ++i) { - SDOperand Elt = DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT, - Op, DAG.getConstant(i, TLI.getPointerTy())); + SDOperand Elt = MVT::isVector(PTyElementVT) ? + DAG.getNode(ISD::VEXTRACT_SUBVECTOR, PTyElementVT, + Op, DAG.getConstant(i * (SrcVL / NE), TLI.getPointerTy())) : + DAG.getNode(ISD::VEXTRACT_VECTOR_ELT, PTyElementVT, + Op, DAG.getConstant(i, TLI.getPointerTy())); if (PTyElementVT == PTyLegalElementVT) { // Elements are legal. OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt)); From baldrick at free.fr Wed Jun 13 11:53:43 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 13 Jun 2007 11:53:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706131653.l5DGrhKn002993@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.461 -> 1.462 --- Log message: Only correctly lower exception handing intrinsics if exception handling is turned on. Likewise for scanning of invokes to mark landing pads. --- Diffs of the changes: (+7 -8) SelectionDAGISel.cpp | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.461 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.462 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.461 Wed Jun 13 10:12:02 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jun 13 11:53:21 2007 @@ -2574,7 +2574,7 @@ case Intrinsic::eh_exception: { MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - if (MMI) { + if (ExceptionHandling && MMI) { // Mark exception register as live in. unsigned Reg = TLI.getExceptionAddressRegister(); if (Reg) CurMBB->addLiveIn(Reg); @@ -2596,7 +2596,7 @@ case Intrinsic::eh_filter:{ MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - if (MMI) { + if (ExceptionHandling && MMI) { // Inform the MachineModuleInfo of the personality for this landing pad. ConstantExpr *CE = dyn_cast(I.getOperand(2)); assert(CE && CE->getOpcode() == Instruction::BitCast && @@ -4386,12 +4386,11 @@ FunctionLoweringInfo FuncInfo(TLI, Fn, MF); - for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - if (InvokeInst *Invoke = dyn_cast(I->getTerminator())) { - // Mark landing pad. - MachineBasicBlock *LandingPad = FuncInfo.MBBMap[Invoke->getSuccessor(1)]; - LandingPad->setIsLandingPad(); - } + if (ExceptionHandling) + for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) + if (InvokeInst *Invoke = dyn_cast(I->getTerminator())) + // Mark landing pad. + FuncInfo.MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad(); for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) SelectBasicBlock(I, MF, FuncInfo); From dalej at apple.com Wed Jun 13 12:52:59 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 13 Jun 2007 10:52:59 -0700 Subject: [llvm-commits] proposed patch: shift when shift amount >= bit width In-Reply-To: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> References: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> Message-ID: On Jun 12, 2007, at 1:19 PM, Lauro Ramos Venancio wrote: > The attached patch unify the handle of shifts when the shift amount is > greater or equal the bit width. > > Nowadays, LLVM evaluates shl(i32 X,32) to 0 in some places and to > undef in other places. > For compatibility purpose, this patch implements the gcc behavior. This is not enough to make a compiler handle shifts by greater than the word size consistently; in both gcc and llvm-gcc, for example, the result of int y=32; x>>y depends on optimization level. There is probably a target dependency as well; for example, the 68020 used the low 6 bits of a variable shift count, while most other chips use only 5 bits. I don't think we can ever promise consistent behavior for things like this, and I'm not sure implementing a consistent behavior in one particular case is a good idea. I'd rather see users educated to understand that this construct is not valid C and they shouldn't be doing it (a warning, perhaps, in cases where the compiler can detect it). > This fix the miscompilation of the file ffmpeg/libavformat/mpeg.c. I'm not familiar with this file, but if it depends on the handling of shifts by larger than the word size, it is not correct C, so speaking of a "miscompilation" is a bit harsh. > Proposed behavior: > === shl(X,N) ===== > if (N if (N>=bitwidth(X)) result = 0; > > === Lshr(X,N) ===== > if (N> N > if (N>=bitwidth(X)) result = 0; > > === Ashr(X,N) ===== > if (N> N > if (N>=bitwidth(X) && X<0) result = -1; > if (N>=bitwidth(X) && X>=0) result = 0; > > > Lauro -------------- next part -------------- A non-text attachment was scrubbed... Name: shift.patch Type: text/x-patch Size: 14756 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070613/9a6efa95/attachment.bin -------------- next part -------------- > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Wed Jun 13 12:55:14 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 13 Jun 2007 19:55:14 +0200 Subject: [llvm-commits] Workaround for PR1508 Message-ID: <200706131955.15130.baldrick@free.fr> Look for eh.filter and eh.selector intrinsics in the successor to an empty (exception for a branch) landing pad. The big FIXME comment explains more. Testcase included, along with an XFAIL for a test which uses eh.selector in a routine with no landing pads (not possible in llvm-gcc generated code). Ciao, Duncan. -------------- next part -------------- A non-text attachment was scrubbed... Name: eh_hack.diff Type: text/x-diff Size: 7643 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070613/5323bd3b/attachment.bin From dalej at apple.com Wed Jun 13 13:00:16 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 13 Jun 2007 13:00:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp Message-ID: <200706131800.l5DI0G1W006848@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMInstrInfo.cpp updated: 1.35 -> 1.36 --- Log message: Handle blocks with 2 unconditional branches in AnalyzeBranch. --- Diffs of the changes: (+10 -0) ARMInstrInfo.cpp | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.35 llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.35 Fri Jun 8 16:59:56 2007 +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Wed Jun 13 12:59:52 2007 @@ -345,6 +345,16 @@ return false; } + // If the block ends with two B's or tB's, handle it. The second one is not + // executed, so remove it. + if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) && + (LastOpc == ARM::B || LastOpc == ARM::tB)) { + TBB = SecondLastInst->getOperand(0).getMachineBasicBlock(); + I = LastInst; + I->eraseFromParent(); + return false; + } + // Otherwise, can't handle this. return true; } From dalej at apple.com Wed Jun 13 13:00:25 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 13 Jun 2007 13:00:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Message-ID: <200706131800.l5DI0PVB006872@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.cpp updated: 1.20 -> 1.21 --- Log message: Handle blocks with 2 unconditional branches in AnalyzeBranch. --- Diffs of the changes: (+10 -0) AlphaInstrInfo.cpp | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.20 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.21 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.20 Fri Jun 8 16:59:56 2007 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Wed Jun 13 12:59:52 2007 @@ -200,6 +200,16 @@ return false; } + // If the block ends with two Alpha::BRs, handle it. The second one is not + // executed, so remove it. + if (SecondLastInst->getOpcode() == Alpha::BR && + LastInst->getOpcode() == Alpha::BR) { + TBB = SecondLastInst->getOperand(0).getMachineBasicBlock(); + I = LastInst; + I->eraseFromParent(); + return false; + } + // Otherwise, can't handle this. return true; } From dalej at apple.com Wed Jun 13 13:00:25 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 13 Jun 2007 13:00:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Message-ID: <200706131800.l5DI0PkF006873@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.cpp updated: 1.40 -> 1.41 --- Log message: Handle blocks with 2 unconditional branches in AnalyzeBranch. --- Diffs of the changes: (+10 -0) PPCInstrInfo.cpp | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.40 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.41 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.40 Fri Jun 8 16:59:56 2007 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Wed Jun 13 12:59:52 2007 @@ -220,6 +220,16 @@ return false; } + // If the block ends with two PPC:Bs, handle it. The second one is not + // executed, so remove it. + if (SecondLastInst->getOpcode() == PPC::B && + LastInst->getOpcode() == PPC::B) { + TBB = SecondLastInst->getOperand(0).getMachineBasicBlock(); + I = LastInst; + I->eraseFromParent(); + return false; + } + // Otherwise, can't handle this. return true; } From dalej at apple.com Wed Jun 13 13:00:26 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 13 Jun 2007 13:00:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200706131800.l5DI0QoR006881@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.88 -> 1.89 --- Log message: Handle blocks with 2 unconditional branches in AnalyzeBranch. --- Diffs of the changes: (+10 -0) X86InstrInfo.cpp | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.88 llvm/lib/Target/X86/X86InstrInfo.cpp:1.89 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.88 Fri Jun 8 16:59:56 2007 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Jun 13 12:59:52 2007 @@ -427,6 +427,16 @@ return false; } + // If the block ends with two X86::JMPs, handle it. The second one is not + // executed, so remove it. + if (SecondLastInst->getOpcode() == X86::JMP && + LastInst->getOpcode() == X86::JMP) { + TBB = SecondLastInst->getOperand(0).getMachineBasicBlock(); + I = LastInst; + I->eraseFromParent(); + return false; + } + // Otherwise, can't handle this. return true; } From lauro.venancio at gmail.com Wed Jun 13 13:34:42 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Wed, 13 Jun 2007 15:34:42 -0300 Subject: [llvm-commits] proposed patch: shift when shift amount >= bit width In-Reply-To: References: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> Message-ID: <9c10c9f0706131134u58217bdcv6646b07623706bf1@mail.gmail.com> > > This is not enough to make a compiler handle shifts by greater than the > word size consistently; in both gcc and llvm-gcc, for example, the > result of > > int y=32; > x>>y > > depends on optimization level. I know. On x86, the result of int n = 32; 1<= bit width In-Reply-To: <9c10c9f0706131134u58217bdcv6646b07623706bf1@mail.gmail.com> References: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> <9c10c9f0706131134u58217bdcv6646b07623706bf1@mail.gmail.com> Message-ID: On Jun 13, 2007, at 11:34 AM, Lauro Ramos Venancio wrote: >> >> This is not enough to make a compiler handle shifts by greater >> than the >> word size consistently; in both gcc and llvm-gcc, for example, the >> result of >> >> int y=32; >> x>>y >> >> depends on optimization level. > > I know. On x86, the result of > int n = 32; > 1< > is 1 with "gcc -O0" and 0 with "gcc -O3". But some important programs > (like ffmpeg) use these shifts expecting the gcc behavior. The ffmpeg, > for example, works well with "gcc -O0" and "gcc -O3". So, for > compatibility purpose, I think we should implement the gcc behavior > and do not create another behavior. I don't think this is appropriate Lauro. The program needs to be fixed, it's not just a codegen or optimizer issue, everything in the compiler assumes that these shifts are undefined. Programs cannot reliably expect a compiler to do the right thing here, and your patch isn't a fix. -Chris From lauro.venancio at gmail.com Wed Jun 13 14:06:12 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Wed, 13 Jun 2007 16:06:12 -0300 Subject: [llvm-commits] proposed patch: shift when shift amount >= bit width In-Reply-To: References: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> <9c10c9f0706131134u58217bdcv6646b07623706bf1@mail.gmail.com> Message-ID: <9c10c9f0706131206s46ce357at574293f98b0a10d9@mail.gmail.com> > I don't think this is appropriate Lauro. The program needs to be > fixed, it's not just a codegen or optimizer issue, everything in the > compiler assumes that these shifts are undefined. Programs cannot > reliably expect a compiler to do the right thing here, and your patch > isn't a fix. Nowadays LLVM doesn't assume, in all places, that these shifts are undefined. See the following code (APInt.cpp): // If all the bits were shifted out, the result is 0. This avoids issues // with shifting by the size of the integer type, which produces undefined // results. We define these "undefined results" to always be 0. if (shiftAmt == BitWidth) return APInt(BitWidth, 0); and this code: // If all the bits were shifted out, the result is, technically, undefined. // We return -1 if it was negative, 0 otherwise. We check this early to avoid // issues in the algorithm below. if (shiftAmt == BitWidth) { if (isNegative()) return APInt(BitWidth, -1ULL); else return APInt(BitWidth, 0); } I think to implement the gcc behavior would make easier the migration from gcc to llvm. Lauro From clattner at apple.com Wed Jun 13 14:07:29 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 13 Jun 2007 12:07:29 -0700 Subject: [llvm-commits] proposed patch: shift when shift amount >= bit width In-Reply-To: <9c10c9f0706131206s46ce357at574293f98b0a10d9@mail.gmail.com> References: <9c10c9f0706121318s6c88d50ar4e8d7d3e4e0df97a@mail.gmail.com> <9c10c9f0706131134u58217bdcv6646b07623706bf1@mail.gmail.com> <9c10c9f0706131206s46ce357at574293f98b0a10d9@mail.gmail.com> Message-ID: On Jun 13, 2007, at 12:06 PM, Lauro Ramos Venancio wrote: >> I don't think this is appropriate Lauro. The program needs to be >> fixed, it's not just a codegen or optimizer issue, everything in the >> compiler assumes that these shifts are undefined. Programs cannot >> reliably expect a compiler to do the right thing here, and your patch >> isn't a fix. > > Nowadays LLVM doesn't assume, in all places, that these shifts are > undefined. > See the following code (APInt.cpp): > > // If all the bits were shifted out, the result is 0. This avoids > issues > // with shifting by the size of the integer type, which produces > undefined > // results. We define these "undefined results" to always be 0. > if (shiftAmt == BitWidth) > return APInt(BitWidth, 0); > > and this code: > > // If all the bits were shifted out, the result is, technically, > undefined. > // We return -1 if it was negative, 0 otherwise. We check this > early to avoid > // issues in the algorithm below. > if (shiftAmt == BitWidth) { > if (isNegative()) > return APInt(BitWidth, -1ULL); > else > return APInt(BitWidth, 0); > } > > I think to implement the gcc behavior would make easier the migration > from gcc to llvm. APInt can't return undef, so it has to pick a deterministic value. LLVM values are a different story. -Chris From clattner at apple.com Wed Jun 13 15:12:57 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 13 Jun 2007 13:12:57 -0700 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <200706131955.15130.baldrick@free.fr> References: <200706131955.15130.baldrick@free.fr> Message-ID: <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> On Jun 13, 2007, at 10:55 AM, Duncan Sands wrote: > Look for eh.filter and eh.selector intrinsics in the > successor to an empty (exception for a branch) landing pad. > The big FIXME comment explains more. Testcase included, > along with an XFAIL for a test which uses eh.selector in a > routine with no landing pads (not possible in llvm-gcc > generated code). Seems fine to me, minor comments: Please use SmallSet instead of std::set. + // Inform the MachineModuleInfo of the personality for this landing pad. + ConstantExpr *CE = dyn_cast(I.getOperand(2)); + assert(CE && CE->getOpcode() == Instruction::BitCast && Please just use cast<> instead of dyn_cast, which guarantees no null return. + if (Br && Br->isUnconditional() && LLVMBB->size() == 1) { + // Smells like a critical edge: look for eh intrinsics in the successor. + BasicBlock *S = Br->getSuccessor(0); + + assert(!FuncInfo.MBBMap[S]->isLandingPad() && + "Chained landing pads!"); + for (BasicBlock::iterator I = S->begin(), E = --S->end(); I ! = E; ++I) + if (CallInst *C = dyn_cast(I)) + if (Function *F = C->getCalledFunction()) + if (F->isDeclaration()) + if (unsigned IID = F->getIntrinsicID()) + if (IID == Intrinsic::eh_selector || + IID == Intrinsic::eh_filter) { + addCatchInfo(*C, MMI, BB, IID == Intrinsic::eh_filter); +#ifndef NDEBUG + FuncInfo.SelectorsFound.insert(C); +#endif + } Please split this out into a helper predicate function. Inside the loop, please use continue to avoid nesting so much: if (!F->isDeclaration()) continue; ... if (IID != .. && IID != ..) continue; -Chris From christopher.lamb at gmail.com Wed Jun 13 17:20:38 2007 From: christopher.lamb at gmail.com (Christopher Lamb) Date: Wed, 13 Jun 2007 17:20:38 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp CodeGenTarget.cpp CodeGenRegisters.h Message-ID: <200706132220.l5DMKcHV013124@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.56 -> 1.57 CodeGenTarget.cpp updated: 1.91 -> 1.92 CodeGenRegisters.h updated: 1.11 -> 1.12 --- Log message: Add support to tablegen for specifying subregister classes on a per register class basis. --- Diffs of the changes: (+50 -0) CodeGenRegisters.h | 1 + CodeGenTarget.cpp | 10 ++++++++++ RegisterInfoEmitter.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.56 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.57 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.56 Mon Jun 4 18:52:59 2007 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Wed Jun 13 17:20:15 2007 @@ -224,6 +224,44 @@ std::map > SuperClassMap; OS << "\n"; + + + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Sub-register Classess...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses [] = {\n "; + + bool Empty = true; + + for (unsigned subrc = 0, e2 = RC.SubRegClasses.size(); + subrc != e2; ++subrc) { + unsigned rc2 = 0, e2 = RegisterClasses.size(); + for (; rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + if (!Empty) OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + break; + } + } + if (rc2 == e2) + throw "Register Class member '" + + RC.SubRegClasses[subrc]->getName() + + "' is not a valid RegisterClass!"; + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; @@ -304,6 +342,7 @@ << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " + << RC.getName() + "SubRegClasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.91 llvm/utils/TableGen/CodeGenTarget.cpp:1.92 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.91 Wed Jun 6 05:14:55 2007 +++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Jun 13 17:20:15 2007 @@ -199,6 +199,16 @@ Elements.push_back(Reg); } + std::vector SubRegClassList = + R->getValueAsListOfDefs("SubRegClassList"); + for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) { + Record *SubRegClass = SubRegClassList[i]; + if (!SubRegClass->isSubClassOf("RegisterClass")) + throw "Register Class member '" + SubRegClass->getName() + + "' does not derive from the RegisterClass class!"; + SubRegClasses.push_back(SubRegClass); + } + // Allow targets to override the size in bits of the RegisterClass. unsigned Size = R->getValueAsInt("Size"); Index: llvm/utils/TableGen/CodeGenRegisters.h diff -u llvm/utils/TableGen/CodeGenRegisters.h:1.11 llvm/utils/TableGen/CodeGenRegisters.h:1.12 --- llvm/utils/TableGen/CodeGenRegisters.h:1.11 Thu Dec 29 18:12:56 2005 +++ llvm/utils/TableGen/CodeGenRegisters.h Wed Jun 13 17:20:15 2007 @@ -38,6 +38,7 @@ std::vector VTs; unsigned SpillSize; unsigned SpillAlignment; + std::vector SubRegClasses; std::string MethodProtos, MethodBodies; const std::string &getName() const; From christopher.lamb at gmail.com Wed Jun 13 17:20:43 2007 From: christopher.lamb at gmail.com (Christopher Lamb) Date: Wed, 13 Jun 2007 17:20:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200706132220.l5DMKhur013131@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.102 -> 1.103 --- Log message: Add support to tablegen for specifying subregister classes on a per register class basis. --- Diffs of the changes: (+4 -0) Target.td | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.102 llvm/lib/Target/Target.td:1.103 --- llvm/lib/Target/Target.td:1.102 Wed Jun 6 05:15:28 2007 +++ llvm/lib/Target/Target.td Wed Jun 13 17:20:15 2007 @@ -109,6 +109,10 @@ // allocation used by the register allocator. // list MemberList = regList; + + // SubClassList - Specify which register classes correspond to subregisters + // of this class. The order should be by subregister set index. + list SubRegClassList = []; // MethodProtos/MethodBodies - These members can be used to insert arbitrary // code into a generated register class. The normal usage of this is to From christopher.lamb at gmail.com Wed Jun 13 17:20:44 2007 From: christopher.lamb at gmail.com (Christopher Lamb) Date: Wed, 13 Jun 2007 17:20:44 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200706132220.l5DMKiq0013136@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.110 -> 1.111 --- Log message: Add support to tablegen for specifying subregister classes on a per register class basis. --- Diffs of the changes: (+44 -0) MRegisterInfo.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 44 insertions(+) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.110 llvm/include/llvm/Target/MRegisterInfo.h:1.111 --- llvm/include/llvm/Target/MRegisterInfo.h:1.110 Tue May 1 03:58:27 2007 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Jun 13 17:20:15 2007 @@ -64,6 +64,7 @@ const vt_iterator VTs; const sc_iterator SubClasses; const sc_iterator SuperClasses; + const sc_iterator SubRegClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: @@ -71,8 +72,10 @@ const MVT::ValueType *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, + const TargetRegisterClass * const *subregcs, unsigned RS, unsigned Al, iterator RB, iterator RE) : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs), + SubRegClasses(subregcs), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses @@ -167,6 +170,47 @@ return I; } + /// hasSubRegForClass - return true if the specified TargetRegisterClass is a + /// class of a sub-register class for this TargetRegisterClass. + bool hasSubRegForClass(const TargetRegisterClass *cs) const { + for (int i = 0; SubRegClasses[i] != NULL; ++i) + if (SubRegClasses[i] == cs) + return true; + return false; + } + + /// hasClassForSubReg - return true if the specified TargetRegisterClass is a + /// class of a sub-register class for this TargetRegisterClass. + bool hasClassForSubReg(unsigned SubReg) const { + --SubReg; + for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) + if (i == SubReg) + return true; + return false; + } + + /// getClassForSubReg - return theTargetRegisterClass for the sub-register + /// at idx for this TargetRegisterClass. + sc_iterator getClassForSubReg(unsigned SubReg) const { + --SubReg; + for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) + if (i == SubReg) + return &SubRegClasses[i]; + return NULL; + } + + /// subregclasses_begin / subregclasses_end - Loop over all of + /// the subregister classes of this register class. + sc_iterator subregclasses_begin() const { + return SubRegClasses; + } + + sc_iterator subregclasses_end() const { + sc_iterator I = SubRegClasses; + while (*I != NULL) ++I; + return I; + } + /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register /// allocate, and the preferred order to allocate them in. For example, From sabre at nondot.org Wed Jun 13 19:42:36 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 19:42:36 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-10-ICNPC-ScalingTaskGraphs.html 2006-10-ICNPC-ScalingTaskGraphs.pdf index.html Message-ID: <200706140042.l5E0gaHf016209@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2006-10-ICNPC-ScalingTaskGraphs.html added (r1.1) 2006-10-ICNPC-ScalingTaskGraphs.pdf added (r1.1) index.html updated: 1.50 -> 1.51 --- Log message: add a new paper --- Diffs of the changes: (+65 -0) 2006-10-ICNPC-ScalingTaskGraphs.html | 58 +++++++++++++++++++++++++++++++++++ 2006-10-ICNPC-ScalingTaskGraphs.pdf | 0 index.html | 7 ++++ 3 files changed, 65 insertions(+) Index: llvm-www/pubs/2006-10-ICNPC-ScalingTaskGraphs.html diff -c /dev/null llvm-www/pubs/2006-10-ICNPC-ScalingTaskGraphs.html:1.1 *** /dev/null Wed Jun 13 19:42:25 2007 --- llvm-www/pubs/2006-10-ICNPC-ScalingTaskGraphs.html Wed Jun 13 19:42:15 2007 *************** *** 0 **** --- 1,58 ---- + + + + + + Scaling Task Graphs for Network Processors + + + + +
+ Scaling Task Graphs for Network Processors +
+ +
+ Martin Labrecque and J. Gregory Steffan +
+ +

Abstract:

+
+ Modern network processors (NPs) are highly multithreaded chip multiprocessors (CMPs), supporting + a wide variety of mechanisms for on-chip storage and inter-task communication. Real network processor + applications are hard to program and must be tailored to fit the resources of the underlying NP, motivating + an automated approach to mapping multithreaded applications to NPs. In this paper we propose and evaluate + compiler-based automated task and data management techniques to scale the throughput of network + processing task graphs onto NPs. We evaluate these techniques using a NP simulation infrastructure based + on realistic NP applications, and present an approach to discovering performance bottlenecks. Finally we + demonstrate how our techniques enhance throughput-scaling for NPs. +
+ +

Published:

+
+ "Scaling Task Graphs for Network Processors"
+ Martin Labrecque and J. Gregory Steffan
+ IFIP International Conference on Network and Parallel Computing, Tokyo, + Japan, October, 2006.
+
+ +

Download:

+ + +

BibTeX Entry:

+
+ @INPROCEEDINGS{scaling06,
+   author = {Martin Labrecque and J. Gregory Steffan},
+   title = {Scaling Task Graphs for Network Processors},
+   booktitle = {IFIP International Conference on Network and Parallel Computing},
+   year = {2006},
+   address = {Tokyo, Japan},
+   month = {October},
+ }
+ 
+ + + Index: llvm-www/pubs/2006-10-ICNPC-ScalingTaskGraphs.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.50 llvm-www/pubs/index.html:1.51 --- llvm-www/pubs/index.html:1.50 Wed May 30 06:39:00 2007 +++ llvm-www/pubs/index.html Wed Jun 13 19:42:15 2007 @@ -40,6 +40,13 @@ 2007 Bossa Conference on Open Source, Mobile Internet and Multimedia, Recife, Brazil, March 2007.
+
  • "Scaling Task Graphs for + Network Processors"
    + Martin Labrecque and J. Gregory Steffan
    + IFIP International Conference on Network and Parallel Computing, Tokyo, + Japan, October, 2006.
  • + +
  • "A Virtual Instruction Set Interface for Operating System Kernels"
    John Criswell, Brent Monroe, and Vikram Adve.
    Workshop on the Interaction between Operating Systems and Computer Architecture (WIOSCA '06), Boston, Massachusetts, 2006.
  • From sabre at nondot.org Wed Jun 13 19:48:59 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 19:48:59 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-01-LabrecqueMSThesis.html 2006-01-LabrecqueMSThesis.pdf index.html Message-ID: <200706140048.l5E0mxn1016411@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2006-01-LabrecqueMSThesis.html added (r1.1) 2006-01-LabrecqueMSThesis.pdf added (r1.1) index.html updated: 1.51 -> 1.52 --- Log message: add an llvm-using thesis --- Diffs of the changes: (+62 -0) 2006-01-LabrecqueMSThesis.html | 55 +++++++++++++++++++++++++++++++++++++++++ 2006-01-LabrecqueMSThesis.pdf | 0 index.html | 7 +++++ 3 files changed, 62 insertions(+) Index: llvm-www/pubs/2006-01-LabrecqueMSThesis.html diff -c /dev/null llvm-www/pubs/2006-01-LabrecqueMSThesis.html:1.1 *** /dev/null Wed Jun 13 19:48:47 2007 --- llvm-www/pubs/2006-01-LabrecqueMSThesis.html Wed Jun 13 19:48:37 2007 *************** *** 0 **** --- 1,55 ---- + + + + + + Towards a Compilation Infrastructure for Network Processors + + + +
    + Towards a Compilation Infrastructure for Network Processors +
    +
    + Martin Labrecque, M.S. Thesis +
    + + +

    Abstract:

    +
    +

    + Modern network processors (NPs) typically resemble a highly-multithreaded multiprocessor-on- + a-chip, supporting a wide variety of mechanisms for on-chip storage and inter-task communication. + NP applications are themselves composed of many threads that share memory and other resources, + and synchronize and communicate frequently. In contrast, studies of new NP architectures and fea- + tures are often performed by benchmarking a simulation model of the new NP using independent + kernel programs that neither communicate nor share memory. In this paper we present a NP sim- + ulation infrastructure that (i) uses realistic NP applications that are multithreaded, share memory, + synchronize, and communicate; and (ii) automatically maps these applications to a variety of NP + architectures and features. We use our infrastructure to evaluate threading and scaling, on-chip + storage and communication, and to suggest future techniques for automated compilation for NPs.

    +
    + +

    Published:

    +
    + "Towards a Compilation Infrastructure for Network Processors"
    + Martin Labrecque
    + Masters Thesis, Department of Electrical and Computer Engineering, University of Toronto, January, 2006. +
    + +

    Download:

    + + +

    BibTeX Entry:

    +
    + @MASTERSTHESIS{np_thesis06,
    +   author = {Martin Labrecque},
    +   title = {Towards a Compilation Infrastructure for Network Processors},
    +   school = {University of Toronto},
    +   year = {2006},
    + }
    + + + Index: llvm-www/pubs/2006-01-LabrecqueMSThesis.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.51 llvm-www/pubs/index.html:1.52 --- llvm-www/pubs/index.html:1.51 Wed Jun 13 19:42:15 2007 +++ llvm-www/pubs/index.html Wed Jun 13 19:48:37 2007 @@ -61,6 +61,13 @@
  • "Tailoring Graph-coloring Register Allocation For Runtime Compilation"
    Keith D. Cooper and Anshuman Dasgupta
    Proc. of the 2006 International Symposium on Code Generation and Optimization (CGO'06), New York, New York, 2006.
  • + +
  • "Towards a Compilation Infrastructure for Network Processors"
    +Martin Labrecque
    +Masters Thesis, Department of Electrical and Computer Engineering, University of Toronto, January, 2006.
  • + + +
  • "How Successful is Data Structure Analysis in Isolating and Analyzing Linked Data Structures?"
    Patrick Meredith, Balpreet Pankaj, Swarup Sahoo, Chris Lattner and Vikram Adve
    Technical Report #UIUCDCS-R-2005-2658, Computer Science Dept., Univ. of Illinois, Dec. 2005.
  • From sabre at nondot.org Wed Jun 13 19:57:12 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 19:57:12 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-09-SOC-Synthesis.html 2006-09-SOC-Synthesis.pdf index.html Message-ID: <200706140057.l5E0vCdU016603@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2006-09-SOC-Synthesis.html added (r1.1) 2006-09-SOC-Synthesis.pdf added (r1.1) index.html updated: 1.52 -> 1.53 --- Log message: add another paper --- Diffs of the changes: (+60 -0) 2006-09-SOC-Synthesis.html | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2006-09-SOC-Synthesis.pdf | 0 index.html | 3 ++ 3 files changed, 60 insertions(+) Index: llvm-www/pubs/2006-09-SOC-Synthesis.html diff -c /dev/null llvm-www/pubs/2006-09-SOC-Synthesis.html:1.1 *** /dev/null Wed Jun 13 19:57:03 2007 --- llvm-www/pubs/2006-09-SOC-Synthesis.html Wed Jun 13 19:56:53 2007 *************** *** 0 **** --- 1,57 ---- + + + + + + Platform-Based Behavior-Level and System-Level Synthesis + + + + +
    + Platform-Based Behavior-Level and System-Level Synthesis +
    + +
    + J. Cong, Y. Fan, G. Han, W. Jiang, and Z. Zhang +
    + +

    Abstract:

    +
    + With the rapid increase of complexity in System-on-a-Chip (SoC) design, + the electronic design automation (EDA) + community is moving from RTL (Register Transfer Level) + synthesis to behavioral-level and system-level synthesis. The + needs of system-level verification and software/hardware co- + design also prefer behavior-level executable specifications, such + as C or SystemC. In this paper we present the platform-based + synthesis system, named xPilot, being developed at UCLA. The + first objective of xPilot is to provide novel behavioral synthesis + capability for automatically generating efficient RTL code from + a C or SystemC description for a given system platform and + optimizing the logic, interconnects, performance, and power + simultaneously. The second objective of xPilot is to provide a + platform-based system-level synthesis capability, including both + synthesis for application-specific configurable processors and + heterogeneous multi-core systems. Preliminary experiments on + FPGAs demonstrate the efficacy of our approach on a wide range + of applications and its value in exploring various design tradeoffs. + +
    + +

    Published:

    +
    + "Platform-Based Behavior-Level and System-Level Synthesis"
    + J. Cong, Y. Fan, G. Han, W. Jiang, and Z. Zhang
    + Proceedings of IEEE International SOC Conference, pp. 199-202, Austin, Texas, Sept. 2006. +
    + +

    Download:

    + + + + + Index: llvm-www/pubs/2006-09-SOC-Synthesis.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.52 llvm-www/pubs/index.html:1.53 --- llvm-www/pubs/index.html:1.52 Wed Jun 13 19:48:37 2007 +++ llvm-www/pubs/index.html Wed Jun 13 19:56:53 2007 @@ -46,6 +46,9 @@ IFIP International Conference on Network and Parallel Computing, Tokyo, Japan, October, 2006. +
  • "Platform-Based Behavior-Level and System-Level Synthesis"
    +J. Cong, Y. Fan, G. Han, W. Jiang, and Z. Zhang
    +Proceedings of IEEE International SOC Conference, pp. 199-202, Austin, Texas, Sept. 2006.
  • "A Virtual Instruction Set Interface for Operating System Kernels"
    John Criswell, Brent Monroe, and Vikram Adve.
    Workshop on the Interaction between Operating Systems and Computer Architecture (WIOSCA '06), Boston, Massachusetts, 2006.
  • From sabre at nondot.org Wed Jun 13 20:14:37 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 20:14:37 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2005-07-ZimmermanMSThesis.html 2005-07-ZimmermanMSThesis.pdf index.html Message-ID: <200706140114.l5E1Eb5P016975@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2005-07-ZimmermanMSThesis.html added (r1.1) 2005-07-ZimmermanMSThesis.pdf added (r1.1) index.html updated: 1.53 -> 1.54 --- Log message: another ms thesis --- Diffs of the changes: (+39 -0) 2005-07-ZimmermanMSThesis.html | 33 +++++++++++++++++++++++++++++++++ 2005-07-ZimmermanMSThesis.pdf | 0 index.html | 6 ++++++ 3 files changed, 39 insertions(+) Index: llvm-www/pubs/2005-07-ZimmermanMSThesis.html diff -c /dev/null llvm-www/pubs/2005-07-ZimmermanMSThesis.html:1.1 *** /dev/null Wed Jun 13 20:14:24 2007 --- llvm-www/pubs/2005-07-ZimmermanMSThesis.html Wed Jun 13 20:14:14 2007 *************** *** 0 **** --- 1,33 ---- + + + + + + Profile-directed If-Conversion in Superscalar Microprocessors + + + +
    + Profile-directed If-Conversion in Superscalar Microprocessors +
    +
    + Eric Zimmerman, M.S. Thesis +
    + + +

    Published:

    +
    + "Profile-directed If-Conversion in Superscalar Microprocessors"
    + Eric Zimmerman
    + Masters Thesis, Computer Science Dept., University of Illinois at + Urbana-Champaign, July 2005. +
    + +

    Download:

    + + + + Index: llvm-www/pubs/2005-07-ZimmermanMSThesis.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.53 llvm-www/pubs/index.html:1.54 --- llvm-www/pubs/index.html:1.53 Wed Jun 13 19:56:53 2007 +++ llvm-www/pubs/index.html Wed Jun 13 20:14:14 2007 @@ -106,6 +106,12 @@ Proceedings of the 9th International Database Engineering & Application Sy mposium (IDEAS'05), July 2005. +
  • "Profile-directed If-Conversion in + Superscalar Microprocessors"
    +Eric Zimmerman
    +Masters Thesis, Computer Science Dept., University of Illinois at +Urbana-Champaign, July 2005.
  • +
  • "An Implementation of Swing Modulo Scheduling with Extensions for Superblocks"
    Tanya M. Lattner.
    M.S. Thesis, Computer Science Dept., University of Illinois at From sabre at nondot.org Wed Jun 13 20:24:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 20:24:46 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-10-CASES-IncreaseMem.html 2006-10-CASES-IncreaseMem.pdf index.html Message-ID: <200706140124.l5E1OkoK017279@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2006-10-CASES-IncreaseMem.html added (r1.1) 2006-10-CASES-IncreaseMem.pdf added (r1.1) index.html updated: 1.54 -> 1.55 --- Log message: add another paper --- Diffs of the changes: (+60 -0) 2006-10-CASES-IncreaseMem.html | 54 +++++++++++++++++++++++++++++++++++++++++ 2006-10-CASES-IncreaseMem.pdf | 0 index.html | 6 ++++ 3 files changed, 60 insertions(+) Index: llvm-www/pubs/2006-10-CASES-IncreaseMem.html diff -c /dev/null llvm-www/pubs/2006-10-CASES-IncreaseMem.html:1.1 *** /dev/null Wed Jun 13 20:24:33 2007 --- llvm-www/pubs/2006-10-CASES-IncreaseMem.html Wed Jun 13 20:24:23 2007 *************** *** 0 **** --- 1,54 ---- + + + + + + Automated Compile-Time and Run-Time Techniques to Increase Usable Memory in MMU-Less Embedded Systems + + + + +
    + Automated Compile-Time and Run-Time Techniques to Increase Usable Memory in MMU-Less Embedded Systems
    + +
    + L. Bai, L. Yang, and R. P. Dick +
    + +

    Abstract:

    +
    + Random access memory (RAM) is tightly-constrained in many + embedded systems. This is especially true for the least expensive, lowest-power embedded systems, such as sensor network + nodes and portable consumer electronics. The most widely-used sensor network nodes have only 4?10 KB of RAM and + do not contain memory management units (MMUs). It is very + difficult to implement increasingly complex applications under + such tight memory constraints. Nonetheless, price and power + consumption constraints make it unlikely that increases in RAM + in these systems will keep pace with the requirements of applications.

    + + We propose the use of automated compile-time and run-time + techniques to increase the amount of usable memory in MMU-less embedded systems. The proposed techniques do not in- + crease hardware cost, and are designed to require few or no + changes to existing applications. We have developed a fast compression algorithm well suited to this application, as well as run-time library routines and compiler transformations to control + and optimize the automatic migration of application data between compressed and uncompressed memory regions. These + techniques were experimentally evaluated on Crossbow TelosB + sensor network nodes running a number of data collection and + signal processing applications. The results indicate that available memory can be increased by up to 50% with less than 10% + performance degradation for most benchmarks. +

    + +

    Published:

    +
    + "Automated Compile-Time and Run-Time Techniques to Increase Usable Memory in MMU-Less Embedded Systems"
    + L. Bai, L. Yang, and R. P. Dick
    + Proc. Int. Conf. Compilers, Architecture & Synthesis for Embedded Systems, + pp. 125-135, Oct. 2006.
    +
    + +

    Download:

    + + + + Index: llvm-www/pubs/2006-10-CASES-IncreaseMem.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.54 llvm-www/pubs/index.html:1.55 --- llvm-www/pubs/index.html:1.54 Wed Jun 13 20:14:14 2007 +++ llvm-www/pubs/index.html Wed Jun 13 20:24:23 2007 @@ -46,6 +46,12 @@ IFIP International Conference on Network and Parallel Computing, Tokyo, Japan, October, 2006.
  • +
  • "Automated Compile-Time and +Run-Time Techniques to Increase Usable Memory in MMU-Less Embedded Systems"
    +L. Bai, L. Yang, and R. P. Dick
    +Proc. Int. Conf. Compilers, Architecture & Synthesis for Embedded Systems, +pp. 125-135, Oct. 2006.
  • +
  • "Platform-Based Behavior-Level and System-Level Synthesis"
    J. Cong, Y. Fan, G. Han, W. Jiang, and Z. Zhang
    Proceedings of IEEE International SOC Conference, pp. 199-202, Austin, Texas, Sept. 2006.
  • From nicholas at mxc.ca Wed Jun 13 20:33:49 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 13 Jun 2007 21:33:49 -0400 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-10-CASES-IncreaseMem.html 2006-10-CASES-IncreaseMem.pdf index.html In-Reply-To: <200706140124.l5E1OkoK017279@zion.cs.uiuc.edu> References: <200706140124.l5E1OkoK017279@zion.cs.uiuc.edu> Message-ID: <46709AFD.8000403@mxc.ca> Chris Lattner wrote: > have only 4?10 KB of RAM and – ? Nick From sabre at nondot.org Wed Jun 13 20:37:11 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 20:37:11 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2006-10-CASES-IncreaseMem.html Message-ID: <200706140137.l5E1bBwG017521@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2006-10-CASES-IncreaseMem.html updated: 1.1 -> 1.2 --- Log message: fix a unicode character --- Diffs of the changes: (+1 -1) 2006-10-CASES-IncreaseMem.html | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/pubs/2006-10-CASES-IncreaseMem.html diff -u llvm-www/pubs/2006-10-CASES-IncreaseMem.html:1.1 llvm-www/pubs/2006-10-CASES-IncreaseMem.html:1.2 --- llvm-www/pubs/2006-10-CASES-IncreaseMem.html:1.1 Wed Jun 13 20:24:23 2007 +++ llvm-www/pubs/2006-10-CASES-IncreaseMem.html Wed Jun 13 20:36:49 2007 @@ -19,7 +19,7 @@
    Random access memory (RAM) is tightly-constrained in many embedded systems. This is especially true for the least expensive, lowest-power embedded systems, such as sensor network -nodes and portable consumer electronics. The most widely-used sensor network nodes have only 4?10 KB of RAM and +nodes and portable consumer electronics. The most widely-used sensor network nodes have only 4-10 KB of RAM and do not contain memory management units (MMUs). It is very difficult to implement increasingly complex applications under such tight memory constraints. Nonetheless, price and power From sabre at nondot.org Wed Jun 13 20:42:41 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jun 2007 20:42:41 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2005-09-PASTE-GreedySuiteMinimization.html 2005-09-PASTE-GreedySuiteMinimization.pdf index.html Message-ID: <200706140142.l5E1gfYM017680@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2005-09-PASTE-GreedySuiteMinimization.html added (r1.1) 2005-09-PASTE-GreedySuiteMinimization.pdf added (r1.1) index.html updated: 1.55 -> 1.56 --- Log message: new paper --- Diffs of the changes: (+59 -1) 2005-09-PASTE-GreedySuiteMinimization.html | 52 +++++++++++++++++++++++++++++ 2005-09-PASTE-GreedySuiteMinimization.pdf | 0 index.html | 8 +++- 3 files changed, 59 insertions(+), 1 deletion(-) Index: llvm-www/pubs/2005-09-PASTE-GreedySuiteMinimization.html diff -c /dev/null llvm-www/pubs/2005-09-PASTE-GreedySuiteMinimization.html:1.1 *** /dev/null Wed Jun 13 20:42:29 2007 --- llvm-www/pubs/2005-09-PASTE-GreedySuiteMinimization.html Wed Jun 13 20:42:19 2007 *************** *** 0 **** --- 1,52 ---- + + + + + + A Concept Analysis Inspired Greedy Algorithm for Test Suite Minimization + + + + +
    + A Concept Analysis Inspired Greedy Algorithm for Test Suite Minimization +
    + +
    + Sriraman Tallam and Neelam Gupta +
    + +

    Abstract:

    +
    + Software testing and retesting occurs continuously during the software development lifecycle to detect errors as early as possible and + to ensure that changes to existing software do not break the software. Test suites once developed are reused and updated frequently + as the software evolves. As a result, some test cases in the test suite + may become redundant as the software is modified over time since + the requirements covered by them are also covered by other test + cases. Due to the resource and time constraints for re-executing + large test suites, it is important to develop techniques to minimize + available test suites by removing redundant test cases. In general, + the test suite minimization problem is NP complete. In this paper, + we present a new greedy heuristic algorithm for selecting a minimal + subset of a test suite T that covers all the requirements covered by + T. We show how our algorithm was inspired by the concept analysis framework. We conducted experiments to measure the extent of + test suite reduction obtained by our algorithm and prior heuristics + for test suite minimization. In our experiments, our algorithm always selected same size or smaller size test suite than that selected + by prior heuristics and had comparable time performance. +
    + +

    Published:

    +
    + "A Concept Analysis Inspired Greedy Algorithm for Test Suite Minimization"
    + By Sriraman Tallam and Neelam Gupta
    + ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and + Engineering (PASTE 2005), Lisbon, Portugal, September 5-6, 2005. +
    + +

    Download:

    + + + + Index: llvm-www/pubs/2005-09-PASTE-GreedySuiteMinimization.pdf Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.55 llvm-www/pubs/index.html:1.56 --- llvm-www/pubs/index.html:1.55 Wed Jun 13 20:24:23 2007 +++ llvm-www/pubs/index.html Wed Jun 13 20:42:19 2007 @@ -100,7 +100,13 @@ Proc. of the ACM International Conference on Compilers, Architecture, and Synthesis for Embedded Systems (CASES'05), San Francisco, CA, September, 2005 - + +
  • " +A Concept Analysis Inspired Greedy Algorithm for Test Suite Minimization"
    +By Sriraman Tallam and Neelam Gupta
    +ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and +Engineering (PASTE 2005), Lisbon, Portugal, September 5-6, 2005.
  • +
  • "Deciding Where to Call Performance Libraries"
    From baldrick at free.fr Thu Jun 14 00:51:03 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 14 Jun 2007 07:51:03 +0200 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> References: <200706131955.15130.baldrick@free.fr> <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> Message-ID: <200706140751.04402.baldrick@free.fr> Hi Chris, > + // Inform the MachineModuleInfo of the personality for this > landing pad. > + ConstantExpr *CE = dyn_cast(I.getOperand(2)); > + assert(CE && CE->getOpcode() == Instruction::BitCast && > > Please just use cast<> instead of dyn_cast, which guarantees no null > return. but then you don't get the helpful assertion message. > Please split this out into a helper predicate function. Inside the > loop, please use continue to avoid nesting so much: > > if (!F->isDeclaration()) continue; > ... > if (IID != .. && IID != ..) continue; I deliberately made it ugly because it is a horrible hack - that way you will be motivated to get rid of it by redesigning exception handling! I will prettify it. Ciao, Duncan. From clattner at apple.com Thu Jun 14 00:58:57 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 13 Jun 2007 22:58:57 -0700 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <200706140751.04402.baldrick@free.fr> References: <200706131955.15130.baldrick@free.fr> <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> <200706140751.04402.baldrick@free.fr> Message-ID: <2A24AB02-DED2-40A1-8B81-502EED137BD6@apple.com> On Jun 13, 2007, at 10:51 PM, Duncan Sands wrote: > Hi Chris, > >> + // Inform the MachineModuleInfo of the personality for this >> landing pad. >> + ConstantExpr *CE = dyn_cast(I.getOperand(2)); >> + assert(CE && CE->getOpcode() == Instruction::BitCast && >> >> Please just use cast<> instead of dyn_cast, which guarantees no null >> return. > > but then you don't get the helpful assertion message. Sure, but in release builds, you pay a cost :) -Chris From baldrick at free.fr Thu Jun 14 06:27:30 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 14 Jun 2007 06:27:30 -0500 Subject: [llvm-commits] CVS: llvm/docs/SourceLevelDebugging.html Message-ID: <200706141127.l5EBRUkj006608@zion.cs.uiuc.edu> Changes in directory llvm/docs: SourceLevelDebugging.html updated: 1.28 -> 1.29 --- Log message: Fix typos. --- Diffs of the changes: (+3 -3) SourceLevelDebugging.html | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/docs/SourceLevelDebugging.html diff -u llvm/docs/SourceLevelDebugging.html:1.28 llvm/docs/SourceLevelDebugging.html:1.29 --- llvm/docs/SourceLevelDebugging.html:1.28 Wed Mar 14 14:31:55 2007 +++ llvm/docs/SourceLevelDebugging.html Thu Jun 14 06:27:07 2007 @@ -747,7 +747,7 @@

    This intrinsic is used to provide correspondence between the source file and the generated code. The first argument is the line number (base 1), second -argument si the column number (0 if unknown) and the third argument the source +argument is the column number (0 if unknown) and the third argument the source %llvm.dbg.compile_unit* cast to a { }*. Code following a call to this intrinsic will have been defined in close proximity of the line, column and file. This information holds until @@ -991,7 +991,7 @@

    It is worth noting that this scoping mechanism is used to control scoping of all declarations, not just variable declarations. For example, the scope of a -C++ using declaration is controlled with this couldchange how name lookup is +C++ using declaration is controlled with this and could change how name lookup is performed.

  • @@ -1775,7 +1775,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2007/03/14 19:31:55 $ + Last modified: $Date: 2007/06/14 11:27:07 $ From djg at cray.com Thu Jun 14 10:00:52 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 10:00:52 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp Message-ID: <200706141500.l5EF0q9p011301@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.106 -> 1.107 X86AsmPrinter.cpp updated: 1.242 -> 1.243 --- Log message: Eliminate some redundant newlines in asm output. --- Diffs of the changes: (+2 -3) X86ATTAsmPrinter.cpp | 4 ++-- X86AsmPrinter.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.106 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.107 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.106 Mon Jun 4 13:54:57 2007 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Thu Jun 14 10:00:27 2007 @@ -59,10 +59,10 @@ if (Subtarget->isTargetDarwin()) { return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions"; } else if (Subtarget->isTargetCygMing()) { - return "\t.section\t.text$linkonce." + CurrentFnName + ",\"ax\"\n"; + return "\t.section\t.text$linkonce." + CurrentFnName + ",\"ax\""; } else { return "\t.section\t.llvm.linkonce.t." + CurrentFnName + - ",\"ax\", at progbits\n"; + ",\"ax\", at progbits"; } } } Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.242 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.243 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.242 Sat May 5 04:04:50 2007 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Thu Jun 14 10:00:27 2007 @@ -307,7 +307,6 @@ ExtWeakSymbols.insert(GV); EmitGlobalConstant(C); - O << '\n'; } // Output linker support code for dllexported globals From djg at cray.com Thu Jun 14 10:00:56 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 10:00:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetAsmInfo.cpp Message-ID: <200706141500.l5EF0uBo011306@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetAsmInfo.cpp updated: 1.27 -> 1.28 --- Log message: Eliminate some redundant newlines in asm output. --- Diffs of the changes: (+2 -2) TargetAsmInfo.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetAsmInfo.cpp diff -u llvm/lib/Target/TargetAsmInfo.cpp:1.27 llvm/lib/Target/TargetAsmInfo.cpp:1.28 --- llvm/lib/Target/TargetAsmInfo.cpp:1.27 Sat May 5 04:04:50 2007 +++ llvm/lib/Target/TargetAsmInfo.cpp Thu Jun 14 10:00:27 2007 @@ -55,8 +55,8 @@ TextSectionStartSuffix(""), DataSectionStartSuffix(""), SectionEndDirectiveSuffix(0), - ConstantPoolSection("\t.section .rodata\n"), - JumpTableDataSection("\t.section .rodata\n"), + ConstantPoolSection("\t.section .rodata"), + JumpTableDataSection("\t.section .rodata"), JumpTableDirective(0), CStringSection(0), StaticCtorsSection("\t.section .ctors,\"aw\", at progbits"), From djg at cray.com Thu Jun 14 10:00:57 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 10:00:57 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetAsmInfo.h Message-ID: <200706141500.l5EF0vSX011313@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetAsmInfo.h updated: 1.33 -> 1.34 --- Log message: Eliminate some redundant newlines in asm output. --- Diffs of the changes: (+2 -2) TargetAsmInfo.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Target/TargetAsmInfo.h diff -u llvm/include/llvm/Target/TargetAsmInfo.h:1.33 llvm/include/llvm/Target/TargetAsmInfo.h:1.34 --- llvm/include/llvm/Target/TargetAsmInfo.h:1.33 Sat May 5 04:04:50 2007 +++ llvm/include/llvm/Target/TargetAsmInfo.h Thu Jun 14 10:00:27 2007 @@ -178,12 +178,12 @@ /// ConstantPoolSection - This is the section that we SwitchToSection right /// before emitting the constant pool for a function. - const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n" + const char *ConstantPoolSection; // Defaults to "\t.section .rodata" /// JumpTableDataSection - This is the section that we SwitchToSection right /// before emitting the jump tables for a function when the relocation model /// is not PIC. - const char *JumpTableDataSection; // Defaults to "\t.section .rodata\n" + const char *JumpTableDataSection; // Defaults to "\t.section .rodata" /// JumpTableDirective - if non-null, the directive to emit before a jump /// table. From evan.cheng at apple.com Thu Jun 14 15:29:14 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 14 Jun 2007 15:29:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706142029.l5EKTEmZ017884@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.46 -> 1.47 --- Log message: Fix some stupid bugs that have effectively disabled if-conversion. --- Diffs of the changes: (+7 -1) IfConversion.cpp | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.46 llvm/lib/CodeGen/IfConversion.cpp:1.47 --- llvm/lib/CodeGen/IfConversion.cpp:1.46 Tue Jun 12 19:04:00 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Thu Jun 14 15:28:52 2007 @@ -208,6 +208,7 @@ // marked dead (due to it being predicated), then skip it. if (!BBI.IsEnqueued || BBI.IsDone) continue; + BBI.IsEnqueued = false; bool RetVal = false; switch (BBI.Kind) { @@ -625,6 +626,7 @@ case ICTriangleFalse: case ICTriangleFRev: case ICDiamond: + BBI.IsEnqueued = true; Candidates.push_back(&BBI); break; default: @@ -660,7 +662,7 @@ E = BB->pred_end(); PI != E; ++PI) { BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()]; if (!PBBI.IsDone && PBBI.Kind == ICNotClassfied) { - assert(PBBI.IsEnqueued && "Unexpected"); + assert(!PBBI.IsEnqueued && "Unexpected"); PBBI.IsAnalyzed = false; } } @@ -963,6 +965,7 @@ } } + BBI.IsAnalyzed = false; BBI.NonPredSize = 0; std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate)); @@ -1013,4 +1016,7 @@ std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), std::back_inserter(ToBBI.Predicate)); FromBBI.Predicate.clear(); + + ToBBI.IsAnalyzed = false; + FromBBI.IsAnalyzed = false; } From djg at cray.com Thu Jun 14 15:51:06 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 15:51:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp VirtRegMap.cpp Message-ID: <200706142051.l5EKp6O8018280@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.246 -> 1.247 VirtRegMap.cpp updated: 1.111 -> 1.112 --- Log message: Add a target hook to allow loads from constant pools to be rematerialized, and an implementation for x86. --- Diffs of the changes: (+6 -3) LiveIntervalAnalysis.cpp | 6 ++++-- VirtRegMap.cpp | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.246 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.247 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.246 Fri Jun 8 12:18:56 2007 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Jun 14 15:50:44 2007 @@ -336,12 +336,14 @@ // time we see a vreg. if (interval.empty()) { // Remember if the definition can be rematerialized. All load's from fixed - // stack slots are re-materializable. + // stack slots are re-materializable. The target may permit other loads to + // be re-materialized as well. int FrameIdx = 0; if (vi.DefInst && (tii_->isReMaterializable(vi.DefInst->getOpcode()) || (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) && - mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)))) + mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)) || + tii_->isOtherReMaterializableLoad(vi.DefInst))) interval.remat = vi.DefInst; // Get the Idx of the defining instructions. Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.111 llvm/lib/CodeGen/VirtRegMap.cpp:1.112 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.111 Thu Apr 26 13:59:33 2007 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Jun 14 15:50:44 2007 @@ -664,7 +664,8 @@ // If this instruction is being rematerialized, just remove it! int FrameIdx; if ((TID->Flags & M_REMATERIALIZIBLE) || - TII->isLoadFromStackSlot(&MI, FrameIdx)) { + TII->isLoadFromStackSlot(&MI, FrameIdx) || + TII->isOtherReMaterializableLoad(&MI)) { bool Remove = true; for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); From djg at cray.com Thu Jun 14 15:51:06 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 15:51:06 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200706142051.l5EKp6mE018285@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.127 -> 1.128 --- Log message: Add a target hook to allow loads from constant pools to be rematerialized, and an implementation for x86. --- Diffs of the changes: (+10 -0) TargetInstrInfo.h | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.127 llvm/include/llvm/Target/TargetInstrInfo.h:1.128 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.127 Fri Jun 8 16:59:04 2007 +++ llvm/include/llvm/Target/TargetInstrInfo.h Thu Jun 14 15:50:44 2007 @@ -298,6 +298,16 @@ return 0; } + /// isOtherReMaterializableLoad - If the specified machine instruction is a + /// direct load that is trivially rematerializable, not counting loads from + /// stack slots, return true. If not, return false. This predicate must + /// return false if the instruction has any side effects other than + /// producing the value from the load, or if it requres any address + /// registers that are not always available. + virtual bool isOtherReMaterializableLoad(MachineInstr *MI) const { + return false; + } + /// 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 one or moretrue From djg at cray.com Thu Jun 14 15:51:13 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 15:51:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp X86InstrInfo.h Message-ID: <200706142051.l5EKpDNo018296@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.89 -> 1.90 X86InstrInfo.h updated: 1.64 -> 1.65 --- Log message: Add a target hook to allow loads from constant pools to be rematerialized, and an implementation for x86. --- Diffs of the changes: (+26 -0) X86InstrInfo.cpp | 25 +++++++++++++++++++++++++ X86InstrInfo.h | 1 + 2 files changed, 26 insertions(+) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.89 llvm/lib/Target/X86/X86InstrInfo.cpp:1.90 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.89 Wed Jun 13 12:59:52 2007 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Thu Jun 14 15:50:44 2007 @@ -112,6 +112,31 @@ } +bool X86InstrInfo::isOtherReMaterializableLoad(MachineInstr *MI) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8rm: + case X86::MOV16rm: + case X86::MOV16_rm: + case X86::MOV32rm: + case X86::MOV32_rm: + case X86::MOV64rm: + case X86::FpLD64m: + case X86::MOVSSrm: + case X86::MOVSDrm: + case X86::MOVAPSrm: + case X86::MOVAPDrm: + case X86::MMX_MOVD64rm: + case X86::MMX_MOVQ64rm: + return MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate() && + MI->getOperand(3).isRegister() && MI->getOperand(4).isConstantPoolIndex() && + MI->getOperand(1).getReg() == 0 && + MI->getOperand(2).getImmedValue() == 1 && + MI->getOperand(3).getReg() == 0; + } + return false; +} + /// 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 Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.64 llvm/lib/Target/X86/X86InstrInfo.h:1.65 --- llvm/lib/Target/X86/X86InstrInfo.h:1.64 Thu May 17 19:17:09 2007 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Jun 14 15:50:44 2007 @@ -239,6 +239,7 @@ unsigned& destReg) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + bool isOtherReMaterializableLoad(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target From evan.cheng at apple.com Thu Jun 14 16:26:30 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 14 Jun 2007 16:26:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706142126.l5ELQUw3019037@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.47 -> 1.48 --- Log message: Fix typo. --- Diffs of the changes: (+1 -1) IfConversion.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.47 llvm/lib/CodeGen/IfConversion.cpp:1.48 --- llvm/lib/CodeGen/IfConversion.cpp:1.47 Thu Jun 14 15:28:52 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Thu Jun 14 16:26:08 2007 @@ -383,7 +383,7 @@ return; // First analyze the end of BB branches. - BBI.TrueBB = BBI.FalseBB; + BBI.TrueBB = BBI.FalseBB = NULL; BBI.BrCond.clear(); BBI.IsBrAnalyzable = !TII->AnalyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond); From dalej at apple.com Thu Jun 14 17:04:08 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 14 Jun 2007 17:04:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h X86InstrInfo.cpp Message-ID: <200706142204.l5EM48CS020251@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.65 -> 1.66 X86InstrInfo.cpp updated: 1.90 -> 1.91 --- Log message: Do not treat FP_REG_KILL as terminator in branch analysis (X86). --- Diffs of the changes: (+11 -4) X86InstrInfo.cpp | 14 ++++++++++---- X86InstrInfo.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.65 llvm/lib/Target/X86/X86InstrInfo.h:1.66 --- llvm/lib/Target/X86/X86InstrInfo.h:1.65 Thu Jun 14 15:50:44 2007 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Jun 14 17:03:45 2007 @@ -261,6 +261,7 @@ virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; // Branch analysis. + virtual bool isUnpredicatedTerminator(const MachineInstr* MI) const; virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, std::vector &Cond) const; Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.90 llvm/lib/Target/X86/X86InstrInfo.cpp:1.91 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.90 Thu Jun 14 15:50:44 2007 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Thu Jun 14 17:03:45 2007 @@ -398,13 +398,20 @@ } } +// For purposes of branch analysis do not count FP_REG_KILL as a terminator. +bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { + const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); + if (MI->getOpcode() == X86::FP_REG_KILL) + return false; + if (TID->Flags & M_TERMINATOR_FLAG) + return !isPredicated(MI); + return false; +} bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, std::vector &Cond) const { - // TODO: If FP_REG_KILL is around, ignore it. - // If the block has no terminators, it just falls into the block after it. MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) @@ -439,8 +446,7 @@ MachineInstr *SecondLastInst = I; // If there are three terminators, we don't know what sort of block this is. - if (SecondLastInst && I != MBB.begin() && - isTerminatorInstr((--I)->getOpcode())) + if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) return true; // If the block ends with X86::JMP and a conditional branch, handle it. From dalej at apple.com Thu Jun 14 17:04:13 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 14 Jun 2007 17:04:13 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/2007-06-14-branchfold.ll Message-ID: <200706142204.l5EM4DPc020264@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: 2007-06-14-branchfold.ll added (r1.1) --- Log message: Do not treat FP_REG_KILL as terminator in branch analysis (X86). --- Diffs of the changes: (+137 -0) 2007-06-14-branchfold.ll | 137 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 137 insertions(+) Index: llvm/test/CodeGen/X86/2007-06-14-branchfold.ll diff -c /dev/null llvm/test/CodeGen/X86/2007-06-14-branchfold.ll:1.1 *** /dev/null Thu Jun 14 17:03:55 2007 --- llvm/test/CodeGen/X86/2007-06-14-branchfold.ll Thu Jun 14 17:03:45 2007 *************** *** 0 **** --- 1,137 ---- + ; RUN: llvm-as < %s | llc -mcpu=i686 | grep jmp | wc -l | grep 1 + ; check that branch folding understands FP_REG_KILL is not a branch + ; the remaining jmp can be removed if we take advantage of knowing + ; abort does not return + + ; ModuleID = 'g.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" + target triple = "i686-pc-linux-gnu" + %struct.FRAME.c34003a = type { float, float } + @report_E = global i8 0 ; [#uses=0] + + define void @main() { + entry: + %FRAME.31 = alloca %struct.FRAME.c34003a, align 8 ; <%struct.FRAME.c34003a*> [#uses=4] + %tmp20 = call i32 @report__ident_int( i32 -50 ) ; [#uses=1] + %tmp2021 = sitofp i32 %tmp20 to float ; [#uses=5] + %tmp23 = fcmp ult float %tmp2021, 0xC7EFFFFFE0000000 ; [#uses=1] + %tmp26 = fcmp ugt float %tmp2021, 0x47EFFFFFE0000000 ; [#uses=1] + %bothcond = or i1 %tmp23, %tmp26 ; [#uses=1] + br i1 %bothcond, label %bb, label %bb30 + + bb: ; preds = %entry + unwind + + bb30: ; preds = %entry + %tmp35 = call i32 @report__ident_int( i32 50 ) ; [#uses=1] + %tmp3536 = sitofp i32 %tmp35 to float ; [#uses=4] + %tmp38 = fcmp ult float %tmp3536, 0xC7EFFFFFE0000000 ; [#uses=1] + %tmp44 = fcmp ugt float %tmp3536, 0x47EFFFFFE0000000 ; [#uses=1] + %bothcond226 = or i1 %tmp38, %tmp44 ; [#uses=1] + br i1 %bothcond226, label %bb47, label %bb49 + + bb47: ; preds = %bb30 + unwind + + bb49: ; preds = %bb30 + %tmp60 = fcmp ult float %tmp3536, %tmp2021 ; [#uses=1] + %tmp60.not = xor i1 %tmp60, true ; [#uses=1] + %tmp65 = fcmp olt float %tmp2021, 0xC7EFFFFFE0000000 ; [#uses=1] + %bothcond227 = and i1 %tmp65, %tmp60.not ; [#uses=1] + br i1 %bothcond227, label %cond_true68, label %cond_next70 + + cond_true68: ; preds = %bb49 + unwind + + cond_next70: ; preds = %bb49 + %tmp71 = call i32 @report__ident_int( i32 -30 ) ; [#uses=1] + %tmp7172 = sitofp i32 %tmp71 to float ; [#uses=3] + %tmp74 = fcmp ult float %tmp7172, 0xC7EFFFFFE0000000 ; [#uses=1] + %tmp80 = fcmp ugt float %tmp7172, 0x47EFFFFFE0000000 ; [#uses=1] + %bothcond228 = or i1 %tmp74, %tmp80 ; [#uses=1] + br i1 %bothcond228, label %bb83, label %bb85 + + bb83: ; preds = %cond_next70 + unwind + + bb85: ; preds = %cond_next70 + %tmp90 = getelementptr %struct.FRAME.c34003a* %FRAME.31, i32 0, i32 1 ; [#uses=3] + store float %tmp7172, float* %tmp90 + %tmp92 = call i32 @report__ident_int( i32 30 ) ; [#uses=1] + %tmp9293 = sitofp i32 %tmp92 to float ; [#uses=7] + %tmp95 = fcmp ult float %tmp9293, 0xC7EFFFFFE0000000 ; [#uses=1] + %tmp101 = fcmp ugt float %tmp9293, 0x47EFFFFFE0000000 ; [#uses=1] + %bothcond229 = or i1 %tmp95, %tmp101 ; [#uses=1] + br i1 %bothcond229, label %bb104, label %bb106 + + bb104: ; preds = %bb85 + unwind + + bb106: ; preds = %bb85 + %tmp111 = getelementptr %struct.FRAME.c34003a* %FRAME.31, i32 0, i32 0 ; [#uses=2] + store float %tmp9293, float* %tmp111 + %tmp123 = load float* %tmp90 ; [#uses=4] + %tmp125 = fcmp ult float %tmp9293, %tmp123 ; [#uses=1] + br i1 %tmp125, label %cond_next147, label %cond_true128 + + cond_true128: ; preds = %bb106 + %tmp133 = fcmp olt float %tmp123, %tmp2021 ; [#uses=1] + %tmp142 = fcmp ogt float %tmp9293, %tmp3536 ; [#uses=1] + %bothcond230 = or i1 %tmp133, %tmp142 ; [#uses=1] + br i1 %bothcond230, label %bb145, label %cond_next147 + + bb145: ; preds = %cond_true128 + unwind + + cond_next147: ; preds = %cond_true128, %bb106 + %tmp157 = fcmp ugt float %tmp123, -3.000000e+01 ; [#uses=1] + %tmp165 = fcmp ult float %tmp9293, -3.000000e+01 ; [#uses=1] + %bothcond231 = or i1 %tmp157, %tmp165 ; [#uses=1] + br i1 %bothcond231, label %bb168, label %bb169 + + bb168: ; preds = %cond_next147 + unwind + + bb169: ; preds = %cond_next147 + %tmp176 = fcmp ugt float %tmp123, 3.000000e+01 ; [#uses=1] + %tmp184 = fcmp ult float %tmp9293, 3.000000e+01 ; [#uses=1] + %bothcond232 = or i1 %tmp176, %tmp184 ; [#uses=1] + br i1 %bothcond232, label %bb187, label %bb188 + + bb187: ; preds = %bb169 + unwind + + bb188: ; preds = %bb169 + %tmp192 = call fastcc float @c34003a__ident.154( %struct.FRAME.c34003a* %FRAME.31, float 3.000000e+01 ) ; [#uses=2] + %tmp194 = load float* %tmp90 ; [#uses=1] + %tmp196 = fcmp ugt float %tmp194, 0.000000e+00 ; [#uses=1] + br i1 %tmp196, label %bb207, label %cond_next200 + + cond_next200: ; preds = %bb188 + %tmp202 = load float* %tmp111 ; [#uses=1] + %tmp204 = fcmp ult float %tmp202, 0.000000e+00 ; [#uses=1] + br i1 %tmp204, label %bb207, label %bb208 + + bb207: ; preds = %cond_next200, %bb188 + unwind + + bb208: ; preds = %cond_next200 + %tmp212 = call fastcc float @c34003a__ident.154( %struct.FRAME.c34003a* %FRAME.31, float 0.000000e+00 ) ; [#uses=1] + %tmp214 = fcmp oge float %tmp212, %tmp192 ; [#uses=1] + %tmp217 = fcmp oge float %tmp192, 1.000000e+02 ; [#uses=1] + %tmp221 = or i1 %tmp214, %tmp217 ; [#uses=1] + br i1 %tmp221, label %cond_true224, label %UnifiedReturnBlock + + cond_true224: ; preds = %bb208 + call void @abort( ) noreturn + ret void + + UnifiedReturnBlock: ; preds = %bb208 + ret void + } + + declare fastcc float @c34003a__ident.154(%struct.FRAME.c34003a* %CHAIN.32, float %x) + + declare i32 @report__ident_int(i32 %x) + + declare void @abort() noreturn From dalej at apple.com Thu Jun 14 17:04:13 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 14 Jun 2007 17:04:13 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200706142204.l5EM4DD9020259@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.128 -> 1.129 --- Log message: Do not treat FP_REG_KILL as terminator in branch analysis (X86). --- Diffs of the changes: (+1 -1) TargetInstrInfo.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.128 llvm/include/llvm/Target/TargetInstrInfo.h:1.129 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.128 Thu Jun 14 15:50:44 2007 +++ llvm/include/llvm/Target/TargetInstrInfo.h Thu Jun 14 17:03:45 2007 @@ -417,7 +417,7 @@ /// isUnpredicatedTerminator - Returns true if the instruction is a /// terminator instruction that has not been predicated. - bool isUnpredicatedTerminator(const MachineInstr *MI) const; + virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; /// PredicateInstruction - Convert the instruction into a predicated /// instruction. It returns true if the operation was successful. From djg at cray.com Thu Jun 14 17:58:25 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 17:58:25 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200706142258.l5EMwPXG021311@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.34 -> 1.35 --- Log message: Rename MVT::getVectorBaseType to MVT::getVectorElementType. --- Diffs of the changes: (+2 -2) ValueTypes.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.34 llvm/include/llvm/CodeGen/ValueTypes.h:1.35 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.34 Sat Apr 28 00:38:52 2007 +++ llvm/include/llvm/CodeGen/ValueTypes.h Thu Jun 14 17:58:02 2007 @@ -129,9 +129,9 @@ /// ValueType getVectorType(ValueType VT, unsigned NumElements); - /// MVT::getVectorBaseType - Given a packed vector type, return the type of + /// MVT::getVectorElementType - Given a packed vector type, return the type of /// each element. - static inline ValueType getVectorBaseType(ValueType VT) { + static inline ValueType getVectorElementType(ValueType VT) { switch (VT) { default: assert(0 && "Invalid vector type!"); case v8i8 : From djg at cray.com Thu Jun 14 17:58:25 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 17:58:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200706142258.l5EMwPtk021313@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.271 -> 1.272 --- Log message: Rename MVT::getVectorBaseType to MVT::getVectorElementType. --- Diffs of the changes: (+2 -2) PPCISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.271 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.272 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.271 Fri May 18 18:21:46 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Jun 14 17:58:02 2007 @@ -2257,7 +2257,7 @@ MVT::ValueType CanonicalVT = VTys[SplatSize-1]; // Build a canonical splat for this value. - SDOperand Elt = DAG.getConstant(Val, MVT::getVectorBaseType(CanonicalVT)); + SDOperand Elt = DAG.getConstant(Val, MVT::getVectorElementType(CanonicalVT)); SmallVector Ops; Ops.assign(MVT::getVectorNumElements(CanonicalVT), Elt); SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, @@ -2647,7 +2647,7 @@ // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except // that it is in input element units, not in bytes. Convert now. - MVT::ValueType EltVT = MVT::getVectorBaseType(V1.getValueType()); + MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType()); unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8; SmallVector ResultMask; From djg at cray.com Thu Jun 14 17:58:31 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 17:58:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200706142258.l5EMwVUZ021322@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.408 -> 1.409 --- Log message: Rename MVT::getVectorBaseType to MVT::getVectorElementType. --- Diffs of the changes: (+22 -22) X86ISelLowering.cpp | 44 ++++++++++++++++++++++---------------------- 1 files changed, 22 insertions(+), 22 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.408 llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.408 Sat Jun 9 00:08:10 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Jun 14 17:58:02 2007 @@ -2106,7 +2106,7 @@ SelectionDAG &DAG) { MVT::ValueType VT = Op.getValueType(); MVT::ValueType MaskVT = Mask.getValueType(); - MVT::ValueType EltVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType EltVT = MVT::getVectorElementType(MaskVT); unsigned NumElems = Mask.getNumOperands(); SmallVector MaskVec; @@ -2265,7 +2265,7 @@ static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) { assert(MVT::isVector(VT) && "Expected a vector type"); unsigned NumElems = MVT::getVectorNumElements(VT); - MVT::ValueType EVT = MVT::getVectorBaseType(VT); + MVT::ValueType EVT = MVT::getVectorElementType(VT); bool isFP = MVT::isFloatingPoint(EVT); SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT); SmallVector ZeroVec(NumElems, Zero); @@ -2302,7 +2302,7 @@ /// operation of specified width. static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) { MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; MaskVec.push_back(DAG.getConstant(NumElems, BaseVT)); @@ -2315,7 +2315,7 @@ /// of specified width. static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) { MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; for (unsigned i = 0, e = NumElems/2; i != e; ++i) { MaskVec.push_back(DAG.getConstant(i, BaseVT)); @@ -2328,7 +2328,7 @@ /// of specified width. static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) { MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); unsigned Half = NumElems/2; SmallVector MaskVec; for (unsigned i = 0; i != Half; ++i) { @@ -2366,7 +2366,7 @@ bool isZero, SelectionDAG &DAG) { SDOperand V1 = isZero ? getZeroVector(VT, DAG) : DAG.getNode(ISD::UNDEF, VT); MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType EVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType EVT = MVT::getVectorElementType(MaskVT); SDOperand Zero = DAG.getConstant(0, EVT); SmallVector MaskVec(NumElems, Zero); MaskVec[Idx] = DAG.getConstant(NumElems, EVT); @@ -2458,7 +2458,7 @@ return Op; MVT::ValueType VT = Op.getValueType(); - MVT::ValueType EVT = MVT::getVectorBaseType(VT); + MVT::ValueType EVT = MVT::getVectorElementType(VT); unsigned EVTBits = MVT::getSizeInBits(EVT); unsigned NumElems = Op.getNumOperands(); @@ -2502,7 +2502,7 @@ Item = getShuffleVectorZeroOrUndef(Item, VT, NumElems, 0, NumZero > 0, DAG); MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; for (unsigned i = 0; i < NumElems; i++) MaskVec.push_back(DAG.getConstant((i == Idx) ? 0 : 1, MaskEVT)); @@ -2571,7 +2571,7 @@ if (MVT::isInteger(EVT) && (NonZeros & (0x3 << 2)) == 0) return V[0]; MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType EVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType EVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; bool Reverse = (NonZeros & 0x3) == 2; for (unsigned i = 0; i < 2; ++i) @@ -2728,7 +2728,7 @@ // Handle v8i16 shuffle high / low shuffle node pair. if (VT == MVT::v8i16 && isPSHUFHW_PSHUFLWMask(PermMask.Val)) { MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; for (unsigned i = 0; i != 4; ++i) MaskVec.push_back(PermMask.getOperand(i)); @@ -2763,7 +2763,7 @@ // Don't do this for MMX. MVT::getSizeInBits(VT) != 64) { MVT::ValueType MaskVT = PermMask.getValueType(); - MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT); SmallVector, 8> Locs; Locs.reserve(NumElems); SmallVector Mask1(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT)); @@ -2888,10 +2888,10 @@ // SHUFPS the element to the lowest double word, then movss. MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); SmallVector IdxVec; - IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorBaseType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT))); + IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorElementType(MaskVT))); + IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); + IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &IdxVec[0], IdxVec.size()); Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), @@ -2909,8 +2909,8 @@ // to a f64mem, the whole operation is folded into a single MOVHPDmr. MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); SmallVector IdxVec; - IdxVec.push_back(DAG.getConstant(1, MVT::getVectorBaseType(MaskVT))); - IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT))); + IdxVec.push_back(DAG.getConstant(1, MVT::getVectorElementType(MaskVT))); + IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT))); SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &IdxVec[0], IdxVec.size()); Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), @@ -2927,7 +2927,7 @@ // Transform it so it match pinsrw which expects a 16-bit value in a GR32 // as its second argument. MVT::ValueType VT = Op.getValueType(); - MVT::ValueType BaseVT = MVT::getVectorBaseType(VT); + MVT::ValueType BaseVT = MVT::getVectorElementType(VT); SDOperand N0 = Op.getOperand(0); SDOperand N1 = Op.getOperand(1); SDOperand N2 = Op.getOperand(2); @@ -2943,7 +2943,7 @@ // Use a movss. N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, N1); MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); - MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); + MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT); SmallVector MaskVec; MaskVec.push_back(DAG.getConstant(4, BaseVT)); for (unsigned i = 1; i <= 3; ++i) @@ -4513,11 +4513,11 @@ i %= NumElems; if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) { return (i == 0) - ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(VT)); + ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT)); } else if (V.getOpcode() == ISD::VECTOR_SHUFFLE) { SDOperand Idx = PermMask.getOperand(i); if (Idx.getOpcode() == ISD::UNDEF) - return DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(VT)); + return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT)); return getShuffleScalarElt(V.Val,cast(Idx)->getValue(),DAG); } return SDOperand(); @@ -4613,7 +4613,7 @@ MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MVT::ValueType VT = N->getValueType(0); - MVT::ValueType EVT = MVT::getVectorBaseType(VT); + MVT::ValueType EVT = MVT::getVectorElementType(VT); SDOperand PermMask = N->getOperand(2); int NumElems = (int)PermMask.getNumOperands(); SDNode *Base = NULL; From djg at cray.com Thu Jun 14 17:58:31 2007 From: djg at cray.com (Dan Gohman) Date: Thu, 14 Jun 2007 17:58:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200706142258.l5EMwVgw021333@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.311 -> 1.312 LegalizeDAG.cpp updated: 1.496 -> 1.497 SelectionDAG.cpp updated: 1.406 -> 1.407 SelectionDAGISel.cpp updated: 1.462 -> 1.463 --- Log message: Rename MVT::getVectorBaseType to MVT::getVectorElementType. --- Diffs of the changes: (+10 -10) DAGCombiner.cpp | 2 +- LegalizeDAG.cpp | 10 +++++----- SelectionDAG.cpp | 4 ++-- SelectionDAGISel.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.311 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.312 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.311 Thu May 24 21:19:06 2007 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Jun 14 17:58:02 2007 @@ -1809,7 +1809,7 @@ return DAG.getConstant(0, VT); } else if (!AfterLegalize || TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) { // Produce a vector of zeros. - SDOperand El = DAG.getConstant(0, MVT::getVectorBaseType(VT)); + SDOperand El = DAG.getConstant(0, MVT::getVectorElementType(VT)); std::vector Ops(MVT::getVectorNumElements(VT), El); return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); } Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.496 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.497 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.496 Wed Jun 13 10:12:02 2007 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jun 14 17:58:02 2007 @@ -1014,7 +1014,7 @@ unsigned NumElts = MVT::getVectorNumElements(Tmp1.getValueType()); MVT::ValueType ShufMaskVT = MVT::getIntVectorWithNumElements(NumElts); - MVT::ValueType ShufMaskEltVT = MVT::getVectorBaseType(ShufMaskVT); + MVT::ValueType ShufMaskEltVT = MVT::getVectorElementType(ShufMaskVT); // We generate a shuffle of InVec and ScVec, so the shuffle mask should // be 0,1,2,3,4,5... with the appropriate element replaced with elt 0 of @@ -1110,7 +1110,7 @@ // FALLTHROUGH case TargetLowering::Expand: { MVT::ValueType VT = Node->getValueType(0); - MVT::ValueType EltVT = MVT::getVectorBaseType(VT); + MVT::ValueType EltVT = MVT::getVectorElementType(VT); MVT::ValueType PtrVT = TLI.getPointerTy(); SDOperand Mask = Node->getOperand(2); unsigned NumElems = Mask.getNumOperands(); @@ -2386,7 +2386,7 @@ "Cannot expand this binary operator!"); // Expand the operation into a bunch of nasty scalar code. SmallVector Ops; - MVT::ValueType EltVT = MVT::getVectorBaseType(Node->getValueType(0)); + MVT::ValueType EltVT = MVT::getVectorElementType(Node->getValueType(0)); MVT::ValueType PtrVT = TLI.getPointerTy(); for (unsigned i = 0, e = MVT::getVectorNumElements(Node->getValueType(0)); i != e; ++i) { @@ -4006,7 +4006,7 @@ // Build the shuffle constant vector: <0, 0, 0, 0> MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); - SDOperand Zero = DAG.getConstant(0, MVT::getVectorBaseType(MaskVT)); + SDOperand Zero = DAG.getConstant(0, MVT::getVectorElementType(MaskVT)); std::vector ZeroVec(NumElems, Zero); SDOperand SplatMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &ZeroVec[0], ZeroVec.size()); @@ -4036,7 +4036,7 @@ E = Values.end(); I != E; ++I) { for (std::vector::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) - MaskVec[*II] = DAG.getConstant(i, MVT::getVectorBaseType(MaskVT)); + MaskVec[*II] = DAG.getConstant(i, MVT::getVectorElementType(MaskVT)); i += NumElems; } SDOperand ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.406 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.407 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.406 Wed Jun 13 10:12:02 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Jun 14 17:58:02 2007 @@ -1114,7 +1114,7 @@ break; case ISD::SCALAR_TO_VECTOR: assert(MVT::isVector(VT) && !MVT::isVector(Operand.getValueType()) && - MVT::getVectorBaseType(VT) == Operand.getValueType() && + MVT::getVectorElementType(VT) == Operand.getValueType() && "Illegal SCALAR_TO_VECTOR node!"); break; case ISD::FNEG: @@ -1593,7 +1593,7 @@ ExtType = ISD::NON_EXTLOAD; if (MVT::isVector(VT)) - assert(EVT == MVT::getVectorBaseType(VT) && "Invalid vector extload!"); + assert(EVT == MVT::getVectorElementType(VT) && "Invalid vector extload!"); else assert(EVT < VT && "Should only be an extending load, not truncating!"); assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) && Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.462 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.463 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.462 Wed Jun 13 11:53:21 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Jun 14 17:58:02 2007 @@ -793,7 +793,7 @@ if (MVT::isVector(PTyElementVT)) { Ops.push_back(DAG.getConstant(NE * MVT::getVectorNumElements(PTyElementVT), MVT::i32)); - Ops.push_back(DAG.getValueType(MVT::getVectorBaseType(PTyElementVT))); + Ops.push_back(DAG.getValueType(MVT::getVectorElementType(PTyElementVT))); N = DAG.getNode(ISD::VCONCAT_VECTORS, MVT::Vector, &Ops[0], Ops.size()); } else { Ops.push_back(DAG.getConstant(NE, MVT::i32)); @@ -2905,7 +2905,7 @@ return DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Val, DAG.getConstant(MVT::getVectorNumElements(RegVT), MVT::i32), - DAG.getValueType(MVT::getVectorBaseType(RegVT))); + DAG.getValueType(MVT::getVectorElementType(RegVT))); } if (MVT::isInteger(RegVT)) { From evan.cheng at apple.com Thu Jun 14 18:13:41 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 14 Jun 2007 18:13:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706142313.l5ENDfhF021880@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.48 -> 1.49 --- Log message: If BB is predicated, invalidate its predecessor(s) which would if-convert it. It needs to be re-analyzed. --- Diffs of the changes: (+7 -3) IfConversion.cpp | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.48 llvm/lib/CodeGen/IfConversion.cpp:1.49 --- llvm/lib/CodeGen/IfConversion.cpp:1.48 Thu Jun 14 16:26:08 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Thu Jun 14 18:13:19 2007 @@ -656,15 +656,19 @@ } /// ReTryPreds - Invalidate predecessor BB info so it would be re-analyzed -/// to determine if it can be if-converted. +/// to determine if it can be if-converted. If predecessor is already +/// enqueud, dequeue it! void IfConverter::ReTryPreds(MachineBasicBlock *BB) { for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) { BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()]; - if (!PBBI.IsDone && PBBI.Kind == ICNotClassfied) { + if (PBBI.IsDone) + continue; + if (PBBI.Kind == ICNotClassfied) { assert(!PBBI.IsEnqueued && "Unexpected"); PBBI.IsAnalyzed = false; - } + } else if (PBBI.IsEnqueued && PBBI.BB != BB) + PBBI.IsEnqueued = false; } } From evan.cheng at apple.com Thu Jun 14 18:34:31 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 14 Jun 2007 18:34:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706142334.l5ENYVFA022458@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.49 -> 1.50 --- Log message: No really, clear predcessors states. --- Diffs of the changes: (+8 -7) IfConversion.cpp | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.49 llvm/lib/CodeGen/IfConversion.cpp:1.50 --- llvm/lib/CodeGen/IfConversion.cpp:1.49 Thu Jun 14 18:13:19 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Thu Jun 14 18:34:09 2007 @@ -662,13 +662,11 @@ for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) { BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()]; - if (PBBI.IsDone) + if (PBBI.IsDone || PBBI.BB == BB) continue; - if (PBBI.Kind == ICNotClassfied) { - assert(!PBBI.IsEnqueued && "Unexpected"); - PBBI.IsAnalyzed = false; - } else if (PBBI.IsEnqueued && PBBI.BB != BB) - PBBI.IsEnqueued = false; + PBBI.Kind = ICNotClassfied; + PBBI.IsAnalyzed = false; + PBBI.IsEnqueued = false; } } @@ -769,8 +767,11 @@ if (PBB == BBI.BB) continue; BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; - if (PBBI.IsEnqueued) + if (PBBI.IsEnqueued) { + PBBI.Kind = ICNotClassfied; + PBBI.IsAnalyzed = false; PBBI.IsEnqueued = false; + } } } From sabre at nondot.org Fri Jun 15 00:27:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 00:27:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200706150527.l5F5RHLc030091@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.769 -> 1.770 --- Log message: delete some obviously dead vector operations, which deletes a few thousand operations from Duraids example. --- Diffs of the changes: (+12 -1) InstructionCombining.cpp | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.769 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.770 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.769 Wed Jun 6 12:08:48 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jun 15 00:26:55 2007 @@ -3245,8 +3245,10 @@ return &I; } else { if (ConstantVector *CP = dyn_cast(Op1)) { - if (CP->isAllOnesValue()) + if (CP->isAllOnesValue()) // X & <-1,-1> -> X return ReplaceInstUsesWith(I, I.getOperand(0)); + } else if (isa(Op1)) { + return ReplaceInstUsesWith(I, Op1); // X & <0,0> -> <0,0> } } @@ -3714,7 +3716,14 @@ if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), KnownZero, KnownOne)) return &I; + } else if (isa(Op1)) { + return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X + } else if (ConstantVector *CP = dyn_cast(Op1)) { + if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1> + return ReplaceInstUsesWith(I, I.getOperand(1)); } + + // or X, -1 == -1 if (ConstantInt *RHS = dyn_cast(Op1)) { @@ -4107,6 +4116,8 @@ if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), KnownZero, KnownOne)) return &I; + } else if (isa(Op1)) { + return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X } if (ConstantInt *RHS = dyn_cast(Op1)) { From sabre at nondot.org Fri Jun 15 00:57:39 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 00:57:39 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/InstCombine/and-or-not.ll Message-ID: <200706150557.l5F5vdIP031030@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/InstCombine: and-or-not.ll added (r1.1) --- Log message: testcase for PR1510: http://llvm.org/PR1510 --- Diffs of the changes: (+27 -0) and-or-not.ll | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/test/Transforms/InstCombine/and-or-not.ll diff -c /dev/null llvm/test/Transforms/InstCombine/and-or-not.ll:1.1 *** /dev/null Fri Jun 15 00:57:30 2007 --- llvm/test/Transforms/InstCombine/and-or-not.ll Fri Jun 15 00:57:20 2007 *************** *** 0 **** --- 1,27 ---- + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep xor | wc -l | grep 2 + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep and + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep { or} + + ; PR1510 + + ; These are all equivelent to A^B + + define i32 @test1(i32 %a, i32 %b) { + entry: + %tmp3 = or i32 %b, %a ; [#uses=1] + %tmp3not = xor i32 %tmp3, -1 ; [#uses=1] + %tmp6 = and i32 %b, %a ; [#uses=1] + %tmp7 = or i32 %tmp6, %tmp3not ; [#uses=1] + %tmp7not = xor i32 %tmp7, -1 ; [#uses=1] + ret i32 %tmp7not + } + + define i32 @test2(i32 %a, i32 %b) { + entry: + %tmp3 = or i32 %b, %a ; [#uses=1] + %tmp6 = and i32 %b, %a ; [#uses=1] + %tmp6not = xor i32 %tmp6, -1 ; [#uses=1] + %tmp7 = and i32 %tmp3, %tmp6not ; [#uses=1] + ret i32 %tmp7 + } + From sabre at nondot.org Fri Jun 15 00:58:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 00:58:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200706150558.l5F5wkYQ031076@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.770 -> 1.771 --- Log message: Implement two xforms: 1. ~(~X | Y) === (X & ~Y) 2. (A|B) & ~(A&B) -> A^B This allows us to transform ~(~(a|b) | (a&b)) -> a^b. This implements PR1510: http://llvm.org/PR1510 for scalar values. --- Diffs of the changes: (+26 -6) InstructionCombining.cpp | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.770 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.771 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.770 Fri Jun 15 00:26:55 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jun 15 00:58:24 2007 @@ -3363,13 +3363,28 @@ } { - Value *A = 0, *B = 0; - if (match(Op0, m_Or(m_Value(A), m_Value(B)))) + Value *A = 0, *B = 0, *C = 0, *D = 0; + if (match(Op0, m_Or(m_Value(A), m_Value(B)))) { if (A == Op1 || B == Op1) // (A | ?) & A --> A return ReplaceInstUsesWith(I, Op1); - if (match(Op1, m_Or(m_Value(A), m_Value(B)))) + + // (A|B) & ~(A&B) -> A^B + if (match(Op1, m_Not(m_And(m_Value(C), m_Value(D))))) { + if ((A == C && B == D) || (A == D && B == C)) + return BinaryOperator::createXor(A, B); + } + } + + if (match(Op1, m_Or(m_Value(A), m_Value(B)))) { if (A == Op0 || B == Op0) // A & (A | ?) --> A return ReplaceInstUsesWith(I, Op0); + + // ~(A&B) & (A|B) -> A^B + if (match(Op0, m_Not(m_And(m_Value(C), m_Value(D))))) { + if ((A == C && B == D) || (A == D && B == C)) + return BinaryOperator::createXor(A, B); + } + } if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_Value(B)))) { @@ -4137,15 +4152,20 @@ return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS); } - // ~(~X & Y) --> (X | ~Y) - if (Op0I->getOpcode() == Instruction::And && RHS->isAllOnesValue()) { + // ~(~X & Y) --> (X | ~Y) - De Morgan's Law + // ~(~X | Y) === (X & ~Y) - De Morgan's Law + if ((Op0I->getOpcode() == Instruction::And || + Op0I->getOpcode() == Instruction::Or) && RHS->isAllOnesValue()) { if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { Instruction *NotY = BinaryOperator::createNot(Op0I->getOperand(1), Op0I->getOperand(1)->getName()+".not"); InsertNewInstBefore(NotY, I); - return BinaryOperator::createOr(Op0NotVal, NotY); + if (Op0I->getOpcode() == Instruction::And) + return BinaryOperator::createOr(Op0NotVal, NotY); + else + return BinaryOperator::createAnd(Op0NotVal, NotY); } } From sabre at nondot.org Fri Jun 15 01:04:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:04:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Instructions.cpp Message-ID: <200706150604.l5F64kIV031259@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Instructions.cpp updated: 1.92 -> 1.93 --- Log message: Enhance BinaryOperator::isNot to support vector not. --- Diffs of the changes: (+5 -1) Instructions.cpp | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.92 llvm/lib/VMCore/Instructions.cpp:1.93 --- llvm/lib/VMCore/Instructions.cpp:1.92 Fri May 11 16:43:24 2007 +++ llvm/lib/VMCore/Instructions.cpp Fri Jun 15 01:04:24 2007 @@ -1404,7 +1404,11 @@ // isConstantAllOnes - Helper function for several functions below static inline bool isConstantAllOnes(const Value *V) { - return isa(V) &&cast(V)->isAllOnesValue(); + if (const ConstantInt *CI = dyn_cast(V)) + return CI->isAllOnesValue(); + if (const ConstantVector *CV = dyn_cast(V)) + return CV->isAllOnesValue(); + return false; } bool BinaryOperator::isNeg(const Value *V) { From sabre at nondot.org Fri Jun 15 01:11:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:11:17 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Message-ID: <200706150611.l5F6BHJP031444@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.36 -> 1.37 --- Log message: add a Constant::getAllOnesValue helper function, which works on integers AND vectors. --- Diffs of the changes: (+5 -0) Constant.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.36 llvm/include/llvm/Constant.h:1.37 --- llvm/include/llvm/Constant.h:1.36 Fri Apr 13 13:12:09 2007 +++ llvm/include/llvm/Constant.h Fri Jun 15 01:10:53 2007 @@ -48,6 +48,11 @@ /// static Constant *getNullValue(const Type *Ty); + /// Static constructor to get a '-1' constant. This supports integers and + /// vectors. + /// + static Constant *getAllOnesValue(const Type *Ty); + /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. virtual bool isNullValue() const = 0; From sabre at nondot.org Fri Jun 15 01:11:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:11:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200706150611.l5F6BHFC031447@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.229 -> 1.230 --- Log message: add a Constant::getAllOnesValue helper function, which works on integers AND vectors. --- Diffs of the changes: (+5 -0) Constants.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.229 llvm/lib/VMCore/Constants.cpp:1.230 --- llvm/lib/VMCore/Constants.cpp:1.229 Thu May 24 09:36:04 2007 +++ llvm/lib/VMCore/Constants.cpp Fri Jun 15 01:10:53 2007 @@ -122,6 +122,11 @@ } } +Constant *Constant::getAllOnesValue(const Type *Ty) { + if (const IntegerType* ITy = dyn_cast(Ty)) + return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth())); + return ConstantVector::getAllOnesValue(cast(Ty)); +} // Static constructor to create an integral constant with all bits set ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) { From sabre at nondot.org Fri Jun 15 01:14:09 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:14:09 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PatternMatch.h Message-ID: <200706150614.l5F6E9xV031575@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PatternMatch.h updated: 1.20 -> 1.21 --- Log message: m_not should match vector not --- Diffs of the changes: (+5 -1) PatternMatch.h | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Support/PatternMatch.h diff -u llvm/include/llvm/Support/PatternMatch.h:1.20 llvm/include/llvm/Support/PatternMatch.h:1.21 --- llvm/include/llvm/Support/PatternMatch.h:1.20 Fri Apr 13 13:12:09 2007 +++ llvm/include/llvm/Support/PatternMatch.h Fri Jun 15 01:13:47 2007 @@ -329,8 +329,12 @@ bool matchIfNot(Value *LHS, Value *RHS) { if (ConstantInt *CI = dyn_cast(RHS)) return CI->isAllOnesValue() && L.match(LHS); - else if (ConstantInt *CI = dyn_cast(LHS)) + if (ConstantInt *CI = dyn_cast(LHS)) return CI->isAllOnesValue() && L.match(RHS); + if (ConstantVector *CV = dyn_cast(RHS)) + return CV->isAllOnesValue() && L.match(LHS); + if (ConstantVector *CV = dyn_cast(LHS)) + return CV->isAllOnesValue() && L.match(RHS); return false; } }; From sabre at nondot.org Fri Jun 15 01:22:54 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:22:54 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/InstCombine/and-or-not.ll Message-ID: <200706150622.l5F6Mslj031810@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/InstCombine: and-or-not.ll updated: 1.1 -> 1.2 --- Log message: add vector versions of this test --- Diffs of the changes: (+20 -1) and-or-not.ll | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletion(-) Index: llvm/test/Transforms/InstCombine/and-or-not.ll diff -u llvm/test/Transforms/InstCombine/and-or-not.ll:1.1 llvm/test/Transforms/InstCombine/and-or-not.ll:1.2 --- llvm/test/Transforms/InstCombine/and-or-not.ll:1.1 Fri Jun 15 00:57:20 2007 +++ llvm/test/Transforms/InstCombine/and-or-not.ll Fri Jun 15 01:22:32 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep xor | wc -l | grep 2 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep xor | wc -l | grep 4 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep and ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep { or} @@ -25,3 +25,22 @@ ret i32 %tmp7 } +define <4 x i32> @test3(<4 x i32> %a, <4 x i32> %b) { +entry: + %tmp3 = or <4 x i32> %a, %b ; <<4 x i32>> [#uses=1] + %tmp3not = xor <4 x i32> %tmp3, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %tmp6 = and <4 x i32> %a, %b ; <<4 x i32>> [#uses=1] + %tmp7 = or <4 x i32> %tmp6, %tmp3not ; <<4 x i32>> [#uses=1] + %tmp7not = xor <4 x i32> %tmp7, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + ret <4 x i32> %tmp7not +} + +define <4 x i32> @test4(<4 x i32> %a, <4 x i32> %b) { +entry: + %tmp3 = or <4 x i32> %a, %b ; <<4 x i32>> [#uses=1] + %tmp6 = and <4 x i32> %a, %b ; <<4 x i32>> [#uses=1] + %tmp6not = xor <4 x i32> %tmp6, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %tmp7 = and <4 x i32> %tmp3, %tmp6not ; <<4 x i32>> [#uses=1] + ret <4 x i32> %tmp7 +} + From sabre at nondot.org Fri Jun 15 01:23:41 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 01:23:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200706150623.l5F6NfnM031832@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.771 -> 1.772 --- Log message: Generalize many transforms to work on ~ of vectors in addition to ~ of integer ops. This implements Transforms/InstCombine/and-or-not.ll test3/test4, and finishes off PR1510: http://llvm.org/PR1510 --- Diffs of the changes: (+31 -29) InstructionCombining.cpp | 60 ++++++++++++++++++++++++----------------------- 1 files changed, 31 insertions(+), 29 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.771 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.772 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.771 Fri Jun 15 00:58:24 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jun 15 01:23:19 2007 @@ -2050,9 +2050,8 @@ return BinaryOperator::createMul(LHS, AddOne(C2)); // X + ~X --> -1 since ~X = -X-1 - if (dyn_castNotVal(LHS) == RHS || - dyn_castNotVal(RHS) == LHS) - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + if (dyn_castNotVal(LHS) == RHS || dyn_castNotVal(RHS) == LHS) + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // (A & C1)+(B & C2) --> (A & C1)|(B & C2) iff C1&C2 == 0 @@ -3717,7 +3716,7 @@ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (isa(Op1)) // X | undef -> -1 - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // or X, X = X if (Op0 == Op1) @@ -3912,16 +3911,14 @@ if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1 if (A == Op1) // ~A | A == -1 - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); } else { A = 0; } // Note, A is still live here! if (match(Op1, m_Not(m_Value(B)))) { // Op0 | ~B if (Op0 == B) - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); // (~A | ~B) == (~(A & B)) - De Morgan's Law if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) { @@ -4135,6 +4132,29 @@ return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X } + // Is this a ~ operation? + if (Value *NotOp = dyn_castNotVal(&I)) { + // ~(~X & Y) --> (X | ~Y) - De Morgan's Law + // ~(~X | Y) === (X & ~Y) - De Morgan's Law + if (BinaryOperator *Op0I = dyn_cast(NotOp)) { + if (Op0I->getOpcode() == Instruction::And || + Op0I->getOpcode() == Instruction::Or) { + if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); + if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { + Instruction *NotY = + BinaryOperator::createNot(Op0I->getOperand(1), + Op0I->getOperand(1)->getName()+".not"); + InsertNewInstBefore(NotY, I); + if (Op0I->getOpcode() == Instruction::And) + return BinaryOperator::createOr(Op0NotVal, NotY); + else + return BinaryOperator::createAnd(Op0NotVal, NotY); + } + } + } + } + + if (ConstantInt *RHS = dyn_cast(Op1)) { // xor (icmp A, B), true = not (icmp A, B) = !icmp A, B if (ICmpInst *ICI = dyn_cast(Op0)) @@ -4151,23 +4171,6 @@ ConstantInt::get(I.getType(), 1)); return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS); } - - // ~(~X & Y) --> (X | ~Y) - De Morgan's Law - // ~(~X | Y) === (X & ~Y) - De Morgan's Law - if ((Op0I->getOpcode() == Instruction::And || - Op0I->getOpcode() == Instruction::Or) && RHS->isAllOnesValue()) { - if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); - if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { - Instruction *NotY = - BinaryOperator::createNot(Op0I->getOperand(1), - Op0I->getOperand(1)->getName()+".not"); - InsertNewInstBefore(NotY, I); - if (Op0I->getOpcode() == Instruction::And) - return BinaryOperator::createOr(Op0NotVal, NotY); - else - return BinaryOperator::createAnd(Op0NotVal, NotY); - } - } if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) if (Op0I->getOpcode() == Instruction::Add) { @@ -4212,12 +4215,11 @@ if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1 if (X == Op1) - return ReplaceInstUsesWith(I, - ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1 if (X == Op0) - return ReplaceInstUsesWith(I, ConstantInt::getAllOnesValue(I.getType())); + return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); BinaryOperator *Op1I = dyn_cast(Op1); @@ -7092,7 +7094,7 @@ case Instruction::AShr: return Constant::getNullValue(I->getType()); case Instruction::And: - return ConstantInt::getAllOnesValue(I->getType()); + return Constant::getAllOnesValue(I->getType()); case Instruction::Mul: return ConstantInt::get(I->getType(), 1); } From evan.cheng at apple.com Fri Jun 15 02:36:56 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 02:36:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706150736.l5F7auDL010184@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.50 -> 1.51 --- Log message: Allow small blocks to be duplicated to enable if-conversion. --- Diffs of the changes: (+99 -25) IfConversion.cpp | 124 +++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 99 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.50 llvm/lib/CodeGen/IfConversion.cpp:1.51 --- llvm/lib/CodeGen/IfConversion.cpp:1.50 Thu Jun 14 18:34:09 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Fri Jun 15 02:36:12 2007 @@ -54,6 +54,7 @@ STATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed"); STATISTIC(NumDiamonds, "Number of diamond if-conversions performed"); STATISTIC(NumIfConvBBs, "Number of if-converted blocks"); +STATISTIC(NumDupBBs, "Number of duplicated blocks"); namespace { class IfConverter : public MachineFunctionPass { @@ -153,7 +154,10 @@ void PredicateBlock(BBInfo &BBI, std::vector &Cond, bool IgnoreTerm = false); - void MergeBlocks(BBInfo &TrueBBI, BBInfo &FalseBBI); + void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, + std::vector &Cond, + bool IgnoreBr = false); + void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI); // blockAlwaysFallThrough - Block ends without a terminator. bool blockAlwaysFallThrough(BBInfo &BBI) const { @@ -196,7 +200,9 @@ std::vector Candidates; MadeChange = false; - while (IfCvtLimit == -1 || (int)NumIfConvBBs < IfCvtLimit) { + unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + + NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds; + while (IfCvtLimit == -1 || (int)NumIfCvts < IfCvtLimit) { // Do an intial analysis for each basic block and finding all the potential // candidates to perform if-convesion. bool Change = AnalyzeBlocks(MF, Candidates); @@ -274,7 +280,9 @@ } Change |= RetVal; - if (IfCvtLimit != -1 && (int)NumIfConvBBs >= IfCvtLimit) + NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev + + NumTriangleFalse + NumTriangleFRev + NumDiamonds; + if (IfCvtLimit != -1 && (int)NumIfCvts >= IfCvtLimit) break; } @@ -326,8 +334,12 @@ if (TrueBBI.IsBeingAnalyzed) return false; - return !blockAlwaysFallThrough(TrueBBI) && - TrueBBI.BrCond.size() == 0 && TrueBBI.BB->pred_size() == 1; + if (TrueBBI.BB->pred_size() != 1) { + if (TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit()) + return false; + } + + return !blockAlwaysFallThrough(TrueBBI) && TrueBBI.BrCond.size() == 0; } /// ValidTriangle - Returns true if the 'true' and 'false' blocks (along @@ -337,8 +349,13 @@ if (TrueBBI.IsBeingAnalyzed) return false; - if (TrueBBI.BB->pred_size() != 1) - return false; + if (TrueBBI.BB->pred_size() != 1) { + unsigned Size = TrueBBI.NonPredSize; + if (TrueBBI.FalseBB) + ++Size; + if (Size > TLI->getIfCvtDupBlockSizeLimit()) + return false; + } MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB; if (!TExit && blockAlwaysFallThrough(TrueBBI)) { @@ -709,11 +726,18 @@ TII->ReverseBranchCondition(Cond); } - PredicateBlock(*CvtBBI, Cond); + if (CvtBBI->BB->pred_size() > 1) { + BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); + // Copy instructions in the true block, predicate them add them to + // the entry block. + CopyAndPredicateBlock(BBI, *CvtBBI, Cond); + } else { + PredicateBlock(*CvtBBI, Cond); - // Merge converted block into entry block. - BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); - MergeBlocks(BBI, *CvtBBI); + // Merge converted block into entry block. + BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); + MergeBlocks(BBI, *CvtBBI); + } bool IterIfcvt = true; if (!canFallThroughTo(BBI.BB, NextBBI->BB)) { @@ -775,22 +799,38 @@ } } - // Predicate the 'true' block after removing its branch. - CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); - PredicateBlock(*CvtBBI, Cond); + bool HasEarlyExit = CvtBBI->FalseBB != NULL; + bool DupBB = CvtBBI->BB->pred_size() > 1; + if (DupBB) { + BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); + // Copy instructions in the true block, predicate them add them to + // the entry block. + CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true); + BBI.BB->removeSuccessor(CvtBBI->BB); + } else { + // Predicate the 'true' block after removing its branch. + CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); + PredicateBlock(*CvtBBI, Cond); + } // If 'true' block has a 'false' successor, add an exit branch to it. - bool HasEarlyExit = CvtBBI->FalseBB != NULL; if (HasEarlyExit) { std::vector RevCond(CvtBBI->BrCond); if (TII->ReverseBranchCondition(RevCond)) assert(false && "Unable to reverse branch condition!"); - TII->InsertBranch(*CvtBBI->BB, CvtBBI->FalseBB, NULL, RevCond); + if (DupBB) { + TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond); + BBI.BB->addSuccessor(CvtBBI->FalseBB); + } else { + TII->InsertBranch(*CvtBBI->BB, CvtBBI->FalseBB, NULL, RevCond); + } } - // Now merge the entry of the triangle with the true block. - BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); - MergeBlocks(BBI, *CvtBBI); + if (!DupBB) { + // Now merge the entry of the triangle with the true block. + BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); + MergeBlocks(BBI, *CvtBBI); + } // Merge in the 'false' block if the 'false' block has no other // predecessors. Otherwise, add a unconditional branch from to 'false'. @@ -970,13 +1010,48 @@ } } + std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate)); + BBI.IsAnalyzed = false; BBI.NonPredSize = 0; - std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate)); NumIfConvBBs++; } +/// CopyAndPredicateBlock - Copy and predicate instructions from source BB to +/// the destination block. Skip end of block branches if IgnoreBr is true. +void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, + std::vector &Cond, + bool IgnoreBr) { + for (MachineBasicBlock::iterator I = FromBBI.BB->begin(), + E = FromBBI.BB->end(); I != E; ++I) { + const TargetInstrDescriptor *TID = I->getInstrDescriptor(); + bool isPredicated = TII->isPredicated(I); + // Do not copy the end of the block branches. + if (IgnoreBr && !isPredicated && (TID->Flags & M_BRANCH_FLAG) != 0) + break; + + MachineInstr *MI = I->clone(); + ToBBI.BB->insert(ToBBI.BB->end(), MI); + ToBBI.NonPredSize++; + + if (!isPredicated) + if (!TII->PredicateInstruction(MI, Cond)) { + cerr << "Unable to predicate " << *MI << "!\n"; + abort(); + } + } + + std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), + std::back_inserter(ToBBI.Predicate)); + std::copy(Cond.begin(), Cond.end(), std::back_inserter(ToBBI.Predicate)); + + ToBBI.ClobbersPred |= FromBBI.ClobbersPred; + ToBBI.IsAnalyzed = false; + + NumDupBBs++; +} + /// MergeBlocks - Move all instructions from FromBB to the end of ToBB. /// void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI) { @@ -1012,16 +1087,15 @@ if (NBB) FromBBI.BB->addSuccessor(NBB); + std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), + std::back_inserter(ToBBI.Predicate)); + FromBBI.Predicate.clear(); + ToBBI.NonPredSize += FromBBI.NonPredSize; FromBBI.NonPredSize = 0; ToBBI.ClobbersPred |= FromBBI.ClobbersPred; ToBBI.HasFallThrough = FromBBI.HasFallThrough; - - std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), - std::back_inserter(ToBBI.Predicate)); - FromBBI.Predicate.clear(); - ToBBI.IsAnalyzed = false; FromBBI.IsAnalyzed = false; } From djg at cray.com Fri Jun 15 09:38:39 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 15 Jun 2007 09:38:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp LoopStrengthReduce.cpp Message-ID: <200706151438.l5FEcdga019992@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.120 -> 1.121 LoopStrengthReduce.cpp updated: 1.140 -> 1.141 --- Log message: Add a SCEV class and supporting code for sign-extend expressions. This created an ambiguity for expandInTy to decide when to use sign-extension or zero-extension, but it turns out that most of its callers don't actually need a type conversion, now that LLVM types don't have explicit signedness. Drop expandInTy in favor of plain expand, and change the few places that actually need a type conversion to do it themselves. --- Diffs of the changes: (+23 -18) IndVarSimplify.cpp | 13 +++++++------ LoopStrengthReduce.cpp | 28 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 18 deletions(-) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.120 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.121 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.120 Tue Jun 5 22:51:56 2007 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Jun 15 09:38:12 2007 @@ -277,8 +277,7 @@ // Expand the code for the iteration count into the preheader of the loop. BasicBlock *Preheader = L->getLoopPreheader(); - Value *ExitCnt = RW.expandCodeFor(TripCount, Preheader->getTerminator(), - IndVar->getType()); + Value *ExitCnt = RW.expandCodeFor(TripCount, Preheader->getTerminator()); // Insert a new icmp_ne or icmp_eq instruction before the branch. ICmpInst::Predicate Opcode; @@ -383,7 +382,7 @@ // just reuse it. Value *&ExitVal = ExitValues[Inst]; if (!ExitVal) - ExitVal = Rewriter.expandCodeFor(ExitValue, InsertPt,Inst->getType()); + ExitVal = Rewriter.expandCodeFor(ExitValue, InsertPt); DOUT << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << " LoopVal = " << *Inst << "\n"; @@ -519,9 +518,12 @@ Changed = true; DOUT << "INDVARS: New CanIV: " << *IndVar; - if (!isa(IterationCount)) + if (!isa(IterationCount)) { + if (IterationCount->getType() != LargestType) + IterationCount = SCEVZeroExtendExpr::get(IterationCount, LargestType); if (Instruction *DI = LinearFunctionTestReplace(L, IterationCount,Rewriter)) DeadInsts.insert(DI); + } // Now that we have a canonical induction variable, we can rewrite any // recurrences in terms of the induction variable. Start with the auxillary @@ -555,8 +557,7 @@ std::map InsertedSizes; while (!IndVars.empty()) { PHINode *PN = IndVars.back().first; - Value *NewVal = Rewriter.expandCodeFor(IndVars.back().second, InsertPt, - PN->getType()); + Value *NewVal = Rewriter.expandCodeFor(IndVars.back().second, InsertPt); DOUT << "INDVARS: Rewrote IV '" << *IndVars.back().second << "' " << *PN << " into = " << *NewVal << "\n"; NewVal->takeName(PN); Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.140 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.141 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.140 Thu Jun 7 16:42:15 2007 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Jun 15 09:38:12 2007 @@ -555,8 +555,7 @@ // If there is no immediate value, skip the next part. if (SCEVConstant *SC = dyn_cast(Imm)) if (SC->getValue()->isZero()) - return Rewriter.expandCodeFor(NewBase, BaseInsertPt, - OperandValToReplace->getType()); + return Rewriter.expandCodeFor(NewBase, BaseInsertPt); Value *Base = Rewriter.expandCodeFor(NewBase, BaseInsertPt); @@ -567,8 +566,7 @@ // Always emit the immediate (if non-zero) into the same block as the user. SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(Base), Imm); - return Rewriter.expandCodeFor(NewValSCEV, IP, - OperandValToReplace->getType()); + return Rewriter.expandCodeFor(NewValSCEV, IP); } @@ -598,6 +596,11 @@ } } Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L); + // Adjust the type back to match the Inst. + if (isa(OperandValToReplace->getType())) { + NewVal = new IntToPtrInst(NewVal, OperandValToReplace->getType(), "cast", + InsertPt); + } // Replace the use of the operand Value with the new Phi we just created. Inst->replaceUsesOfWith(OperandValToReplace, NewVal); DOUT << " CHANGED: IMM =" << *Imm; @@ -644,6 +647,11 @@ // Insert the code into the end of the predecessor block. Instruction *InsertPt = PN->getIncomingBlock(i)->getTerminator(); Code = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L); + + // Adjust the type back to match the PHI. + if (isa(PN->getType())) { + Code = new IntToPtrInst(Code, PN->getType(), "cast", InsertPt); + } } // Replace the use of the operand Value with the new Phi we just created. @@ -1112,8 +1120,7 @@ // Emit the initial base value into the loop preheader. Value *CommonBaseV - = PreheaderRewriter.expandCodeFor(CommonExprs, PreInsertPt, - ReplacedTy); + = PreheaderRewriter.expandCodeFor(CommonExprs, PreInsertPt); if (RewriteFactor == 0) { // Create a new Phi for this base, and stick it in the loop header. @@ -1131,8 +1138,7 @@ IncAmount = SCEV::getNegativeSCEV(Stride); // Insert the stride into the preheader. - Value *StrideV = PreheaderRewriter.expandCodeFor(IncAmount, PreInsertPt, - ReplacedTy); + Value *StrideV = PreheaderRewriter.expandCodeFor(IncAmount, PreInsertPt); if (!isa(StrideV)) ++NumVariable; // Emit the increment of the base value before the terminator of the loop @@ -1142,8 +1148,7 @@ IncExp = SCEV::getNegativeSCEV(IncExp); IncExp = SCEVAddExpr::get(SCEVUnknown::get(NewPHI), IncExp); - IncV = Rewriter.expandCodeFor(IncExp, LatchBlock->getTerminator(), - ReplacedTy); + IncV = Rewriter.expandCodeFor(IncExp, LatchBlock->getTerminator()); IncV->setName(NewPHI->getName()+".inc"); NewPHI->addIncoming(IncV, LatchBlock); @@ -1199,8 +1204,7 @@ SCEVHandle Base = UsersToProcess.back().Base; // Emit the code for Base into the preheader. - Value *BaseV = PreheaderRewriter.expandCodeFor(Base, PreInsertPt, - ReplacedTy); + Value *BaseV = PreheaderRewriter.expandCodeFor(Base, PreInsertPt); DOUT << " INSERTING code for BASE = " << *Base << ":"; if (BaseV->hasName()) From djg at cray.com Fri Jun 15 09:38:43 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 15 Jun 2007 09:38:43 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h ScalarEvolutionExpressions.h Message-ID: <200706151438.l5FEchE6019999@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ScalarEvolutionExpander.h updated: 1.16 -> 1.17 ScalarEvolutionExpressions.h updated: 1.11 -> 1.12 --- Log message: Add a SCEV class and supporting code for sign-extend expressions. This created an ambiguity for expandInTy to decide when to use sign-extension or zero-extension, but it turns out that most of its callers don't actually need a type conversion, now that LLVM types don't have explicit signedness. Drop expandInTy in favor of plain expand, and change the few places that actually need a type conversion to do it themselves. --- Diffs of the changes: (+63 -33) ScalarEvolutionExpander.h | 43 +++++++++------------------------- ScalarEvolutionExpressions.h | 53 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 33 deletions(-) Index: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h diff -u llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.16 llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.17 --- llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.16 Tue Jun 5 20:22:09 2007 +++ llvm/include/llvm/Analysis/ScalarEvolutionExpander.h Fri Jun 15 09:38:12 2007 @@ -78,13 +78,10 @@ /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - /// - /// If a particular value sign is required, a type may be specified for the - /// result. - Value *expandCodeFor(SCEVHandle SH, Instruction *IP, const Type *Ty = 0) { + Value *expandCodeFor(SCEVHandle SH, Instruction *IP) { // Expand the code for this SCEV. this->InsertPt = IP; - return expandInTy(SH, Ty); + return expand(SH); } /// InsertCastOfTo - Insert a cast of V to the specified type, doing what @@ -107,25 +104,6 @@ return V; } - Value *expandInTy(SCEV *S, const Type *Ty) { - Value *V = expand(S); - if (Ty && V->getType() != Ty) { - if (isa(Ty) && V->getType()->isInteger()) - return InsertCastOfTo(Instruction::IntToPtr, V, Ty); - else if (Ty->isInteger() && isa(V->getType())) - return InsertCastOfTo(Instruction::PtrToInt, V, Ty); - else if (Ty->getPrimitiveSizeInBits() == - V->getType()->getPrimitiveSizeInBits()) - return InsertCastOfTo(Instruction::BitCast, V, Ty); - else if (Ty->getPrimitiveSizeInBits() > - V->getType()->getPrimitiveSizeInBits()) - return InsertCastOfTo(Instruction::ZExt, V, Ty); - else - return InsertCastOfTo(Instruction::Trunc, V, Ty); - } - return V; - } - Value *visitConstant(SCEVConstant *S) { return S->getValue(); } @@ -136,17 +114,21 @@ } Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) { - Value *V = expandInTy(S->getOperand(), S->getType()); + Value *V = expand(S->getOperand()); return CastInst::createZExtOrBitCast(V, S->getType(), "tmp.", InsertPt); } + Value *visitSignExtendExpr(SCEVSignExtendExpr *S) { + Value *V = expand(S->getOperand()); + return CastInst::createSExtOrBitCast(V, S->getType(), "tmp.", InsertPt); + } + Value *visitAddExpr(SCEVAddExpr *S) { - const Type *Ty = S->getType(); - Value *V = expandInTy(S->getOperand(S->getNumOperands()-1), Ty); + Value *V = expand(S->getOperand(S->getNumOperands()-1)); // Emit a bunch of add instructions for (int i = S->getNumOperands()-2; i >= 0; --i) - V = InsertBinop(Instruction::Add, V, expandInTy(S->getOperand(i), Ty), + V = InsertBinop(Instruction::Add, V, expand(S->getOperand(i)), InsertPt); return V; } @@ -154,9 +136,8 @@ Value *visitMulExpr(SCEVMulExpr *S); Value *visitSDivExpr(SCEVSDivExpr *S) { - const Type *Ty = S->getType(); - Value *LHS = expandInTy(S->getLHS(), Ty); - Value *RHS = expandInTy(S->getRHS(), Ty); + Value *LHS = expand(S->getLHS()); + Value *RHS = expand(S->getRHS()); return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt); } Index: llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h diff -u llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h:1.11 llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h:1.12 --- llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h:1.11 Thu Mar 1 16:28:51 2007 +++ llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h Fri Jun 15 09:38:12 2007 @@ -24,8 +24,8 @@ enum SCEVTypes { // These should be ordered in terms of increasing complexity to make the // folders simpler. - scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scSDivExpr, - scAddRecExpr, scUnknown, scCouldNotCompute + scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, + scSDivExpr, scAddRecExpr, scUnknown, scCouldNotCompute }; //===--------------------------------------------------------------------===// @@ -166,6 +166,53 @@ } }; + //===--------------------------------------------------------------------===// + /// SCEVSignExtendExpr - This class represents a sign extension of a small + /// integer value to a larger integer value. + /// + class SCEVSignExtendExpr : public SCEV { + SCEVHandle Op; + const Type *Ty; + SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty); + virtual ~SCEVSignExtendExpr(); + public: + /// get method - This just gets and returns a new SCEVSignExtend object + /// + static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); + + const SCEVHandle &getOperand() const { return Op; } + virtual const Type *getType() const { return Ty; } + + virtual bool isLoopInvariant(const Loop *L) const { + return Op->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return Op->hasComputableLoopEvolution(L); + } + + /// getValueRange - Return the tightest constant bounds that this value is + /// known to have. This method is only valid on integer SCEV objects. + virtual ConstantRange getValueRange() const; + + SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, + const SCEVHandle &Conc) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + if (H == Op) + return this; + return get(H, Ty); + } + + virtual void print(std::ostream &OS) const; + void print(std::ostream *OS) const { if (OS) print(*OS); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVSignExtendExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scSignExtend; + } + }; + //===--------------------------------------------------------------------===// /// SCEVCommutativeExpr - This node is the base class for n'ary commutative @@ -503,6 +550,8 @@ return ((SC*)this)->visitTruncateExpr((SCEVTruncateExpr*)S); case scZeroExtend: return ((SC*)this)->visitZeroExtendExpr((SCEVZeroExtendExpr*)S); + case scSignExtend: + return ((SC*)this)->visitSignExtendExpr((SCEVSignExtendExpr*)S); case scAddExpr: return ((SC*)this)->visitAddExpr((SCEVAddExpr*)S); case scMulExpr: From djg at cray.com Fri Jun 15 09:38:43 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 15 Jun 2007 09:38:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp ScalarEvolutionExpander.cpp Message-ID: <200706151438.l5FEchan020006@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.118 -> 1.119 ScalarEvolutionExpander.cpp updated: 1.17 -> 1.18 --- Log message: Add a SCEV class and supporting code for sign-extend expressions. This created an ambiguity for expandInTy to decide when to use sign-extension or zero-extension, but it turns out that most of its callers don't actually need a type conversion, now that LLVM types don't have explicit signedness. Drop expandInTy in favor of plain expand, and change the few places that actually need a type conversion to do it themselves. --- Diffs of the changes: (+53 -7) ScalarEvolution.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++ ScalarEvolutionExpander.cpp | 13 +++++------- 2 files changed, 53 insertions(+), 7 deletions(-) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.118 llvm/lib/Analysis/ScalarEvolution.cpp:1.119 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.118 Wed Jun 6 06:26:20 2007 +++ llvm/lib/Analysis/ScalarEvolution.cpp Fri Jun 15 09:38:12 2007 @@ -245,6 +245,32 @@ OS << "(zeroextend " << *Op << " to " << *Ty << ")"; } +// SCEVSignExtends - Only allow the creation of one SCEVSignExtendExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static ManagedStatic, + SCEVSignExtendExpr*> > SCEVSignExtends; + +SCEVSignExtendExpr::SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty) + : SCEV(scSignExtend), Op(op), Ty(ty) { + assert(Op->getType()->isInteger() && Ty->isInteger() && + "Cannot sign extend non-integer value!"); + assert(Op->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits() + && "This is not an extending conversion!"); +} + +SCEVSignExtendExpr::~SCEVSignExtendExpr() { + SCEVSignExtends->erase(std::make_pair(Op, Ty)); +} + +ConstantRange SCEVSignExtendExpr::getValueRange() const { + return getOperand()->getValueRange().signExtend(getBitWidth()); +} + +void SCEVSignExtendExpr::print(std::ostream &OS) const { + OS << "(signextend " << *Op << " to " << *Ty << ")"; +} + // SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! @@ -588,6 +614,21 @@ return Result; } +SCEVHandle SCEVSignExtendExpr::get(const SCEVHandle &Op, const Type *Ty) { + if (SCEVConstant *SC = dyn_cast(Op)) + return SCEVUnknown::get( + ConstantExpr::getSExt(SC->getValue(), Ty)); + + // FIXME: If the input value is a chrec scev, and we can prove that the value + // did not overflow the old, smaller, value, we can sign extend all of the + // operands (often constants). This would allow analysis of something like + // this: for (signed char X = 0; X < 100; ++X) { int Y = X; } + + SCEVSignExtendExpr *&Result = (*SCEVSignExtends)[std::make_pair(Op, Ty)]; + if (Result == 0) Result = new SCEVSignExtendExpr(Op, Ty); + return Result; +} + // get - Get a canonical add expression, or something simpler if possible. SCEVHandle SCEVAddExpr::get(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty add!"); @@ -1370,6 +1411,9 @@ if (SCEVZeroExtendExpr *E = dyn_cast(S)) return GetConstantFactor(E->getOperand()).zext( cast(E->getType())->getBitWidth()); + if (SCEVSignExtendExpr *E = dyn_cast(S)) + return GetConstantFactor(E->getOperand()).sext( + cast(E->getType())->getBitWidth()); if (SCEVAddExpr *A = dyn_cast(S)) { // The result is the min of all operands. @@ -1470,6 +1514,9 @@ case Instruction::ZExt: return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + case Instruction::SExt: + return SCEVSignExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + case Instruction::BitCast: // BitCasts are no-op casts so we just eliminate the cast. if (I->getType()->isInteger() && Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.17 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.18 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.17 Tue Apr 17 18:43:50 2007 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Fri Jun 15 09:38:12 2007 @@ -93,18 +93,17 @@ } Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { - const Type *Ty = S->getType(); int FirstOp = 0; // Set if we should emit a subtract. if (SCEVConstant *SC = dyn_cast(S->getOperand(0))) if (SC->getValue()->isAllOnesValue()) FirstOp = 1; int i = S->getNumOperands()-2; - Value *V = expandInTy(S->getOperand(i+1), Ty); + Value *V = expand(S->getOperand(i+1)); // Emit a bunch of multiply instructions for (; i >= FirstOp; --i) - V = InsertBinop(Instruction::Mul, V, expandInTy(S->getOperand(i), Ty), + V = InsertBinop(Instruction::Mul, V, expand(S->getOperand(i)), InsertPt); // -1 * ... ---> 0 - ... if (FirstOp == 1) @@ -122,10 +121,10 @@ // {X,+,F} --> X + {0,+,F} if (!isa(S->getStart()) || !cast(S->getStart())->getValue()->isZero()) { - Value *Start = expandInTy(S->getStart(), Ty); + Value *Start = expand(S->getStart()); std::vector NewOps(S->op_begin(), S->op_end()); NewOps[0] = SCEVUnknown::getIntegerSCEV(0, Ty); - Value *Rest = expandInTy(SCEVAddRecExpr::get(NewOps, L), Ty); + Value *Rest = expand(SCEVAddRecExpr::get(NewOps, L)); // FIXME: look for an existing add to use. return InsertBinop(Instruction::Add, Rest, Start, InsertPt); @@ -164,7 +163,7 @@ // If this is a simple linear addrec, emit it now as a special case. if (S->getNumOperands() == 2) { // {0,+,F} --> i*F - Value *F = expandInTy(S->getOperand(1), Ty); + Value *F = expand(S->getOperand(1)); // IF the step is by one, just return the inserted IV. if (ConstantInt *CI = dyn_cast(F)) @@ -201,5 +200,5 @@ SCEVHandle V = S->evaluateAtIteration(IH); //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; - return expandInTy(V, Ty); + return expand(V); } From baldrick at free.fr Fri Jun 15 12:01:12 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 15 Jun 2007 19:01:12 +0200 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> References: <200706131955.15130.baldrick@free.fr> <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> Message-ID: <200706151901.12723.baldrick@free.fr> > Seems fine to me, minor comments: How about this? [I had to make the critical edge detection less conservative after finding a testcase in which some critical edges were not empty]. Ciao, Duncan. -------------- next part -------------- A non-text attachment was scrubbed... Name: eh_hack.diff Type: text/x-diff Size: 7845 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070615/812fae81/attachment.bin From baldrick at free.fr Fri Jun 15 12:14:26 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 15 Jun 2007 12:14:26 -0500 Subject: [llvm-commits] CVS: llvm/test/C++Frontend/2007-05-23-TryFinally.cpp Message-ID: <200706151714.l5FHEQpj024065@zion.cs.uiuc.edu> Changes in directory llvm/test/C++Frontend: 2007-05-23-TryFinally.cpp updated: 1.2 -> 1.3 --- Log message: Use "ignore" rather than grep tricks. --- Diffs of the changes: (+2 -1) 2007-05-23-TryFinally.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/test/C++Frontend/2007-05-23-TryFinally.cpp diff -u llvm/test/C++Frontend/2007-05-23-TryFinally.cpp:1.2 llvm/test/C++Frontend/2007-05-23-TryFinally.cpp:1.3 --- llvm/test/C++Frontend/2007-05-23-TryFinally.cpp:1.2 Thu Jun 7 04:00:48 2007 +++ llvm/test/C++Frontend/2007-05-23-TryFinally.cpp Fri Jun 15 12:13:53 2007 @@ -1,4 +1,5 @@ -// RUN: %llvmgxx %s -S -emit-llvm -O2 -o - | grep -c {handle\\|_Unwind_Resume} | grep {\[14\]} +// RUN: %llvmgxx %s -S -emit-llvm -O2 -o - | ignore grep _Unwind_Resume | \ +// RUN: wc -l | grep {\[03\]} struct One { }; struct Two { }; From evan.cheng at apple.com Fri Jun 15 12:35:11 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 12:35:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706151735.l5FHZBkj024485@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.51 -> 1.52 --- Log message: Extra edges are deleted later if needed. --- Diffs of the changes: (+0 -1) IfConversion.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.51 llvm/lib/CodeGen/IfConversion.cpp:1.52 --- llvm/lib/CodeGen/IfConversion.cpp:1.51 Fri Jun 15 02:36:12 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Fri Jun 15 12:34:48 2007 @@ -806,7 +806,6 @@ // Copy instructions in the true block, predicate them add them to // the entry block. CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true); - BBI.BB->removeSuccessor(CvtBBI->BB); } else { // Predicate the 'true' block after removing its branch. CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); From clattner at apple.com Fri Jun 15 12:53:10 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 15 Jun 2007 10:53:10 -0700 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <200706151901.12723.baldrick@free.fr> References: <200706131955.15130.baldrick@free.fr> <64CF8F8E-82DF-4E39-976E-692E0B50B823@apple.com> <200706151901.12723.baldrick@free.fr> Message-ID: <0847B2E1-8553-41CC-AD8B-B7612833D730@apple.com> On Jun 15, 2007, at 10:01 AM, Duncan Sands wrote: >> Seems fine to me, minor comments: > > How about this? [I had to make the critical edge detection > less conservative after finding a testcase in which some > critical edges were not empty]. > > Ciao, > > Duncan. > Ah, another minor simplification: +/// isFilterOrSelector - Return true if this instruction is a call to the +/// eh.filter or the eh.selector intrinsic. +static bool isFilterOrSelector(Instruction *I) { if (IntrinsicInst *II = dyn_cast(I)) return II->getIntrinsicID() == Intrinsic::eh_selector || II->getIntrinsicID() == Intrinsic::eh_filter; return false; } Otherwise, looks great, please apply, -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070615/64aa169a/attachment.html From resistor at mac.com Fri Jun 15 12:54:28 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 15 Jun 2007 12:54:28 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/2007-06-15-Looping.ll Message-ID: <200706151754.l5FHsSji024914@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: 2007-06-15-Looping.ll added (r1.1) --- Log message: Add a testcase where GVNPRE what getting confused by a loop. --- Diffs of the changes: (+22 -0) 2007-06-15-Looping.ll | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/test/Transforms/GVNPRE/2007-06-15-Looping.ll diff -c /dev/null llvm/test/Transforms/GVNPRE/2007-06-15-Looping.ll:1.1 *** /dev/null Fri Jun 15 12:54:15 2007 --- llvm/test/Transforms/GVNPRE/2007-06-15-Looping.ll Fri Jun 15 12:54:05 2007 *************** *** 0 **** --- 1,22 ---- + ; RUN: llvm-as < %s | opt -gvnpre | llvm-dis + + define fastcc void @compute_max_score_1() { + entry: + %tmp7 = sub i32 0, 0 ; [#uses=0] + br label %bb + + bb: ; preds = %bb212, %entry + %indvar29 = phi i32 [ 0, %entry ], [ %indvar.next30, %bb212 ] ; [#uses=2] + %j.01.0 = sub i32 %indvar29, 0 ; [#uses=0] + br label %cond_next166 + + cond_next166: ; preds = %cond_next166, %bb + br i1 false, label %bb212, label %cond_next166 + + bb212: ; preds = %cond_next166 + %indvar.next30 = add i32 %indvar29, 1 ; [#uses=1] + br i1 false, label %return, label %bb + + return: ; preds = %bb212 + ret void + } From resistor at mac.com Fri Jun 15 12:55:37 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 15 Jun 2007 12:55:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706151755.l5FHtbHi024947@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.32 -> 1.33 --- Log message: Fix test/Transforms/GVNPRE/2007-06-15-Looping.ll --- Diffs of the changes: (+2 -4) GVNPRE.cpp | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.32 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.33 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.32 Tue Jun 12 17:43:57 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Fri Jun 15 12:55:15 2007 @@ -801,15 +801,13 @@ Value* s1 = 0; if (isa(U->getOperand(0))) - s1 = find_leader(availableOut[*PI], - phi_translate(U->getOperand(0), *PI, BB)); + s1 = find_leader(availableOut[*PI], U->getOperand(0)); else s1 = U->getOperand(0); Value* s2 = 0; if (isa(U->getOperand(1))) - s2 = find_leader(availableOut[*PI], - phi_translate(U->getOperand(1), *PI, BB)); + s2 = find_leader(availableOut[*PI], U->getOperand(1)); else s2 = U->getOperand(1); From djg at cray.com Fri Jun 15 13:01:15 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 15 Jun 2007 13:01:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200706151801.l5FI1Fhm025195@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.121 -> 1.122 --- Log message: Use SCEVConstant::get instead of SCEVUnknown::get to create an integer constant SCEV. --- Diffs of the changes: (+2 -2) IndVarSimplify.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.121 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.122 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.121 Fri Jun 15 09:38:12 2007 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Jun 15 13:00:55 2007 @@ -264,8 +264,8 @@ // The IterationCount expression contains the number of times that the // backedge actually branches to the loop header. This is one less than the // number of times the loop executes, so add one to it. - Constant *OneC = ConstantInt::get(IterationCount->getType(), 1); - TripCount = SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC)); + ConstantInt *OneC = ConstantInt::get(IterationCount->getType(), 1); + TripCount = SCEVAddExpr::get(IterationCount, SCEVConstant::get(OneC)); IndVar = L->getCanonicalInductionVariableIncrement(); } else { // We have to use the preincremented value... From baldrick at free.fr Fri Jun 15 14:04:43 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 15 Jun 2007 14:04:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706151904.l5FJ4hSm027197@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.463 -> 1.464 --- Log message: Workaround for PR1508: http://llvm.org/PR1508 . --- Diffs of the changes: (+96 -29) SelectionDAGISel.cpp | 125 +++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 96 insertions(+), 29 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.463 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.464 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.463 Thu Jun 14 17:58:02 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jun 15 14:04:19 2007 @@ -179,6 +179,11 @@ /// anywhere in the function. std::map StaticAllocaMap; +#ifndef NDEBUG + SmallSet CatchInfoLost; + SmallSet CatchInfoFound; +#endif + unsigned MakeReg(MVT::ValueType VT) { return RegMap->createVirtualRegister(TLI.getRegClassFor(VT)); } @@ -199,6 +204,15 @@ }; } +/// isFilterOrSelector - Return true if this instruction is a call to the +/// eh.filter or the eh.selector intrinsic. +static bool isFilterOrSelector(Instruction *I) { + if (IntrinsicInst *II = dyn_cast(I)) + return II->getIntrinsicID() == Intrinsic::eh_selector + || II->getIntrinsicID() == Intrinsic::eh_filter; + return false; +} + /// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by /// PHI nodes or outside of the basic block that defines it, or used by a /// switch instruction, which may expand to multiple basic blocks. @@ -2463,6 +2477,33 @@ return NULL; } +/// addCatchInfo - Extract the personality and type infos from an eh.selector +/// or eh.filter call, and add them to the specified machine basic block. +static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI, + MachineBasicBlock *MBB) { + // Inform the MachineModuleInfo of the personality for this landing pad. + ConstantExpr *CE = cast(I.getOperand(2)); + assert(CE->getOpcode() == Instruction::BitCast && + isa(CE->getOperand(0)) && + "Personality should be a function"); + MMI->addPersonality(MBB, cast(CE->getOperand(0))); + + // Gather all the type infos for this landing pad and pass them along to + // MachineModuleInfo. + std::vector TyInfo; + for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) { + Constant *C = cast(I.getOperand(i)); + GlobalVariable *GV = ExtractGlobalVariable(C); + assert (GV || isa(C) && + "TypeInfo must be a global variable or NULL"); + TyInfo.push_back(GV); + } + if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter) + MMI->addFilterTypeInfo(MBB, TyInfo); + else + MMI->addCatchTypeInfo(MBB, TyInfo); +} + /// visitIntrinsicCall - Lower the call to the specified intrinsic function. If /// we want to emit this as a call to a named external function, return the name /// otherwise lower it and return null. @@ -2595,29 +2636,14 @@ case Intrinsic::eh_selector: case Intrinsic::eh_filter:{ MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - + if (ExceptionHandling && MMI) { - // Inform the MachineModuleInfo of the personality for this landing pad. - ConstantExpr *CE = dyn_cast(I.getOperand(2)); - assert(CE && CE->getOpcode() == Instruction::BitCast && - isa(CE->getOperand(0)) && - "Personality should be a function"); - MMI->addPersonality(CurMBB, cast(CE->getOperand(0))); - - // Gather all the type infos for this landing pad and pass them along to - // MachineModuleInfo. - std::vector TyInfo; - for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) { - Constant *C = cast(I.getOperand(i)); - GlobalVariable *GV = ExtractGlobalVariable(C); - assert (GV || isa(C) && - "TypeInfo must be a global variable or NULL"); - TyInfo.push_back(GV); - } - if (Intrinsic == Intrinsic::eh_filter) - MMI->addFilterTypeInfo(CurMBB, TyInfo); + if (CurMBB->isLandingPad()) + addCatchInfo(I, MMI, CurMBB); +#ifndef NDEBUG else - MMI->addCatchTypeInfo(CurMBB, TyInfo); + FuncInfo.CatchInfoLost.insert(&I); +#endif // Mark exception selector register as live in. unsigned Reg = TLI.getExceptionSelectorRegister(); @@ -4403,6 +4429,11 @@ E = MF.livein_end(); I != E; ++I) BB->addLiveIn(I->first); +#ifndef NDEBUG + assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() && + "Not all catch info was assigned to a landing pad!"); +#endif + return true; } @@ -4513,6 +4544,20 @@ EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction()); } +static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB, + MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) { + assert(!FLI.MBBMap[SrcBB]->isLandingPad() && + "Copying catch info out of a landing pad!"); + for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I) + if (isFilterOrSelector(I)) { + // Apply the catch info to DestBB. + addCatchInfo(cast(*I), MMI, FLI.MBBMap[DestBB]); +#ifndef NDEBUG + FLI.CatchInfoFound.insert(I); +#endif + } +} + void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, std::vector > &PHINodesToUpdate, FunctionLoweringInfo &FuncInfo) { @@ -4527,15 +4572,37 @@ BB = FuncInfo.MBBMap[LLVMBB]; SDL.setCurrentBasicBlock(BB); - if (ExceptionHandling && BB->isLandingPad()) { - MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); + MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - if (MMI) { - // Add a label to mark the beginning of the landing pad. Deletion of the - // landing pad can thus be detected via the MachineModuleInfo. - unsigned LabelID = MMI->addLandingPad(BB); - DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(), - DAG.getConstant(LabelID, MVT::i32))); + if (ExceptionHandling && MMI && BB->isLandingPad()) { + // Add a label to mark the beginning of the landing pad. Deletion of the + // landing pad can thus be detected via the MachineModuleInfo. + unsigned LabelID = MMI->addLandingPad(BB); + DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(), + DAG.getConstant(LabelID, MVT::i32))); + + // FIXME: Hack around an exception handling flaw (PR1508): the personality + // function and list of typeids logically belong to the invoke (or, if you + // like, the basic block containing the invoke), and need to be associated + // with it in the dwarf exception handling tables. Currently however the + // information is provided by intrinsics (eh.filter and eh.selector) that + // can be moved to unexpected places by the optimizers: if the unwind edge + // is critical, then breaking it can result in the intrinsics being in the + // successor of the landing pad, not the landing pad itself. This results + // in exceptions not being caught because no typeids are associated with + // the invoke. This may not be the only way things can go wrong, but it + // is the only way we try to work around for the moment. + BranchInst *Br = dyn_cast(LLVMBB->getTerminator()); + + if (Br && Br->isUnconditional()) { // Critical edge? + BasicBlock::iterator I, E; + for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I) + if (isFilterOrSelector(I)) + break; + + if (I == E) + // No catch info found - try to extract some from the successor. + copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo); } } From baldrick at free.fr Fri Jun 15 14:04:44 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 15 Jun 2007 14:04:44 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll 2007-06-06-CriticalEdgeLandingPad.ll Message-ID: <200706151904.l5FJ4i6B027202@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/Generic: 2007-04-14-EHSelectorCrash.ll updated: 1.2 -> 1.3 2007-06-06-CriticalEdgeLandingPad.ll updated: 1.1 -> 1.2 --- Log message: Workaround for PR1508: http://llvm.org/PR1508 . --- Diffs of the changes: (+5 -1) 2007-04-14-EHSelectorCrash.ll | 2 ++ 2007-06-06-CriticalEdgeLandingPad.ll | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll diff -u llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll:1.2 llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll:1.3 --- llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll:1.2 Fri Apr 27 12:12:23 2007 +++ llvm/test/CodeGen/Generic/2007-04-14-EHSelectorCrash.ll Fri Jun 15 14:04:19 2007 @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -enable-eh ; RUN: llvm-as < %s | llc -enable-eh -march=x86-64 +; XFAIL: * +; Un-XFAIL this when PR1508 is fixed. ; PR1326 Index: llvm/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll diff -u llvm/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll:1.1 llvm/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll:1.2 --- llvm/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll:1.1 Wed Jun 6 04:59:53 2007 +++ llvm/test/CodeGen/Generic/2007-06-06-CriticalEdgeLandingPad.ll Fri Jun 15 14:04:19 2007 @@ -1,5 +1,7 @@ -; RUN: llvm-as < %s | llc -enable-eh -asm-verbose -o - | grep {Llabel137.*Region start} +; RUN: llvm-as < %s | llc -enable-eh -asm-verbose -o - | \ +; RUN: grep -A 3 {Llabel137.*Region start} | grep {5.*Action} ; PR1422 +; PR1508 target triple = "i686-pc-linux-gnu" %struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* } From baldrick at free.fr Fri Jun 15 14:05:28 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 15 Jun 2007 21:05:28 +0200 Subject: [llvm-commits] Workaround for PR1508 In-Reply-To: <0847B2E1-8553-41CC-AD8B-B7612833D730@apple.com> References: <200706131955.15130.baldrick@free.fr> <200706151901.12723.baldrick@free.fr> <0847B2E1-8553-41CC-AD8B-B7612833D730@apple.com> Message-ID: <200706152105.29028.baldrick@free.fr> > Ah, another minor simplification: > > +/// isFilterOrSelector - Return true if this instruction is a call > to the > +/// eh.filter or the eh.selector intrinsic. > +static bool isFilterOrSelector(Instruction *I) { > if (IntrinsicInst *II = dyn_cast(I)) > return II->getIntrinsicID() == Intrinsic::eh_selector > || II->getIntrinsicID() == Intrinsic::eh_filter; > return false; > } That's pretty slick! Applied with this change. Thanks for reviewing, Duncan. From evan.cheng at apple.com Fri Jun 15 14:05:35 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 14:05:35 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200706151905.l5FJ5Z4d027230@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.221 -> 1.222 --- Log message: No longer needed. --- Diffs of the changes: (+0 -4) MachineInstr.h | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.221 llvm/include/llvm/CodeGen/MachineInstr.h:1.222 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.221 Tue May 29 13:30:54 2007 +++ llvm/include/llvm/CodeGen/MachineInstr.h Fri Jun 15 14:05:13 2007 @@ -394,10 +394,6 @@ return true; } - /// isPredicable - True if the instruction can be converted into a - /// predicated instruction. - bool isPredicable() const; - /// clone - Create a copy of 'this' instruction that is identical in /// all ways except the the instruction has no parent, prev, or next. MachineInstr* clone() const { return new MachineInstr(*this); } From evan.cheng at apple.com Fri Jun 15 14:06:29 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 14:06:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp MachineInstr.cpp Message-ID: <200706151906.l5FJ6TTB027387@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.52 -> 1.53 MachineInstr.cpp updated: 1.151 -> 1.152 --- Log message: MachineInstr::isPredicable() is no longer needed. --- Diffs of the changes: (+5 -10) IfConversion.cpp | 11 +++++------ MachineInstr.cpp | 4 ---- 2 files changed, 5 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.52 llvm/lib/CodeGen/IfConversion.cpp:1.53 --- llvm/lib/CodeGen/IfConversion.cpp:1.52 Fri Jun 15 12:34:48 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Fri Jun 15 14:06:07 2007 @@ -447,7 +447,7 @@ if (TID->Flags & M_CLOBBERS_PRED) BBI.ClobbersPred = true; - if (!I->isPredicable()) { + if ((TID->Flags & M_PREDICABLE) == 0) { BBI.IsUnpredicable = true; return; } @@ -881,7 +881,8 @@ while (TT != BBI.TrueBB->end() && FT != BBI.FalseBB->end()) { if (TT->isIdenticalTo(FT)) Dups.push_back(TT); // Will erase these later. - else if (!TT->isPredicable() && !FT->isPredicable()) + else if ((TT->getInstrDescriptor()->Flags & M_PREDICABLE) == 0 || + (FT->getInstrDescriptor()->Flags & M_PREDICABLE) == 0) return false; // Can't if-convert. Abort! ++TT; ++FT; @@ -890,15 +891,13 @@ // One of the two pathes have more terminators, make sure they are // all predicable. while (TT != BBI.TrueBB->end()) { - if (!TT->isPredicable()) { + if ((TT->getInstrDescriptor()->Flags & M_PREDICABLE) == 0) return false; // Can't if-convert. Abort! - } ++TT; } while (FT != BBI.FalseBB->end()) { - if (!FT->isPredicable()) { + if ((FT->getInstrDescriptor()->Flags & M_PREDICABLE) == 0) return false; // Can't if-convert. Abort! - } ++FT; } } Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.151 llvm/lib/CodeGen/MachineInstr.cpp:1.152 --- llvm/lib/CodeGen/MachineInstr.cpp:1.151 Tue May 29 13:33:12 2007 +++ llvm/lib/CodeGen/MachineInstr.cpp Fri Jun 15 14:06:07 2007 @@ -184,10 +184,6 @@ } } -bool MachineInstr::isPredicable() const { - return TID->Flags & M_PREDICABLE; -} - /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of /// the specific register or -1 if it is not found. It further tightening /// the search criteria to a use that kills the register if isKill is true. From sabre at nondot.org Fri Jun 15 14:10:12 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 14:10:12 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/inline-asm-x-scalar.ll Message-ID: <200706151910.l5FJACRe027597@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: inline-asm-x-scalar.ll updated: 1.2 -> 1.3 --- Log message: make this test harder, include a tied register. --- Diffs of the changes: (+7 -0) inline-asm-x-scalar.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/CodeGen/X86/inline-asm-x-scalar.ll diff -u llvm/test/CodeGen/X86/inline-asm-x-scalar.ll:1.2 llvm/test/CodeGen/X86/inline-asm-x-scalar.ll:1.3 --- llvm/test/CodeGen/X86/inline-asm-x-scalar.ll:1.2 Mon Apr 9 00:26:48 2007 +++ llvm/test/CodeGen/X86/inline-asm-x-scalar.ll Fri Jun 15 14:09:53 2007 @@ -15,3 +15,10 @@ ret void } +define void @test4() { + %tmp1 = tail call float asm "", "=x,0,~{dirflag},~{fpsr},~{flags}"( float 0x47EFFFFFE0000000 ); [#uses=1] + %tmp4 = sub float %tmp1, 0x3810000000000000 ; [#uses=1] + tail call void asm sideeffect "", "x,~{dirflag},~{fpsr},~{flags}"( float %tmp4 ) + ret void +} + From sabre at nondot.org Fri Jun 15 14:11:21 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 15 Jun 2007 14:11:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706151911.l5FJBLtf027684@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.464 -> 1.465 --- Log message: Fix CodeGen/X86/inline-asm-x-scalar.ll:test4, by retaining regclass info for tied register constraints. --- Diffs of the changes: (+9 -6) SelectionDAGISel.cpp | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.464 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.465 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.464 Fri Jun 15 14:04:19 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jun 15 14:11:01 2007 @@ -3222,7 +3222,8 @@ // Otherwise, if this was a reference to an LLVM register class, create vregs // for this reference. std::vector RegClassRegs; - if (PhysReg.second) { + const TargetRegisterClass *RC = PhysReg.second; + if (RC) { // If this is an early clobber or tied register, our regalloc doesn't know // how to maintain the constraint. If it isn't, go ahead and create vreg // and let the regalloc do the right thing. @@ -3272,11 +3273,13 @@ // Check to see if this register is allocatable (i.e. don't give out the // stack pointer). - const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, TLI, MRI); - if (!RC) { - // Make sure we find consecutive registers. - NumAllocated = 0; - continue; + if (RC == 0) { + RC = isAllocatableRegister(Reg, MF, TLI, MRI); + if (!RC) { // Couldn't allocate this register. + // Reset NumAllocated to make sure we return consecutive registers. + NumAllocated = 0; + continue; + } } // Okay, this register is good, we can use it. From djg at cray.com Fri Jun 15 14:22:17 2007 From: djg at cray.com (Dan Gohman) Date: Fri, 15 Jun 2007 14:22:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200706151922.l5FJMHPX028326@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolutionExpander.cpp updated: 1.18 -> 1.19 --- Log message: Fold a binary operator with constant operands when expanding code for a SCEV. --- Diffs of the changes: (+5 -0) ScalarEvolutionExpander.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.18 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.19 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.18 Fri Jun 15 09:38:12 2007 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Fri Jun 15 14:21:55 2007 @@ -72,6 +72,11 @@ /// of work to avoid inserting an obviously redundant operation. Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, Instruction *&InsertPt) { + // Fold a binop with constant operands. + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) + return ConstantExpr::get(Opcode, CLHS, CRHS); + // Do a quick scan to see if we have this binop nearby. If so, reuse it. unsigned ScanLimit = 6; for (BasicBlock::iterator IP = InsertPt, E = InsertPt->getParent()->begin(); From criswell at cs.uiuc.edu Fri Jun 15 15:04:33 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 15 Jun 2007 15:04:33 -0500 Subject: [llvm-commits] CVS: llvm-www/SVNMigration.html Message-ID: <200706152004.PAA03944@choi.cs.uiuc.edu> Changes in directory llvm-www: SVNMigration.html updated: 1.14 -> 1.15 --- Log message: Bumped date back. --- Diffs of the changes: (+2 -2) SVNMigration.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/SVNMigration.html diff -u llvm-www/SVNMigration.html:1.14 llvm-www/SVNMigration.html:1.15 --- llvm-www/SVNMigration.html:1.14 Fri Apr 20 22:43:01 2007 +++ llvm-www/SVNMigration.html Fri Jun 15 15:03:47 2007 @@ -8,7 +8,7 @@
    Schedule
    -

    When: June 5, 2007, approx. 1pm CDT (Central Time USA) or 18:00 GMT).

    +

    When: (Tentatively) June 25, 2007, approx. 1pm CDT (Central Time USA) or 18:00 GMT).

    Duration: 4 hours

    Notices:: Notices will be sent out 1 week before, 1 day before, and 1 hour before the conversion actually takes place.

    @@ -219,6 +219,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
    Last modified: $Date: 2007/04/21 03:43:01 $ +
    Last modified: $Date: 2007/06/15 20:03:47 $ From criswell at cs.uiuc.edu Fri Jun 15 15:11:27 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 15 Jun 2007 15:11:27 -0500 Subject: [llvm-commits] CVS: llvm-www/devmtg/2007-05/08-Criswell-SVA.pdf Message-ID: <200706152011.PAA04017@choi.cs.uiuc.edu> Changes in directory llvm-www/devmtg/2007-05: 08-Criswell-SVA.pdf added (r1.1) --- Log message: PDF of Slides --- Diffs of the changes: (+0 -0) 08-Criswell-SVA.pdf | 0 1 files changed Index: llvm-www/devmtg/2007-05/08-Criswell-SVA.pdf From criswell at cs.uiuc.edu Fri Jun 15 15:13:31 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 15 Jun 2007 15:13:31 -0500 Subject: [llvm-commits] CVS: llvm-www/devmtg/2007-05/index.html Message-ID: <200706152013.PAA04044@choi.cs.uiuc.edu> Changes in directory llvm-www/devmtg/2007-05: index.html updated: 1.8 -> 1.9 --- Log message: Added slides in PDF and PowerPoint format. --- Diffs of the changes: (+3 -1) index.html | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-www/devmtg/2007-05/index.html diff -u llvm-www/devmtg/2007-05/index.html:1.8 llvm-www/devmtg/2007-05/index.html:1.9 --- llvm-www/devmtg/2007-05/index.html:1.8 Thu May 31 17:23:04 2007 +++ llvm-www/devmtg/2007-05/index.html Fri Jun 15 15:13:04 2007 @@ -97,6 +97,8 @@ Processor Element. video + slides (PDF) + slides (PPT) John Criswell Secure Virtual Architecture - A presentation on our research to create a virtual machine that operates below the operating system and a @@ -245,6 +247,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
    Last modified: $Date: 2007/05/31 22:23:04 $ +
    Last modified: $Date: 2007/06/15 20:13:04 $ From criswell at cs.uiuc.edu Fri Jun 15 15:15:40 2007 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 15 Jun 2007 15:15:40 -0500 Subject: [llvm-commits] CVS: llvm-www/devmtg/2007-05/index.html Message-ID: <200706152015.PAA04122@choi.cs.uiuc.edu> Changes in directory llvm-www/devmtg/2007-05: index.html updated: 1.9 -> 1.10 --- Log message: Fixed formatting. --- Diffs of the changes: (+4 -4) index.html | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-www/devmtg/2007-05/index.html diff -u llvm-www/devmtg/2007-05/index.html:1.9 llvm-www/devmtg/2007-05/index.html:1.10 --- llvm-www/devmtg/2007-05/index.html:1.9 Fri Jun 15 15:13:04 2007 +++ llvm-www/devmtg/2007-05/index.html Fri Jun 15 15:15:14 2007 @@ -96,9 +96,9 @@ implementation of an LLVM back-end Target for the Cell BE Symbiotic Processor Element. - video - slides (PDF) - slides (PPT) + video
    + slides (PDF)
    + slides (PPT) John Criswell Secure Virtual Architecture - A presentation on our research to create a virtual machine that operates below the operating system and a @@ -247,6 +247,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
    Last modified: $Date: 2007/06/15 20:13:04 $ +
    Last modified: $Date: 2007/06/15 20:15:14 $ From clattner at apple.com Fri Jun 15 15:51:06 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 15 Jun 2007 13:51:06 -0700 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp LoopStrengthReduce.cpp In-Reply-To: <200706151438.l5FEcdga019992@zion.cs.uiuc.edu> References: <200706151438.l5FEcdga019992@zion.cs.uiuc.edu> Message-ID: <7A9598EB-A3AB-4EB7-972D-DBCE43473027@apple.com> On Jun 15, 2007, at 7:38 AM, Dan Gohman wrote: > > > Changes in directory llvm/lib/Transforms/Scalar: > > IndVarSimplify.cpp updated: 1.120 -> 1.121 > LoopStrengthReduce.cpp updated: 1.140 -> 1.141 > --- > Log message: > > Add a SCEV class and supporting code for sign-extend expressions. > > This created an ambiguity for expandInTy to decide when to use > sign-extension or zero-extension, but it turns out that most of its > callers > don't actually need a type conversion, now that LLVM types don't have > explicit signedness. Drop expandInTy in favor of plain expand, and > change > the few places that actually need a type conversion to do it > themselves. Very nice! -Chris From tonic at nondot.org Fri Jun 15 15:51:16 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 15 Jun 2007 15:51:16 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200706152051.l5FKpGvB030653@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td updated: 1.55 -> 1.56 --- Log message: Add local var annotation intrinsic. --- Diffs of the changes: (+5 -0) Intrinsics.td | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/Intrinsics.td diff -u llvm/include/llvm/Intrinsics.td:1.55 llvm/include/llvm/Intrinsics.td:1.56 --- llvm/include/llvm/Intrinsics.td:1.55 Wed Apr 11 21:48:45 2007 +++ llvm/include/llvm/Intrinsics.td Fri Jun 15 15:50:54 2007 @@ -235,6 +235,11 @@ llvm_vararg_ty]>; def int_eh_typeid_for : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>; +//===---------------- Generic Variable Attribute Intrinsics----------------===// +// +def int_var_annotation : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty], + [], "llvm.var.annotation">; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// From tonic at nondot.org Fri Jun 15 15:51:16 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 15 Jun 2007 15:51:16 -0500 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200706152051.l5FKpGqu030659@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.254 -> 1.255 --- Log message: Add local var annotation intrinsic. --- Diffs of the changes: (+51 -1) LangRef.html | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 51 insertions(+), 1 deletion(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.254 llvm/docs/LangRef.html:1.255 --- llvm/docs/LangRef.html:1.254 Tue Jun 12 12:01:15 2007 +++ llvm/docs/LangRef.html Fri Jun 15 15:50:54 2007 @@ -191,6 +191,12 @@
  • Debugger intrinsics
  • Exception Handling intrinsics
  • +
  • General intrinsics
  • +
      +
    1. 'llvm.var.annotation' + Intrinsic
    2. +
    + @@ -4819,6 +4825,50 @@ Handling document.

    + + + +
    +

    This class of intrinsics is designed to be generic and has +no specific purpose.

    +
    + + + + +
    + +
    Syntax:
    +
    +  declare void @llvm.var.annotation(i8* <val>, i8* <str>)
    +
    + +
    Overview:
    + +

    +The 'llvm.var.annotation' intrinsic +

    + +
    Arguments:
    + +

    +The first argument is a pointer to a value, and the second is a pointer to a +global string. +

    + +
    Semantics:
    + +

    +This intrinsic allows annotation of local variables with arbitrary strings. +This can be useful for special purpose optimizations that want to look for these + annotations. These have no other defined use, they are ignored by code + generation and optimization. +

    +
    @@ -4830,7 +4880,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2007/06/12 17:01:15 $ + Last modified: $Date: 2007/06/15 20:50:54 $ From tonic at nondot.org Fri Jun 15 15:53:09 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 15 Jun 2007 15:53:09 -0500 Subject: [llvm-commits] CVS: llvm/test/CFrontend/2007-06-15-AnnotateAttribute.c Message-ID: <200706152053.l5FKr9gT030748@zion.cs.uiuc.edu> Changes in directory llvm/test/CFrontend: 2007-06-15-AnnotateAttribute.c added (r1.1) --- Log message: test case for annotate attribute --- Diffs of the changes: (+25 -0) 2007-06-15-AnnotateAttribute.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+) Index: llvm/test/CFrontend/2007-06-15-AnnotateAttribute.c diff -c /dev/null llvm/test/CFrontend/2007-06-15-AnnotateAttribute.c:1.1 *** /dev/null Fri Jun 15 15:52:57 2007 --- llvm/test/CFrontend/2007-06-15-AnnotateAttribute.c Fri Jun 15 15:52:47 2007 *************** *** 0 **** --- 1,25 ---- + // RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep llvm.global.annotations | grep foo \ + // RUN: | grep @X | grep @a + // RUN: %llvmgxx -c -emit-llvm %s -o - | llvm-dis | grep -c llvm.var.annotation | grep 3 + + #include + + /* Global variable with attribute */ + int X __attribute__((annotate("GlobalValAnnotation"))); + + /* Function with attribute */ + int foo(int y) __attribute__((annotate("GlobalValAnnotation"))) + __attribute__((noinline)); + + int foo(int y __attribute__((annotate("LocalValAnnotation")))) { + int x __attribute__((annotate("LocalValAnnotation"))); + x = 34; + return y + x; + } + + int main() { + static int a __attribute__((annotate("GlobalValAnnotation"))); + a = foo(2); + printf("hello world%d\n", a); + return 0; + } From clattner at apple.com Fri Jun 15 15:53:51 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 15 Jun 2007 13:53:51 -0700 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp ScalarEvolutionExpander.cpp In-Reply-To: <200706151438.l5FEchan020006@zion.cs.uiuc.edu> References: <200706151438.l5FEchan020006@zion.cs.uiuc.edu> Message-ID: <0FD89829-CF88-4EEF-B0AA-FED6C0C30781@apple.com> On Jun 15, 2007, at 7:38 AM, Dan Gohman wrote: > + case Instruction::SExt: > + return SCEVSignExtendExpr::get(getSCEV(I->getOperand(0)), I- > >getType()); > + Nifty. Have you done any performance analysis of this? What cases is it beneficial for? If this helps LSR, for example, can you please add a testcase to verify this doesn't break in the future? Thanks Dan, great stuff, -Chris From lattner at apple.com Fri Jun 15 16:02:55 2007 From: lattner at apple.com (lattner at apple.com) Date: Fri, 15 Jun 2007 14:02:55 -0700 (PDT) Subject: [llvm-commits] [128471] Add annotate attribute. Message-ID: <20070615210255.7D2BA8D5A7B4@src> Revision: 128471 Author: lattner Date: 2007-06-15 14:02:55 -0700 (Fri, 15 Jun 2007) Log Message: ----------- Add annotate attribute. Modified Paths: -------------- apple-local/branches/llvm/gcc/c-common.c apple-local/branches/llvm/gcc/llvm-backend.cpp apple-local/branches/llvm/gcc/llvm-convert.cpp apple-local/branches/llvm/gcc/llvm-internal.h Modified: apple-local/branches/llvm/gcc/c-common.c =================================================================== --- apple-local/branches/llvm/gcc/c-common.c 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/c-common.c 2007-06-15 21:02:55 UTC (rev 128471) @@ -660,6 +660,12 @@ bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); +/* APPLE LOCAL begin LLVM */ +#ifdef ENABLE_LLVM +static tree handle_annotate_attribute (tree*, tree, tree, int, bool *); +#endif +/* APPLE LOCAL end LLVM */ + static void check_function_nonnull (tree, tree); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); @@ -747,6 +753,12 @@ handle_warn_unused_result_attribute }, { "sentinel", 0, 1, false, true, true, handle_sentinel_attribute }, + /* APPLE LOCAL begin LLVM */ + #ifdef ENABLE_LLVM + { "annotate", 0, -1, true, false, false, + handle_annotate_attribute }, + #endif + /* APPLE LOCAL end LLVM */ { NULL, 0, 0, false, false, false, NULL } }; @@ -5758,6 +5770,39 @@ return NULL_TREE; } +/* APPLE LOCAL begin LLVM */ +#ifdef ENABLE_LLVM +/* Handle "annotate" attribute */ +static tree +handle_annotate_attribute (tree *node, tree name, tree args, + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree id; + id = TREE_VALUE (args); + + if (TREE_CODE (*node) == FUNCTION_DECL || + TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == PARM_DECL) + { + + /* Arg must be a string and node must be a var or function decl */ + if (TREE_CODE (id) != STRING_CST) + { + error ("%qs attribute arg is required to be a string", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + } + else + { + warning ("%qs attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} +#endif +/* APPLE LOCAL end LLVM */ + /* Check for valid arguments being passed to a function. */ void check_function_arguments (tree attrs, tree params) Modified: apple-local/branches/llvm/gcc/llvm-backend.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-backend.cpp 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-backend.cpp 2007-06-15 21:02:55 UTC (rev 128471) @@ -81,6 +81,7 @@ std::vector > StaticCtors, StaticDtors; std::vector AttributeUsedGlobals; std::vector AttributeNoinlineFunctions; +std::vector > AttributeAnnotateGlobals; /// PerFunctionPasses - This is the list of cleanup passes run per-function /// as each is compiled. In cases where we are not doing IPO, it includes the @@ -489,6 +490,26 @@ AttributeNoinlineFunctions.clear(); } + // Add llvm.global.annotations + if (!AttributeAnnotateGlobals.empty()) { + std::vector AttrList; + + for (unsigned i = 0, e = AttributeAnnotateGlobals.size(); i != e; ++i) { + Constant *Elts[2] = {AttributeAnnotateGlobals[i].first, + AttributeAnnotateGlobals[i].second }; + AttrList.push_back(ConstantStruct::get(Elts, 2, false)); + } + + Constant *Array = + ConstantArray::get(ArrayType::get(AttrList[0]->getType(), AttrList.size()), + AttrList); + GlobalValue *gv = new GlobalVariable(Array->getType(), false, + GlobalValue::AppendingLinkage, Array, + "llvm.global.annotations", TheModule); + gv->setSection("llvm.metadata"); + + } + // Finish off the per-function pass. if (PerFunctionPasses) PerFunctionPasses->doFinalization(); @@ -650,7 +671,47 @@ return; } +/// AddAnnotateAttrsToGlobal - Adds decls that have a +/// annotate attribute to a vector to be emitted later. +void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree decl) { + // Handle annotate attribute on global. + tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + if (!annotateAttr) + return; + + // There may be multiple annotate attributes. Pass return of lookup_attr + // to successive lookups. + while (annotateAttr) { + + // Each annotate attribute is a tree list. + // Get value of list which is our linked list of args. + tree args = TREE_VALUE(annotateAttr); + + // Each annotate attribute may have multiple args. + // Treat each arg as if it were a separate annotate attribute. + for (tree a = args; a; a = TREE_CHAIN(a)) { + // Each element of the arg list is a tree list, so get value + tree val = TREE_VALUE(a); + + // Assert its a string, and then get that string. + assert(TREE_CODE(val) == STRING_CST && + "Annotate attribute arg should always be a string"); + Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + const Type *SBP= PointerType::get(Type::Int8Ty); + AttributeAnnotateGlobals.push_back( + std::make_pair(ConstantExpr::getBitCast(GV,SBP), + ConstantExpr::getBitCast(strGV,SBP))); + } + + // Get next annotate attribute. + annotateAttr = TREE_CHAIN(annotateAttr); + if (annotateAttr) + annotateAttr = lookup_attribute("annotate", annotateAttr); + } +} + + /// 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. @@ -762,6 +823,10 @@ const Type *SBP= PointerType::get(Type::Int8Ty); AttributeUsedGlobals.push_back(ConstantExpr::getBitCast(GV, SBP)); } + + // Add annotate attributes for globals + if (DECL_ATTRIBUTES(decl)) + AddAnnotateAttrsToGlobal(GV, decl); } if (TheDebugInfo) TheDebugInfo->EmitGlobalVariable(GV, decl); Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-06-15 21:02:55 UTC (rev 128471) @@ -600,6 +600,10 @@ AttributeNoinlineFunctions.push_back(ConstantExpr::getBitCast(Fn,SBP)); } + // Handle annotate attributes + if (DECL_ATTRIBUTES(FnDecl)) + AddAnnotateAttrsToGlobal(Fn, FnDecl); + // Create a new basic block for the function. Builder.SetInsertPoint(new BasicBlock("entry", Fn)); @@ -645,6 +649,10 @@ Builder.GetInsertBlock()); } + // Emit annotate intrinsic if arg has annotate attr + if (DECL_ATTRIBUTES(Args)) + EmitAnnotateIntrinsic(Tmp, Args); + Client.setName(Name); Client.setLocation(Tmp); ABIConverter.HandleArgument(TREE_TYPE(Args)); @@ -1392,6 +1400,52 @@ BranchFixups.push_back(BranchFixup(BI, isExceptionEdge)); } +// Emits annotate intrinsic if the decl has the annotate attribute set. +void TreeToLLVM::EmitAnnotateIntrinsic(Value *V, tree decl) { + + // Handle annotate attribute on global. + tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); + + if (!annotateAttr) + return; + + Function *annotateFun = Intrinsic::getDeclaration(TheModule, + Intrinsic::var_annotation); + + // There may be multiple annotate attributes. Pass return of lookup_attr + // to successive lookups. + while (annotateAttr) { + + // Each annotate attribute is a tree list. + // Get value of list which is our linked list of args. + tree args = TREE_VALUE(annotateAttr); + + // Each annotate attribute may have multiple args. + // Treat each arg as if it were a separate annotate attribute. + for (tree a = args; a; a = TREE_CHAIN(a)) { + // Each element of the arg list is a tree list, so get value + tree val = TREE_VALUE(a); + + // Assert its a string, and then get that string. + assert(TREE_CODE(val) == STRING_CST && + "Annotate attribute arg should always be a string"); + const Type *SBP = PointerType::get(Type::Int8Ty); + Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); + Value *Ops[2] = { + BitCastToType(V, SBP), + BitCastToType(strGV, SBP) + }; + + Builder.CreateCall(annotateFun, Ops, 2); + } + + // Get next annotate attribute. + annotateAttr = TREE_CHAIN(annotateAttr); + if (annotateAttr) + annotateAttr = lookup_attribute("annotate", annotateAttr); + } +} + //===----------------------------------------------------------------------===// // ... Basic Lists and Binding Scopes ... //===----------------------------------------------------------------------===// @@ -1493,9 +1547,13 @@ } AI->setAlignment(Alignment); - + SET_DECL_LLVM(decl, AI); + // Handle annotate attributes + if (DECL_ATTRIBUTES(decl)) + EmitAnnotateIntrinsic(AI, decl); + if (TheDebugInfo) { if (DECL_NAME(decl)) { TheDebugInfo->EmitDeclare(decl, llvm::dwarf::DW_TAG_auto_variable, Modified: apple-local/branches/llvm/gcc/llvm-internal.h =================================================================== --- apple-local/branches/llvm/gcc/llvm-internal.h 2007-06-15 20:34:18 UTC (rev 128470) +++ apple-local/branches/llvm/gcc/llvm-internal.h 2007-06-15 21:02:55 UTC (rev 128471) @@ -92,6 +92,10 @@ /// marked attribute(noinline) extern std::vector AttributeNoinlineFunctions; +/// AddAnnotateAttrsToGlobal - Adds decls that have a +/// annotate attribute to a vector to be emitted later. +extern void AddAnnotateAttrsToGlobal(GlobalValue *GV, union tree_node* decl); + void changeLLVMValue(Value *Old, Value *New); void readLLVMTypesStringTable(); void writeLLVMTypesStringTable(); @@ -444,6 +448,10 @@ static bool isNoopCast(Value *V, const Type *Ty); void HandleMultiplyDefinedGCCTemp(tree_node *var); + + /// EmitAnnotateIntrinsic - Emits call to annotate attr intrinsic + void EmitAnnotateIntrinsic(Value *V, tree_node *decl); + private: /// GatherTypeInfo - Walk through the expression gathering all the /// typeinfos that are used. From evan.cheng at apple.com Fri Jun 15 16:14:16 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 16:14:16 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200706152114.l5FLEGvO031164@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.129 -> 1.130 --- Log message: Added CanBeDuplicated(). It returns true if an instruction can be safely duplicated (e.g. during ifcvt). --- Diffs of the changes: (+7 -0) TargetInstrInfo.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.129 llvm/include/llvm/Target/TargetInstrInfo.h:1.130 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.129 Thu Jun 14 17:03:45 2007 +++ llvm/include/llvm/Target/TargetInstrInfo.h Fri Jun 15 16:13:54 2007 @@ -415,6 +415,13 @@ return false; } + /// CanBeDuplicated - Returns true if the instruction can be duplicated + /// without causing unforseenable side-effect (e.g. instructions with unique + /// labels attached). + virtual bool CanBeDuplicated(const MachineInstr *MI) const { + return false; + } + /// isUnpredicatedTerminator - Returns true if the instruction is a /// terminator instruction that has not been predicated. virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; From evan.cheng at apple.com Fri Jun 15 16:15:23 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 16:15:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp ARMInstrInfo.h Message-ID: <200706152115.l5FLFNXs031203@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMInstrInfo.cpp updated: 1.36 -> 1.37 ARMInstrInfo.h updated: 1.13 -> 1.14 --- Log message: Instructions with unique labels or embedded jumptables cannot be duplicated during ifcvt. --- Diffs of the changes: (+31 -0) ARMInstrInfo.cpp | 29 +++++++++++++++++++++++++++++ ARMInstrInfo.h | 2 ++ 2 files changed, 31 insertions(+) Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.37 --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 Wed Jun 13 12:59:52 2007 +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Fri Jun 15 16:15:00 2007 @@ -446,6 +446,35 @@ return PIdx != -1 && MI->getOperand(PIdx).getImmedValue() != ARMCC::AL; } +bool ARMInstrInfo::CanBeDuplicated(const MachineInstr *MI) const { + switch (MI->getOpcode()) { + default: return true; + // These have unique labels. + case ARM::PICADD: + case ARM::PICLD: + case ARM::PICLDZH: + case ARM::PICLDZB: + case ARM::PICLDH: + case ARM::PICLDB: + case ARM::PICLDSH: + case ARM::PICLDSB: + case ARM::PICSTR: + case ARM::PICSTRH: + case ARM::PICSTRB: + case ARM::LEApcrel: + case ARM::LEApcrelJT: + case ARM::tPICADD: + case ARM::tLEApcrel: + case ARM::tLEApcrelJT: + case ARM::CONSTPOOL_ENTRY: + // These embed jumptables. + case ARM::BR_JTr: + case ARM::BR_JTm: + case ARM::BR_JTadd: + return false; + } +} + bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI, const std::vector &Pred) const { unsigned Opc = MI->getOpcode(); Index: llvm/lib/Target/ARM/ARMInstrInfo.h diff -u llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 llvm/lib/Target/ARM/ARMInstrInfo.h:1.14 --- llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 Tue May 29 13:42:18 2007 +++ llvm/lib/Target/ARM/ARMInstrInfo.h Fri Jun 15 16:15:00 2007 @@ -106,6 +106,8 @@ // Predication support. virtual bool isPredicated(const MachineInstr *MI) const; + virtual bool CanBeDuplicated(const MachineInstr *MI) const; + virtual bool PredicateInstruction(MachineInstr *MI, const std::vector &Pred) const; From evan.cheng at apple.com Fri Jun 15 16:18:27 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 15 Jun 2007 16:18:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706152118.l5FLIRXq031275@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.53 -> 1.54 --- Log message: Not every predicable block can be safely duplicated. --- Diffs of the changes: (+35 -8) IfConversion.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 35 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.53 llvm/lib/CodeGen/IfConversion.cpp:1.54 --- llvm/lib/CodeGen/IfConversion.cpp:1.53 Fri Jun 15 14:06:07 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Fri Jun 15 16:18:05 2007 @@ -100,6 +100,7 @@ bool IsBrAnalyzable : 1; bool HasFallThrough : 1; bool IsUnpredicable : 1; + bool CannotBeCopied : 1; bool ClobbersPred : 1; unsigned NonPredSize; MachineBasicBlock *BB; @@ -111,7 +112,7 @@ BBInfo() : Kind(ICNotClassfied), IsDone(false), IsBeingAnalyzed(false), IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false), HasFallThrough(false), IsUnpredicable(false), - ClobbersPred(false), NonPredSize(0), + CannotBeCopied(false), ClobbersPred(false), NonPredSize(0), BB(0), TrueBB(0), FalseBB(0), TailBB(0) {} }; @@ -334,8 +335,9 @@ if (TrueBBI.IsBeingAnalyzed) return false; - if (TrueBBI.BB->pred_size() != 1) { - if (TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit()) + if (TrueBBI.BB->pred_size() > 1) { + if (TrueBBI.CannotBeCopied || + TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit()) return false; } @@ -349,7 +351,10 @@ if (TrueBBI.IsBeingAnalyzed) return false; - if (TrueBBI.BB->pred_size() != 1) { + if (TrueBBI.BB->pred_size() > 1) { + if (TrueBBI.CannotBeCopied) + return false; + unsigned Size = TrueBBI.NonPredSize; if (TrueBBI.FalseBB) ++Size; @@ -420,6 +425,9 @@ bool SeenCondBr = false; for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); I != E; ++I) { + if (!BBI.CannotBeCopied && !TII->CanBeDuplicated(I)) + BBI.CannotBeCopied = true; + const TargetInstrDescriptor *TID = I->getInstrDescriptor(); bool isPredicated = TII->isPredicated(I); bool isCondBr = BBI.IsBrAnalyzable && @@ -721,11 +729,20 @@ BBInfo *NextBBI = &FalseBBI; std::vector Cond(BBI.BrCond); - if (BBI.Kind == ICSimpleFalse) { + if (BBI.Kind == ICSimpleFalse) std::swap(CvtBBI, NextBBI); - TII->ReverseBranchCondition(Cond); + + if (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1) { + // Something has changed. It's no longer safe to predicate this block. + BBI.Kind = ICNotClassfied; + BBI.IsAnalyzed = false; + CvtBBI->IsAnalyzed = false; + return false; } + if (BBI.Kind == ICSimpleFalse) + TII->ReverseBranchCondition(Cond); + if (CvtBBI->BB->pred_size() > 1) { BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); // Copy instructions in the true block, predicate them add them to @@ -777,10 +794,20 @@ BBInfo *NextBBI = &FalseBBI; std::vector Cond(BBI.BrCond); - if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) { + if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) std::swap(CvtBBI, NextBBI); - TII->ReverseBranchCondition(Cond); + + if (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1) { + // Something has changed. It's no longer safe to predicate this block. + BBI.Kind = ICNotClassfied; + BBI.IsAnalyzed = false; + CvtBBI->IsAnalyzed = false; + return false; } + + if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) + TII->ReverseBranchCondition(Cond); + if (BBI.Kind == ICTriangleRev || BBI.Kind == ICTriangleFRev) { ReverseBranchCondition(*CvtBBI); // BB has been changed, modify its predecessors (except for this From clattner at apple.com Fri Jun 15 16:37:54 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 15 Jun 2007 14:37:54 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp ARMInstrInfo.h In-Reply-To: <200706152115.l5FLFNXs031203@zion.cs.uiuc.edu> References: <200706152115.l5FLFNXs031203@zion.cs.uiuc.edu> Message-ID: <38A4060B-D4C6-44E3-BC18-AB39C5738E58@apple.com> On Jun 15, 2007, at 2:15 PM, Evan Cheng wrote: > Instructions with unique labels or embedded jumptables cannot be > duplicated during ifcvt. Please turn this into a targetinstrinfo bit. Virtual methods should only be used for properties whose behavior is a property of the *operands* of the instruction in combination with the opcode. This property seems to only depend on the opcode. -Chris > --- > Diffs of the changes: (+31 -0) > > ARMInstrInfo.cpp | 29 +++++++++++++++++++++++++++++ > ARMInstrInfo.h | 2 ++ > 2 files changed, 31 insertions(+) > > > Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp > diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 llvm/lib/Target/ > ARM/ARMInstrInfo.cpp:1.37 > --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 Wed Jun 13 12:59:52 2007 > +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Fri Jun 15 16:15:00 2007 > @@ -446,6 +446,35 @@ > return PIdx != -1 && MI->getOperand(PIdx).getImmedValue() != > ARMCC::AL; > } > > +bool ARMInstrInfo::CanBeDuplicated(const MachineInstr *MI) const { > + switch (MI->getOpcode()) { > + default: return true; > + // These have unique labels. > + case ARM::PICADD: > + case ARM::PICLD: > + case ARM::PICLDZH: > + case ARM::PICLDZB: > + case ARM::PICLDH: > + case ARM::PICLDB: > + case ARM::PICLDSH: > + case ARM::PICLDSB: > + case ARM::PICSTR: > + case ARM::PICSTRH: > + case ARM::PICSTRB: > + case ARM::LEApcrel: > + case ARM::LEApcrelJT: > + case ARM::tPICADD: > + case ARM::tLEApcrel: > + case ARM::tLEApcrelJT: > + case ARM::CONSTPOOL_ENTRY: > + // These embed jumptables. > + case ARM::BR_JTr: > + case ARM::BR_JTm: > + case ARM::BR_JTadd: > + return false; > + } > +} > + > bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI, > const std::vector > &Pred) const { > unsigned Opc = MI->getOpcode(); > > > Index: llvm/lib/Target/ARM/ARMInstrInfo.h > diff -u llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 llvm/lib/Target/ARM/ > ARMInstrInfo.h:1.14 > --- llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 Tue May 29 13:42:18 2007 > +++ llvm/lib/Target/ARM/ARMInstrInfo.h Fri Jun 15 16:15:00 2007 > @@ -106,6 +106,8 @@ > // Predication support. > virtual bool isPredicated(const MachineInstr *MI) const; > > + virtual bool CanBeDuplicated(const MachineInstr *MI) const; > + > virtual > bool PredicateInstruction(MachineInstr *MI, > const std::vector > &Pred) const; > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From tonic at nondot.org Fri Jun 15 17:27:20 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 15 Jun 2007 17:27:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200706152227.l5FMRKWi000374@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.465 -> 1.466 --- Log message: Codegen support (stripped out) for the annotate attribute. --- Diffs of the changes: (+4 -0) SelectionDAGISel.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.465 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.466 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.465 Fri Jun 15 14:11:01 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jun 15 17:26:58 2007 @@ -2774,6 +2774,10 @@ case Intrinsic::prefetch: // FIXME: Currently discarding prefetches. return 0; + + case Intrinsic::var_annotation: + // Discard annotate attributes + return 0; } } From tonic at nondot.org Fri Jun 15 17:27:21 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 15 Jun 2007 17:27:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IntrinsicLowering.cpp Message-ID: <200706152227.l5FMRLtb000379@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IntrinsicLowering.cpp updated: 1.87 -> 1.88 --- Log message: Codegen support (stripped out) for the annotate attribute. --- Diffs of the changes: (+3 -0) IntrinsicLowering.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.87 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.88 --- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.87 Mon Jun 11 18:16:16 2007 +++ llvm/lib/CodeGen/IntrinsicLowering.cpp Fri Jun 15 17:26:58 2007 @@ -711,6 +711,9 @@ case Intrinsic::eh_filter: break; // Simply strip out debugging and eh intrinsics + case Intrinsic::var_annotation: + break; // Strip out annotate intrinsic + case Intrinsic::memcpy_i32: case Intrinsic::memcpy_i64: { static Constant *MemcpyFCache = 0; From resistor at mac.com Fri Jun 15 19:25:29 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 15 Jun 2007 19:25:29 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll Message-ID: <200706160025.l5G0PTs6002775@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/GVNPRE: 2007-06-15-InvokeInst.ll added (r1.1) --- Log message: Testcase where GVNPRE was getting confused by invoke instructions. --- Diffs of the changes: (+70 -0) 2007-06-15-InvokeInst.ll | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 70 insertions(+) Index: llvm/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll diff -c /dev/null llvm/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll:1.1 *** /dev/null Fri Jun 15 19:25:20 2007 --- llvm/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll Fri Jun 15 19:25:10 2007 *************** *** 0 **** --- 1,70 ---- + ; RUN: llvm-as < %s | opt -gvnpre | llvm-dis + + @.str1 = external constant [4 x i8] ; <[4 x i8]*> [#uses=1] + @.str2 = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] + + define i32 @main(i32 %argc, i8** %argv) { + entry: + br i1 false, label %cond_next, label %cond_true + + cond_true: ; preds = %entry + ret i32 0 + + cond_next: ; preds = %entry + %tmp10 = invoke i16 @_ZN12token_stream4openEPKc( i8* null, i8* null ) sext + to label %invcont unwind label %cleanup690 ; [#uses=0] + + invcont: ; preds = %cond_next + %tmp15 = invoke i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0) ) + to label %invcont14 unwind label %cleanup685 ; [#uses=0] + + invcont14: ; preds = %invcont + %tmp17 = invoke i8* @_ZN24lambda_expression_parser10expressionEPP11arglst_node( i8* null, i8** null ) + to label %cond_true22 unwind label %cleanup685 + + cond_true22: ; preds = %invcont14 + %tmp35 = invoke i32 null( i8* null ) + to label %cond_next56 unwind label %cleanup685 ; [#uses=0] + + cond_next56: ; preds = %cond_true22 + %tmp59 = invoke i32 (i8*, ...)* @printf( i8* getelementptr ([5 x i8]* @.str2, i32 0, i32 0) ) + to label %invcont58 unwind label %cleanup685 ; [#uses=0] + + invcont58: ; preds = %cond_next56 + invoke void null( i8* null, i8* null, i32 0 ) + to label %invcont72 unwind label %cleanup685 + + invcont72: ; preds = %invcont58 + %tmp143 = invoke i32 null( i8* null ) + to label %invcont142 unwind label %cleanup685 ; [#uses=0] + + invcont142: ; preds = %invcont72 + br i1 false, label %cond_false407, label %cond_true150 + + cond_true150: ; preds = %invcont142 + ret i32 0 + + cond_false407: ; preds = %invcont142 + %tmp431 = invoke i8* null( i8* null, i8* null, i32 0, i32* null ) + to label %bb432 unwind label %cleanup685 + + bb432: ; preds = %bb432, %cond_false407 + %rexp413.7 = phi i8* [ %tmp431, %cond_false407 ], [ %rexp413.7, %bb432 ] + %tmp434 = icmp eq i8* %rexp413.7, null ; [#uses=1] + br i1 %tmp434, label %bb432, label %cond_true437 + + cond_true437: ; preds = %bb432 + ret i32 0 + + cleanup685: ; preds = %cond_false407, %invcont72, %invcont58, %cond_next56, %cond_true22, %invcont14, %invcont + ret i32 0 + + cleanup690: ; preds = %cond_next + ret i32 0 + } + + declare i16 @_ZN12token_stream4openEPKc(i8*, i8*) sext + + declare i32 @printf(i8*, ...) + + declare i8* @_ZN24lambda_expression_parser10expressionEPP11arglst_node(i8*, i8**) From resistor at mac.com Fri Jun 15 19:27:16 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 15 Jun 2007 19:27:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706160027.l5G0RGIW002812@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.33 -> 1.34 --- Log message: Fix test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll by ignoring all instructions that depend on invokes. --- Diffs of the changes: (+36 -3) GVNPRE.cpp | 39 ++++++++++++++++++++++++++++++++++++--- 1 files changed, 36 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.33 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.34 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.33 Fri Jun 15 12:55:15 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Fri Jun 15 19:26:54 2007 @@ -285,6 +285,33 @@ } } +bool dependsOnInvoke(Value* V) { + if (!isa(V)) + return false; + + User* U = cast(V); + std::vector worklist(U->op_begin(), U->op_end()); + std::set visited; + + while (!worklist.empty()) { + Value* current = worklist.back(); + worklist.pop_back(); + visited.insert(current); + + if (!isa(current)) + continue; + else if (isa(current)) + return true; + + User* curr = cast(current); + for (unsigned i = 0; i < curr->getNumOperands(); ++i) + if (visited.find(curr->getOperand(i)) == visited.end()) + worklist.push_back(curr->getOperand(i)); + } + + return false; +} + // Remove all expressions whose operands are not themselves in the set void GVNPRE::clean(std::set& set) { std::vector worklist; @@ -302,6 +329,7 @@ lhsValid = true; break; } + lhsValid &= !dependsOnInvoke(BO->getOperand(0)); bool rhsValid = !isa(BO->getOperand(1)); if (!rhsValid) @@ -311,6 +339,7 @@ rhsValid = true; break; } + rhsValid &= !dependsOnInvoke(BO->getOperand(1)); if (!lhsValid || !rhsValid) set.erase(BO); @@ -323,7 +352,8 @@ lhsValid = true; break; } - + lhsValid &= !dependsOnInvoke(C->getOperand(0)); + bool rhsValid = !isa(C->getOperand(1)); if (!rhsValid) for (std::set::iterator I = set.begin(), E = set.end(); @@ -332,6 +362,7 @@ rhsValid = true; break; } + rhsValid &= !dependsOnInvoke(C->getOperand(1)); if (!lhsValid || !rhsValid) set.erase(C); @@ -800,13 +831,15 @@ User* U = cast(e2); Value* s1 = 0; - if (isa(U->getOperand(0))) + if (isa(U->getOperand(0)) || + isa(U->getOperand(0))) s1 = find_leader(availableOut[*PI], U->getOperand(0)); else s1 = U->getOperand(0); Value* s2 = 0; - if (isa(U->getOperand(1))) + if (isa(U->getOperand(1)) || + isa(U->getOperand(1))) s2 = find_leader(availableOut[*PI], U->getOperand(1)); else s2 = U->getOperand(1); From isanbard at gmail.com Sat Jun 16 01:17:54 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 16 Jun 2007 01:17:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200706160617.l5G6HsH0009379@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.409 -> 1.410 --- Log message: Fix a failure to bit_convert from integer GPR to MMX register. --- Diffs of the changes: (+2 -0) X86ISelLowering.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 llvm/lib/Target/X86/X86ISelLowering.cpp:1.410 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 Thu Jun 14 17:58:02 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Jun 16 01:17:31 2007 @@ -394,6 +394,8 @@ setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); + + setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); } if (Subtarget->hasSSE1()) { From isanbard at gmail.com Sat Jun 16 01:32:10 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 16 Jun 2007 01:32:10 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll Message-ID: <200706160632.l5G6WA8M009668@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: 2007-06-15-IntToMMX.ll added (r1.1) --- Log message: Testcase for MMX int to MMX register failure. --- Diffs of the changes: (+17 -0) 2007-06-15-IntToMMX.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll diff -c /dev/null llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll:1.1 *** /dev/null Sat Jun 16 01:31:57 2007 --- llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll Sat Jun 16 01:31:47 2007 *************** *** 0 **** --- 1,17 ---- + ; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+mmx | grep paddusw + @R = external global <1 x i64> ; <<1 x i64>*> [#uses=1] + + define void @foo(<1 x i64> %A, <1 x i64> %B) { + entry: + %tmp4 = bitcast <1 x i64> %B to <4 x i16> ; <<4 x i16>> [#uses=1] + %tmp6 = bitcast <1 x i64> %A to <4 x i16> ; <<4 x i16>> [#uses=1] + %tmp7 = tail call <4 x i16> @llvm.x86.mmx.paddus.w( <4 x i16> %tmp6, <4 x i16> %tmp4 ) ; <<4 x i16>> [#uses=1] + %tmp8 = bitcast <4 x i16> %tmp7 to <1 x i64> ; <<1 x i64>> [#uses=1] + store <1 x i64> %tmp8, <1 x i64>* @R + tail call void @llvm.x86.mmx.emms( ) + ret void + } + + declare <4 x i16> @llvm.x86.mmx.paddus.w(<4 x i16>, <4 x i16>) + + declare void @llvm.x86.mmx.emms() From baldrick at free.fr Sat Jun 16 02:50:15 2007 From: baldrick at free.fr (Duncan Sands) Date: Sat, 16 Jun 2007 09:50:15 +0200 Subject: [llvm-commits] [128471] Add annotate attribute. In-Reply-To: <20070615210255.7D2BA8D5A7B4@src> References: <20070615210255.7D2BA8D5A7B4@src> Message-ID: <200706160950.15377.baldrick@free.fr> Hi, > + // Add llvm.global.annotations > + if (!AttributeAnnotateGlobals.empty()) { > + std::vector AttrList; since you know how big this vector is going to be, you could reserve that much space here. > + for (unsigned i = 0, e = AttributeAnnotateGlobals.size(); i != e; ++i) { > + Constant *Elts[2] = {AttributeAnnotateGlobals[i].first, > + AttributeAnnotateGlobals[i].second }; > + AttrList.push_back(ConstantStruct::get(Elts, 2, false)); > + } You presumably could have done this at the point where values are added to AttributeAnnotateGlobals, eliminating the need for AttrList altogether. > + gv->setSection("llvm.metadata"); At this point you can presumably empty out AttributeAnnotateGlobals, freeing memory. > + if (!annotateAttr) > + return; No need for this return statement, since if annotateAttr is NULL then > + // There may be multiple annotate attributes. Pass return of lookup_attr > + // to successive lookups. > + while (annotateAttr) { this while loop is never executed. Ciao, Duncan. From evan.cheng at apple.com Sat Jun 16 04:35:14 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 16 Jun 2007 04:35:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IfConversion.cpp Message-ID: <200706160935.l5G9ZEWY022939@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IfConversion.cpp updated: 1.54 -> 1.55 --- Log message: Really turn if-converter loose: 1. Consider all possible ifcvt cases at once. No longer restricted to bottom up iterative approach. 2. Sort all possible cases based on a cost function. Perform the most profitable ones first invalidate others that target the same blocks. 3. Fixed a number of bugs related to block duplication. --- Diffs of the changes: (+210 -165) IfConversion.cpp | 375 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 210 insertions(+), 165 deletions(-) Index: llvm/lib/CodeGen/IfConversion.cpp diff -u llvm/lib/CodeGen/IfConversion.cpp:1.54 llvm/lib/CodeGen/IfConversion.cpp:1.55 --- llvm/lib/CodeGen/IfConversion.cpp:1.54 Fri Jun 15 16:18:05 2007 +++ llvm/lib/CodeGen/IfConversion.cpp Sat Jun 16 04:34:52 2007 @@ -58,14 +58,14 @@ namespace { class IfConverter : public MachineFunctionPass { - enum BBICKind { + enum IfcvtKind { ICNotClassfied, // BB data valid, but not classified. - ICSimple, // BB is entry of an one split, no rejoin sub-CFG. ICSimpleFalse, // Same as ICSimple, but on the false path. - ICTriangle, // BB is entry of a triangle sub-CFG. + ICSimple, // BB is entry of an one split, no rejoin sub-CFG. + ICTriangleFRev, // Same as ICTriangleFalse, but false path rev condition. ICTriangleRev, // Same as ICTriangle, but true path rev condition. ICTriangleFalse, // Same as ICTriangle, but on the false path. - ICTriangleFRev, // Same as ICTriangleFalse, but false path rev condition. + ICTriangle, // BB is entry of a triangle sub-CFG. ICDiamond // BB is entry of a diamond sub-CFG. }; @@ -76,7 +76,6 @@ /// diamond shape), its size, whether it's predicable, and whether any /// instruction can clobber the 'would-be' predicate. /// - /// Kind - Type of block. See BBICKind. /// IsDone - True if BB is not to be considered for ifcvt. /// IsBeingAnalyzed - True if BB is currently being analyzed. /// IsAnalyzed - True if BB has been analyzed (info is still valid). @@ -92,7 +91,6 @@ /// BrCond - Conditions for end of block conditional branches. /// Predicate - Predicate used in the BB. struct BBInfo { - BBICKind Kind; bool IsDone : 1; bool IsBeingAnalyzed : 1; bool IsAnalyzed : 1; @@ -106,14 +104,29 @@ MachineBasicBlock *BB; MachineBasicBlock *TrueBB; MachineBasicBlock *FalseBB; - MachineBasicBlock *TailBB; std::vector BrCond; std::vector Predicate; - BBInfo() : Kind(ICNotClassfied), IsDone(false), IsBeingAnalyzed(false), + BBInfo() : IsDone(false), IsBeingAnalyzed(false), IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false), HasFallThrough(false), IsUnpredicable(false), CannotBeCopied(false), ClobbersPred(false), NonPredSize(0), - BB(0), TrueBB(0), FalseBB(0), TailBB(0) {} + BB(0), TrueBB(0), FalseBB(0) {} + }; + + /// IfcvtToken - Record information about pending if-conversions to attemp: + /// BBI - Corresponding BBInfo. + /// Kind - Type of block. See IfcvtKind. + /// NeedSubsumsion - True if the to be predicated BB has already been + /// predicated. + /// Duplicates - Number of instructions that would be duplicated due + /// to this if-conversion. + struct IfcvtToken { + BBInfo &BBI; + IfcvtKind Kind; + bool NeedSubsumsion; + unsigned Duplicates; + IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d) + : BBI(b), Kind(k), NeedSubsumsion(s), Duplicates(d) {} }; /// Roots - Basic blocks that do not have successors. These are the starting @@ -136,22 +149,22 @@ private: bool ReverseBranchCondition(BBInfo &BBI); - bool ValidSimple(BBInfo &TrueBBI) const; + bool ValidSimple(BBInfo &TrueBBI, unsigned &Dups) const; bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, - bool FalseBranch = false) const; + bool FalseBranch, unsigned &Dups) const; bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI) const; void ScanInstructions(BBInfo &BBI); - BBInfo &AnalyzeBlock(MachineBasicBlock *BB); + BBInfo &AnalyzeBlock(MachineBasicBlock *BB, + std::vector &Tokens); bool FeasibilityAnalysis(BBInfo &BBI, std::vector &Cond, bool isTriangle = false, bool RevBranch = false); - bool AttemptRestructuring(BBInfo &BBI); bool AnalyzeBlocks(MachineFunction &MF, - std::vector &Candidates); + std::vector &Tokens); void ReTryPreds(MachineBasicBlock *BB); void RemoveExtraEdges(BBInfo &BBI); - bool IfConvertSimple(BBInfo &BBI); - bool IfConvertTriangle(BBInfo &BBI); - bool IfConvertDiamond(BBInfo &BBI); + bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind); + bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind); + bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind); void PredicateBlock(BBInfo &BBI, std::vector &Cond, bool IgnoreTerm = false); @@ -165,12 +178,26 @@ return BBI.IsBrAnalyzable && BBI.TrueBB == NULL; } - // IfcvtCandidateCmp - Used to sort if-conversion candidates. - static bool IfcvtCandidateCmp(BBInfo* C1, BBInfo* C2){ - // Favor diamond over triangle, etc. - return (unsigned)C1->Kind < (unsigned)C2->Kind; + // IfcvtTokenCmp - Used to sort if-conversion candidates. + static bool IfcvtTokenCmp(IfcvtToken *C1, IfcvtToken *C2) { + // Favors subsumsion. + if (C1->NeedSubsumsion == false && C2->NeedSubsumsion == true) + return true; + else if (C1->NeedSubsumsion == C2->NeedSubsumsion) { + if (C1->Duplicates > C2->Duplicates) + return true; + else if (C1->Duplicates == C2->Duplicates) { + // Favors diamond over triangle, etc. + if ((unsigned)C1->Kind < (unsigned)C2->Kind) + return true; + else if (C1->Kind == C2->Kind) + return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber(); + } + } + return false; } }; + char IfConverter::ID = 0; } @@ -199,37 +226,43 @@ if (I->succ_size() == 0) Roots.push_back(I); - std::vector Candidates; + std::vector Tokens; MadeChange = false; unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds; while (IfCvtLimit == -1 || (int)NumIfCvts < IfCvtLimit) { // Do an intial analysis for each basic block and finding all the potential // candidates to perform if-convesion. - bool Change = AnalyzeBlocks(MF, Candidates); - while (!Candidates.empty()) { - BBInfo &BBI = *Candidates.back(); - Candidates.pop_back(); + bool Change = AnalyzeBlocks(MF, Tokens); + while (!Tokens.empty()) { + IfcvtToken *Token = Tokens.back(); + Tokens.pop_back(); + BBInfo &BBI = Token->BBI; + IfcvtKind Kind = Token->Kind; // If the block has been evicted out of the queue or it has already been // marked dead (due to it being predicated), then skip it. - if (!BBI.IsEnqueued || BBI.IsDone) + if (BBI.IsDone) + BBI.IsEnqueued = false; + if (!BBI.IsEnqueued) continue; + BBI.IsEnqueued = false; bool RetVal = false; - switch (BBI.Kind) { + switch (Kind) { default: assert(false && "Unexpected!"); break; case ICSimple: case ICSimpleFalse: { - bool isFalse = BBI.Kind == ICSimpleFalse; + bool isFalse = Kind == ICSimpleFalse; if ((isFalse && DisableSimpleF) || (!isFalse && DisableSimple)) break; - DOUT << "Ifcvt (Simple" << (BBI.Kind == ICSimpleFalse ? " false" : "") + DOUT << "Ifcvt (Simple" << (Kind == ICSimpleFalse ? " false" :"") << "): BB#" << BBI.BB->getNumber() << " (" - << ((BBI.Kind == ICSimpleFalse) - ? BBI.FalseBB->getNumber() : BBI.TrueBB->getNumber()) << ") "; - RetVal = IfConvertSimple(BBI); + << ((Kind == ICSimpleFalse) + ? BBI.FalseBB->getNumber() + : BBI.TrueBB->getNumber()) << ") "; + RetVal = IfConvertSimple(BBI, Kind); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; if (RetVal) if (isFalse) NumSimpleFalse++; @@ -240,8 +273,8 @@ case ICTriangleRev: case ICTriangleFalse: case ICTriangleFRev: { - bool isFalse = BBI.Kind == ICTriangleFalse; - bool isRev = (BBI.Kind == ICTriangleRev || BBI.Kind == ICTriangleFRev); + bool isFalse = Kind == ICTriangleFalse; + bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev); if (DisableTriangle && !isFalse && !isRev) break; if (DisableTriangleR && !isFalse && isRev) break; if (DisableTriangleF && isFalse && !isRev) break; @@ -252,9 +285,9 @@ if (isRev) DOUT << " rev"; DOUT << "): BB#" << BBI.BB->getNumber() << " (T:" - << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber() - << ") "; - RetVal = IfConvertTriangle(BBI); + << BBI.TrueBB->getNumber() << ",F:" + << BBI.FalseBB->getNumber() << ") "; + RetVal = IfConvertTriangle(BBI, Kind); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; if (RetVal) { if (isFalse) { @@ -267,18 +300,18 @@ } break; } - case ICDiamond: + case ICDiamond: { if (DisableDiamond) break; DOUT << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:" - << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber(); - if (BBI.TailBB) - DOUT << "," << BBI.TailBB->getNumber() ; - DOUT << ") "; - RetVal = IfConvertDiamond(BBI); + << BBI.TrueBB->getNumber() << ",F:" + << BBI.FalseBB->getNumber() << ") "; + RetVal = IfConvertDiamond(BBI, Kind); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; if (RetVal) NumDiamonds++; break; } + } + Change |= RetVal; NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev + @@ -292,12 +325,22 @@ MadeChange |= Change; } + // Delete tokens in case of early exit. + while (!Tokens.empty()) { + IfcvtToken *Token = Tokens.back(); + Tokens.pop_back(); + delete Token; + } + + Tokens.clear(); Roots.clear(); BBAnalysis.clear(); return MadeChange; } +/// findFalseBlock - BB has a fallthrough. Find its 'false' successor given +/// its 'true' successor. static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB) { for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), @@ -309,6 +352,8 @@ return NULL; } +/// ReverseBranchCondition - Reverse the condition of the end of the block +/// branchs. Swap block's 'true' and 'false' successors. bool IfConverter::ReverseBranchCondition(BBInfo &BBI) { if (!TII->ReverseBranchCondition(BBI.BrCond)) { TII->RemoveBranch(*BBI.BB); @@ -330,8 +375,11 @@ } /// ValidSimple - Returns true if the 'true' block (along with its -/// predecessor) forms a valid simple shape for ifcvt. -bool IfConverter::ValidSimple(BBInfo &TrueBBI) const { +/// predecessor) forms a valid simple shape for ifcvt. It also returns the +/// number of instructions that the ifcvt would need to duplicate if performed +/// in Dups. +bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups) const { + Dups = 0; if (TrueBBI.IsBeingAnalyzed) return false; @@ -339,6 +387,7 @@ if (TrueBBI.CannotBeCopied || TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit()) return false; + Dups = TrueBBI.NonPredSize; } return !blockAlwaysFallThrough(TrueBBI) && TrueBBI.BrCond.size() == 0; @@ -346,8 +395,13 @@ /// ValidTriangle - Returns true if the 'true' and 'false' blocks (along /// with their common predecessor) forms a valid triangle shape for ifcvt. +/// If 'FalseBranch' is true, it checks if 'true' block's false branch +/// branches to the false branch rather than the other way around. It also +/// returns the number of instructions that the ifcvt would need to duplicate +/// if performed in 'Dups'. bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, - bool FalseBranch) const { + bool FalseBranch, unsigned &Dups) const { + Dups = 0; if (TrueBBI.IsBeingAnalyzed) return false; @@ -356,10 +410,21 @@ return false; unsigned Size = TrueBBI.NonPredSize; - if (TrueBBI.FalseBB) - ++Size; + if (TrueBBI.IsBrAnalyzable) { + if (TrueBBI.TrueBB && TrueBBI.BrCond.size() == 0) + // End with an unconditional branch. It will be removed. + --Size; + else { + MachineBasicBlock *FExit = FalseBranch + ? TrueBBI.TrueBB : TrueBBI.FalseBB; + if (FExit) + // Require a conditional branch + ++Size; + } + } if (Size > TLI->getIfCvtDupBlockSizeLimit()) return false; + Dups = Size; } MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB; @@ -467,13 +532,8 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, std::vector &Pred, bool isTriangle, bool RevBranch) { - // Forget about it if it's unpredicable. - if (BBI.IsUnpredicable) - return false; - - // If the block is dead, or it is going to be the entry block of a sub-CFG - // that will be if-converted, then it cannot be predicated. - if (BBI.IsDone || BBI.IsEnqueued) + // If the block is dead or unpredicable, then it cannot be predicated. + if (BBI.IsDone || BBI.IsUnpredicable) return false; // Check predication threshold. @@ -507,7 +567,8 @@ /// AnalyzeBlock - Analyze the structure of the sub-CFG starting from /// the specified block. Record its successors and whether it looks like an /// if-conversion candidate. -IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB) { +IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, + std::vector &Tokens) { BBInfo &BBI = BBAnalysis[BB->getNumber()]; if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) @@ -515,7 +576,6 @@ BBI.BB = BB; BBI.IsBeingAnalyzed = true; - BBI.Kind = ICNotClassfied; ScanInstructions(BBI); @@ -533,8 +593,8 @@ return BBI; } - BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB); - BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB); + BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens); + BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens); if (TrueBBI.IsDone && FalseBBI.IsDone) { BBI.IsBeingAnalyzed = false; @@ -545,6 +605,10 @@ std::vector RevCond(BBI.BrCond); bool CanRevCond = !TII->ReverseBranchCondition(RevCond); + unsigned Dups = 0; + bool TNeedSub = TrueBBI.Predicate.size() > 0; + bool FNeedSub = FalseBBI.Predicate.size() > 0; + bool Enqueued = false; if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI) && !(TrueBBI.ClobbersPred && FalseBBI.ClobbersPred) && FeasibilityAnalysis(TrueBBI, BBI.BrCond) && @@ -557,112 +621,86 @@ // \ / // TailBB // Note TailBB can be empty. - BBI.Kind = ICDiamond; - BBI.TailBB = TrueBBI.TrueBB; - } else { - // FIXME: Consider duplicating if BB is small. - if (ValidTriangle(TrueBBI, FalseBBI) && - FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) { - // Triangle: - // EBB - // | \_ - // | | - // | TBB - // | / - // FBB - BBI.Kind = ICTriangle; - } else if (ValidTriangle(TrueBBI, FalseBBI, true) && - FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) { - BBI.Kind = ICTriangleRev; - } else if (ValidSimple(TrueBBI) && - FeasibilityAnalysis(TrueBBI, BBI.BrCond)) { - // Simple (split, no rejoin): - // EBB - // | \_ - // | | - // | TBB---> exit - // | - // FBB - BBI.Kind = ICSimple; - } else if (CanRevCond) { - // Try the other path... - if (ValidTriangle(FalseBBI, TrueBBI) && - FeasibilityAnalysis(FalseBBI, RevCond, true)) { - BBI.Kind = ICTriangleFalse; - } else if (ValidTriangle(FalseBBI, TrueBBI, true) && - FeasibilityAnalysis(FalseBBI, RevCond, true, true)) { - BBI.Kind = ICTriangleFRev; - } else if (ValidSimple(FalseBBI) && - FeasibilityAnalysis(FalseBBI, RevCond)) { - BBI.Kind = ICSimpleFalse; - } + Tokens.push_back(new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups)); + Enqueued = true; + } + + if (ValidTriangle(TrueBBI, FalseBBI, false, Dups) && + FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) { + // Triangle: + // EBB + // | \_ + // | | + // | TBB + // | / + // FBB + Tokens.push_back(new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups)); + Enqueued = true; + } + + if (ValidTriangle(TrueBBI, FalseBBI, true, Dups) && + FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) { + Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups)); + Enqueued = true; + } + + if (ValidSimple(TrueBBI, Dups) && + FeasibilityAnalysis(TrueBBI, BBI.BrCond)) { + // Simple (split, no rejoin): + // EBB + // | \_ + // | | + // | TBB---> exit + // | + // FBB + Tokens.push_back(new IfcvtToken(BBI, ICSimple, TNeedSub, Dups)); + Enqueued = true; + } + + if (CanRevCond) { + // Try the other path... + if (ValidTriangle(FalseBBI, TrueBBI, false, Dups) && + FeasibilityAnalysis(FalseBBI, RevCond, true)) { + Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups)); + Enqueued = true; + } + + if (ValidTriangle(FalseBBI, TrueBBI, true, Dups) && + FeasibilityAnalysis(FalseBBI, RevCond, true, true)) { + Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups)); + Enqueued = true; + } + + if (ValidSimple(FalseBBI, Dups) && + FeasibilityAnalysis(FalseBBI, RevCond)) { + Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups)); + Enqueued = true; } } + BBI.IsEnqueued = Enqueued; BBI.IsBeingAnalyzed = false; BBI.IsAnalyzed = true; return BBI; } -/// AttemptRestructuring - Restructure the sub-CFG rooted in the given block to -/// expose more if-conversion opportunities. e.g. -/// -/// cmp -/// b le BB1 -/// / \____ -/// / | -/// cmp | -/// b eq BB1 | -/// / \____ | -/// / \ | -/// BB1 -/// ==> -/// -/// cmp -/// b eq BB1 -/// / \____ -/// / | -/// cmp | -/// b le BB1 | -/// / \____ | -/// / \ | -/// BB1 -bool IfConverter::AttemptRestructuring(BBInfo &BBI) { - return false; -} - /// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion /// candidates. It returns true if any CFG restructuring is done to expose more /// if-conversion opportunities. bool IfConverter::AnalyzeBlocks(MachineFunction &MF, - std::vector &Candidates) { + std::vector &Tokens) { bool Change = false; std::set Visited; for (unsigned i = 0, e = Roots.size(); i != e; ++i) { for (idf_ext_iterator I=idf_ext_begin(Roots[i],Visited), E = idf_ext_end(Roots[i], Visited); I != E; ++I) { MachineBasicBlock *BB = *I; - BBInfo &BBI = AnalyzeBlock(BB); - switch (BBI.Kind) { - case ICSimple: - case ICSimpleFalse: - case ICTriangle: - case ICTriangleRev: - case ICTriangleFalse: - case ICTriangleFRev: - case ICDiamond: - BBI.IsEnqueued = true; - Candidates.push_back(&BBI); - break; - default: - Change |= AttemptRestructuring(BBI); - break; - } + AnalyzeBlock(BB, Tokens); } } // Sort to favor more complex ifcvt scheme. - std::stable_sort(Candidates.begin(), Candidates.end(), IfcvtCandidateCmp); + std::stable_sort(Tokens.begin(), Tokens.end(), IfcvtTokenCmp); return Change; } @@ -689,7 +727,6 @@ BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()]; if (PBBI.IsDone || PBBI.BB == BB) continue; - PBBI.Kind = ICNotClassfied; PBBI.IsAnalyzed = false; PBBI.IsEnqueued = false; } @@ -722,25 +759,24 @@ /// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG. /// -bool IfConverter::IfConvertSimple(BBInfo &BBI) { +bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) { BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; BBInfo *CvtBBI = &TrueBBI; BBInfo *NextBBI = &FalseBBI; std::vector Cond(BBI.BrCond); - if (BBI.Kind == ICSimpleFalse) + if (Kind == ICSimpleFalse) std::swap(CvtBBI, NextBBI); if (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1) { // Something has changed. It's no longer safe to predicate this block. - BBI.Kind = ICNotClassfied; BBI.IsAnalyzed = false; CvtBBI->IsAnalyzed = false; return false; } - if (BBI.Kind == ICSimpleFalse) + if (Kind == ICSimpleFalse) TII->ReverseBranchCondition(Cond); if (CvtBBI->BB->pred_size() > 1) { @@ -787,28 +823,27 @@ /// IfConvertTriangle - If convert a triangle sub-CFG. /// -bool IfConverter::IfConvertTriangle(BBInfo &BBI) { +bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; BBInfo *CvtBBI = &TrueBBI; BBInfo *NextBBI = &FalseBBI; std::vector Cond(BBI.BrCond); - if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) + if (Kind == ICTriangleFalse || Kind == ICTriangleFRev) std::swap(CvtBBI, NextBBI); if (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1) { // Something has changed. It's no longer safe to predicate this block. - BBI.Kind = ICNotClassfied; BBI.IsAnalyzed = false; CvtBBI->IsAnalyzed = false; return false; } - if (BBI.Kind == ICTriangleFalse || BBI.Kind == ICTriangleFRev) + if (Kind == ICTriangleFalse || Kind == ICTriangleFRev) TII->ReverseBranchCondition(Cond); - if (BBI.Kind == ICTriangleRev || BBI.Kind == ICTriangleFRev) { + if (Kind == ICTriangleRev || Kind == ICTriangleFRev) { ReverseBranchCondition(*CvtBBI); // BB has been changed, modify its predecessors (except for this // one) so they don't get ifcvt'ed based on bad intel. @@ -819,7 +854,6 @@ continue; BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; if (PBBI.IsEnqueued) { - PBBI.Kind = ICNotClassfied; PBBI.IsAnalyzed = false; PBBI.IsEnqueued = false; } @@ -895,12 +929,13 @@ /// IfConvertDiamond - If convert a diamond sub-CFG. /// -bool IfConverter::IfConvertDiamond(BBInfo &BBI) { +bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind) { BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; + MachineBasicBlock *TailBB = TrueBBI.TrueBB; SmallVector Dups; - if (!BBI.TailBB) { + if (!TailBB) { // No common merge block. Check if the terminators (e.g. return) are // the same or predicable. MachineBasicBlock::iterator TT = BBI.TrueBB->getFirstTerminator(); @@ -947,12 +982,22 @@ // Check the 'true' and 'false' blocks if either isn't ended with a branch. // Either the block fallthrough to another block or it ends with a // return. If it's the former, add a branch to its successor. - bool NeedBr1 = !BBI1->TrueBB && BBI1->BB->succ_size(); - bool NeedBr2 = !BBI2->TrueBB && BBI2->BB->succ_size(); + bool NeedBr1 = !BBI1->TrueBB && BBI1->BB->succ_size() > 0; + bool NeedBr2 = !BBI2->TrueBB && BBI2->BB->succ_size() > 0; - if ((TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred) || - (!TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred && - NeedBr1 && !NeedBr2)) { + // Figure out the more profitable ordering. + bool DoSwap = false; + if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred) + DoSwap = true; + else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) { + if (!NeedBr1 && NeedBr2) + DoSwap = true; + else if (NeedBr1 == NeedBr2) { + if (TrueBBI.NonPredSize > FalseBBI.NonPredSize) + DoSwap = true; + } + } + if (DoSwap) { std::swap(BBI1, BBI2); std::swap(Cond1, Cond2); std::swap(NeedBr1, NeedBr2); @@ -1001,10 +1046,10 @@ // tail block, and the tail block does not have other predecessors, then // fold the tail block in as well. BBInfo *CvtBBI = NeedBr1 ? BBI2 : &BBI; - if (BBI.TailBB && - BBI.TailBB->pred_size() == 1 && CvtBBI->BB->succ_size() == 1) { + if (TailBB && + TailBB->pred_size() == 1 && CvtBBI->BB->succ_size() == 1) { CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); - BBInfo TailBBI = BBAnalysis[BBI.TailBB->getNumber()]; + BBInfo TailBBI = BBAnalysis[TailBB->getNumber()]; MergeBlocks(*CvtBBI, TailBBI); TailBBI.IsDone = true; } From nicholas at mxc.ca Sat Jun 16 11:17:57 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 16 Jun 2007 11:17:57 -0500 Subject: [llvm-commits] CVS: llvm/test/Other/2007-06-16-Funcname.ll Message-ID: <200706161617.l5GGHvcX031585@zion.cs.uiuc.edu> Changes in directory llvm/test/Other: 2007-06-16-Funcname.ll added (r1.1) --- Log message: Call the correct function name. Patch from Stephane Letz. --- Diffs of the changes: (+7 -0) 2007-06-16-Funcname.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Other/2007-06-16-Funcname.ll diff -c /dev/null llvm/test/Other/2007-06-16-Funcname.ll:1.1 *** /dev/null Sat Jun 16 11:17:45 2007 --- llvm/test/Other/2007-06-16-Funcname.ll Sat Jun 16 11:17:35 2007 *************** *** 0 **** --- 1,7 ---- + ; RUN: llvm-as < %s | llvm2cpp -funcname=WAKKA | not grep makeLLVMModule + ; PR1515 + + define void @foo() { + ret void + } + From nicholas at mxc.ca Sat Jun 16 11:17:57 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 16 Jun 2007 11:17:57 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm2cpp/CppWriter.cpp Message-ID: <200706161617.l5GGHvaP031590@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm2cpp: CppWriter.cpp updated: 1.49 -> 1.50 --- Log message: Call the correct function name. Patch from Stephane Letz. --- Diffs of the changes: (+1 -1) CppWriter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm2cpp/CppWriter.cpp diff -u llvm/tools/llvm2cpp/CppWriter.cpp:1.49 llvm/tools/llvm2cpp/CppWriter.cpp:1.50 --- llvm/tools/llvm2cpp/CppWriter.cpp:1.49 Tue Jun 5 00:28:26 2007 +++ llvm/tools/llvm2cpp/CppWriter.cpp Sat Jun 16 11:17:35 2007 @@ -1690,7 +1690,7 @@ Out << "using namespace llvm;\n\n"; Out << "Module* " << fname << "();\n\n"; Out << "int main(int argc, char**argv) {\n"; - Out << " Module* Mod = makeLLVMModule();\n"; + Out << " Module* Mod = " << fname << "();\n"; Out << " verifyModule(*Mod, PrintMessageAction);\n"; Out << " std::cerr.flush();\n"; Out << " std::cout.flush();\n"; From clattner at apple.com Sat Jun 16 14:35:38 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 16 Jun 2007 12:35:38 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp In-Reply-To: <200706160617.l5G6HsH0009379@zion.cs.uiuc.edu> References: <200706160617.l5G6HsH0009379@zion.cs.uiuc.edu> Message-ID: On Jun 15, 2007, at 11:17 PM, Bill Wendling wrote: > Fix a failure to bit_convert from integer GPR to MMX register. Bill, this causes a regression on this testcase: define double @test2(i64 %A) { %B = bitcast i64 %A to double ret double %B } $ llvm-as < t.ll | llc -march=x86-64 before: .align 4 .globl _test2 _test2: movd %rdi, %xmm0 ret after: _test2: subq $8, %rsp movq %rdi, (%rsp) movsd (%rsp), %xmm0 addq $8, %rsp ret Please fix or revert your patch until you can, -Chris > > --- > Diffs of the changes: (+2 -0) > > X86ISelLowering.cpp | 2 ++ > 1 files changed, 2 insertions(+) > > > Index: llvm/lib/Target/X86/X86ISelLowering.cpp > diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 llvm/lib/ > Target/X86/X86ISelLowering.cpp:1.410 > --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 Thu Jun 14 > 17:58:02 2007 > +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Jun 16 01:17:31 2007 > @@ -394,6 +394,8 @@ > setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); > setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); > setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); > + > + setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); > } > > if (Subtarget->hasSSE1()) { > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From reid at x10sys.com Sat Jun 16 15:33:47 2007 From: reid at x10sys.com (Reid Spencer) Date: Sat, 16 Jun 2007 15:33:47 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm2cpp/CppWriter.cpp Message-ID: <200706162033.l5GKXleh004356@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm2cpp: CppWriter.cpp updated: 1.50 -> 1.51 --- Log message: Fix PR1516: http://llvm.org/PR1516 : When printing the uses of a function (-gen-function only), make sure to include the constants referenced by intializers of global variables. --- Diffs of the changes: (+7 -2) CppWriter.cpp | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/tools/llvm2cpp/CppWriter.cpp diff -u llvm/tools/llvm2cpp/CppWriter.cpp:1.50 llvm/tools/llvm2cpp/CppWriter.cpp:1.51 --- llvm/tools/llvm2cpp/CppWriter.cpp:1.50 Sat Jun 16 11:17:35 2007 +++ llvm/tools/llvm2cpp/CppWriter.cpp Sat Jun 16 15:33:24 2007 @@ -1435,9 +1435,14 @@ for (unsigned i = 0; i < I->getNumOperands(); ++i) { Value* operand = I->getOperand(i); printType(operand->getType()); - if (GlobalValue* GV = dyn_cast(operand)) + + // If the operand references a GVal or Constant, make a note of it + if (GlobalValue* GV = dyn_cast(operand)) { gvs.push_back(GV); - else if (Constant* C = dyn_cast(operand)) + if (GlobalVariable *GVar = dyn_cast(GV)) + if (GVar->hasInitializer()) + consts.push_back(GVar->getInitializer()); + } else if (Constant* C = dyn_cast(operand)) consts.push_back(C); } } From reid at x10sys.com Sat Jun 16 15:48:49 2007 From: reid at x10sys.com (Reid Spencer) Date: Sat, 16 Jun 2007 15:48:49 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm2cpp/CppWriter.cpp Message-ID: <200706162048.l5GKmn3O004729@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm2cpp: CppWriter.cpp updated: 1.51 -> 1.52 --- Log message: Fix PR1517: http://llvm.org/PR1517 : Use SmallPtrSet instead of std::vector to eliminate duplicate uses in a function generated with -gen-function. This prevents the output from having multiple duplicate declarations of constants and gvals. --- Diffs of the changes: (+10 -9) CppWriter.cpp | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-) Index: llvm/tools/llvm2cpp/CppWriter.cpp diff -u llvm/tools/llvm2cpp/CppWriter.cpp:1.51 llvm/tools/llvm2cpp/CppWriter.cpp:1.52 --- llvm/tools/llvm2cpp/CppWriter.cpp:1.51 Sat Jun 16 15:33:24 2007 +++ llvm/tools/llvm2cpp/CppWriter.cpp Sat Jun 16 15:48:27 2007 @@ -23,6 +23,7 @@ #include "llvm/TypeSymbolTable.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/CFG.h" #include "llvm/Support/ManagedStatic.h" @@ -1423,8 +1424,8 @@ // Print type definitions for every type referenced by an instruction and // make a note of any global values or constants that are referenced - std::vector gvs; - std::vector consts; + SmallPtrSet gvs; + SmallPtrSet consts; for (Function::const_iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB){ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { @@ -1438,19 +1439,19 @@ // If the operand references a GVal or Constant, make a note of it if (GlobalValue* GV = dyn_cast(operand)) { - gvs.push_back(GV); + gvs.insert(GV); if (GlobalVariable *GVar = dyn_cast(GV)) if (GVar->hasInitializer()) - consts.push_back(GVar->getInitializer()); + consts.insert(GVar->getInitializer()); } else if (Constant* C = dyn_cast(operand)) - consts.push_back(C); + consts.insert(C); } } } // Print the function declarations for any functions encountered nl(Out) << "// Function Declarations"; nl(Out); - for (std::vector::iterator I = gvs.begin(), E = gvs.end(); + for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); I != E; ++I) { if (Function* Fun = dyn_cast(*I)) { if (!is_inline || Fun != F) @@ -1460,7 +1461,7 @@ // Print the global variable declarations for any variables encountered nl(Out) << "// Global Variable Declarations"; nl(Out); - for (std::vector::iterator I = gvs.begin(), E = gvs.end(); + for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); I != E; ++I) { if (GlobalVariable* F = dyn_cast(*I)) printVariableHead(F); @@ -1468,7 +1469,7 @@ // Print the constants found nl(Out) << "// Constant Definitions"; nl(Out); - for (std::vector::iterator I = consts.begin(), E = consts.end(); + for (SmallPtrSet::iterator I = consts.begin(), E = consts.end(); I != E; ++I) { printConstant(*I); } @@ -1477,7 +1478,7 @@ // been emitted. These definitions just couple the gvars with their constant // initializers. nl(Out) << "// Global Variable Definitions"; nl(Out); - for (std::vector::iterator I = gvs.begin(), E = gvs.end(); + for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); I != E; ++I) { if (GlobalVariable* GV = dyn_cast(*I)) printVariableBody(GV); From isanbard at gmail.com Sat Jun 16 18:57:38 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 16 Jun 2007 18:57:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200706162357.l5GNvcBB008407@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.410 -> 1.411 --- Log message: Revert patch. It regresses: define double @test2(i64 %A) { %B = bitcast i64 %A to double ret double %B } $ llvm-as < t.ll | llc -march=x86-64 before: .align 4 .globl _test2 _test2: movd %rdi, %xmm0 ret after: _test2: subq $8, %rsp movq %rdi, (%rsp) movsd (%rsp), %xmm0 addq $8, %rsp ret --- Diffs of the changes: (+0 -2) X86ISelLowering.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.410 llvm/lib/Target/X86/X86ISelLowering.cpp:1.411 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.410 Sat Jun 16 01:17:31 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Jun 16 18:57:15 2007 @@ -394,8 +394,6 @@ setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); - - setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); } if (Subtarget->hasSSE1()) { From isanbard at gmail.com Sat Jun 16 18:58:14 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 16 Jun 2007 18:58:14 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll Message-ID: <200706162358.l5GNwEYf008426@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: 2007-06-15-IntToMMX.ll updated: 1.1 -> 1.2 --- Log message: XFAILing until I can fix properly. --- Diffs of the changes: (+1 -0) 2007-06-15-IntToMMX.ll | 1 + 1 files changed, 1 insertion(+) Index: llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll diff -u llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll:1.1 llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll:1.2 --- llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll:1.1 Sat Jun 16 01:31:47 2007 +++ llvm/test/CodeGen/X86/2007-06-15-IntToMMX.ll Sat Jun 16 18:57:51 2007 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+mmx | grep paddusw +; XFAIL: * @R = external global <1 x i64> ; <<1 x i64>*> [#uses=1] define void @foo(<1 x i64> %A, <1 x i64> %B) { From isanbard at gmail.com Sat Jun 16 18:58:17 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 16 Jun 2007 16:58:17 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp In-Reply-To: References: <200706160617.l5G6HsH0009379@zion.cs.uiuc.edu> Message-ID: <60812AB2-2306-4B4C-BC2E-36F44717AFC2@gmail.com> Doh! Reverting. Sorry about that. -bw On Jun 16, 2007, at 12:35 PM, Chris Lattner wrote: > On Jun 15, 2007, at 11:17 PM, Bill Wendling wrote: >> Fix a failure to bit_convert from integer GPR to MMX register. > > Bill, this causes a regression on this testcase: > > define double @test2(i64 %A) { > %B = bitcast i64 %A to double > ret double %B > } > > $ llvm-as < t.ll | llc -march=x86-64 > > before: > > .align 4 > .globl _test2 > _test2: > movd %rdi, %xmm0 > ret > > after: > > _test2: > subq $8, %rsp > movq %rdi, (%rsp) > movsd (%rsp), %xmm0 > addq $8, %rsp > ret > > Please fix or revert your patch until you can, > > -Chris > >> >> --- >> Diffs of the changes: (+2 -0) >> >> X86ISelLowering.cpp | 2 ++ >> 1 files changed, 2 insertions(+) >> >> >> Index: llvm/lib/Target/X86/X86ISelLowering.cpp >> diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 llvm/lib/ >> Target/X86/X86ISelLowering.cpp:1.410 >> --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.409 Thu Jun 14 >> 17:58:02 2007 >> +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Jun 16 01:17:31 2007 >> @@ -394,6 +394,8 @@ >> setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); >> setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); >> setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); >> + >> + setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); >> } >> >> if (Subtarget->hasSSE1()) { >> >> >> >> _______________________________________________ >> 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 christopher.lamb at gmail.com Sat Jun 16 23:14:20 2007 From: christopher.lamb at gmail.com (Christopher Lamb) Date: Sat, 16 Jun 2007 21:14:20 -0700 Subject: [llvm-commits] PR1350 patch 2 Message-ID: <94B68D43-2996-43F8-9653-8232AAB1D68C@gmail.com> This actually adds some new SDNodes, and I want to make sure I've done it right. After this patch the SDNodes are there, but ScheduleDAG will assert out if they're used. No dg regressions that I can tell from this patch (the nodes shouldn't get created unless a backed does so explicitly). Give me the thumbs up and I'll commit it. -- Christopher Lamb ? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/f77499da/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: PR1350_2.patch Type: application/octet-stream Size: 4847 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/f77499da/attachment.obj -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/f77499da/attachment-0001.html From christopher.lamb at gmail.com Sat Jun 16 23:27:37 2007 From: christopher.lamb at gmail.com (Christopher Lamb) Date: Sat, 16 Jun 2007 21:27:37 -0700 Subject: [llvm-commits] PR1350 patch 2 In-Reply-To: <94B68D43-2996-43F8-9653-8232AAB1D68C@gmail.com> References: <94B68D43-2996-43F8-9653-8232AAB1D68C@gmail.com> Message-ID: <3A7EF81A-35AC-42E8-A0CC-305A8169C132@gmail.com> Whoops! Omitted a hunk. On Jun 16, 2007, at 9:14 PM, Christopher Lamb wrote: > This actually adds some new SDNodes, and I want to make sure I've > done it right. After this patch the SDNodes are there, but > ScheduleDAG will assert out if they're used. No dg regressions that > I can tell from this patch (the nodes shouldn't get created unless > a backed does so explicitly). Give me the thumbs up and I'll commit > it. -- Christopher Lamb -------------- next part -------------- A non-text attachment was scrubbed... Name: PR1350_2.patch Type: application/octet-stream Size: 7198 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/e6d86f3d/attachment.obj -------------- next part -------------- From clamb at ageia.com Sat Jun 16 23:25:52 2007 From: clamb at ageia.com (Christopher Lamb) Date: Sat, 16 Jun 2007 21:25:52 -0700 Subject: [llvm-commits] PR1350 patch 2 In-Reply-To: <94B68D43-2996-43F8-9653-8232AAB1D68C@gmail.com> References: <94B68D43-2996-43F8-9653-8232AAB1D68C@gmail.com> Message-ID: Whoops! Omitted a hunk. On Jun 16, 2007, at 9:14 PM, Christopher Lamb wrote: > This actually adds some new SDNodes, and I want to make sure I've > done it right. After this patch the SDNodes are there, but > ScheduleDAG will assert out if they're used. No dg regressions that > I can tell from this patch (the nodes shouldn't get created unless > a backed does so explicitly). Give me the thumbs up and I'll commit > it. > > -- > Christopher Lamb > ? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/40c9e583/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: PR1350_2.patch Type: application/octet-stream Size: 7198 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/40c9e583/attachment.obj -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070616/40c9e583/attachment-0001.html From sabre at nondot.org Sun Jun 17 18:30:23 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 17 Jun 2007 18:30:23 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/bitcast2.ll Message-ID: <200706172330.l5HNUNBx027493@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: bitcast2.ll added (r1.1) --- Log message: ensure we don't regress on these tests. We generate aweful code in x86-32 for these though. --- Diffs of the changes: (+13 -0) bitcast2.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/CodeGen/X86/bitcast2.ll diff -c /dev/null llvm/test/CodeGen/X86/bitcast2.ll:1.1 *** /dev/null Sun Jun 17 18:30:07 2007 --- llvm/test/CodeGen/X86/bitcast2.ll Sun Jun 17 18:29:57 2007 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | llc -march=x86-64 | grep movd | wc -l | grep 2 + ; RUN: llvm-as < %s | llc -march=x86-64 | not grep rsp + + define i64 @test1(double %A) { + %B = bitcast double %A to i64 + ret i64 %B + } + + define double @test2(i64 %A) { + %B = bitcast i64 %A to double + ret double %B + } + From clattner at apple.com Sun Jun 17 18:31:10 2007 From: clattner at apple.com (Chris Lattner) Date: Sun, 17 Jun 2007 16:31:10 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp In-Reply-To: <200706162357.l5GNvcBB008407@zion.cs.uiuc.edu> References: <200706162357.l5GNvcBB008407@zion.cs.uiuc.edu> Message-ID: On Jun 16, 2007, at 4:57 PM, Bill Wendling wrote: > Revert patch. It regresses: > > define double @test2(i64 %A) { > %B = bitcast i64 %A to double > ret double %B > } Thanks Bill, -Chris From evan.cheng at apple.com Sun Jun 17 19:06:47 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 17 Jun 2007 17:06:47 -0700 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp VirtRegMap.cpp In-Reply-To: <200706142051.l5EKp6O8018280@zion.cs.uiuc.edu> References: <200706142051.l5EKp6O8018280@zion.cs.uiuc.edu> Message-ID: <7FB176F5-9963-4678-A802-EA8B1EBC5C72@apple.com> Hi Dan, Is this necessary? ARM is already doing this by marking trivially re- materializable instructions with let isReMaterializable = 1. Evan On Jun 14, 2007, at 1:51 PM, Dan Gohman wrote: > > > Changes in directory llvm/lib/CodeGen: > > LiveIntervalAnalysis.cpp updated: 1.246 -> 1.247 > VirtRegMap.cpp updated: 1.111 -> 1.112 > --- > Log message: > > Add a target hook to allow loads from constant pools to be > rematerialized, and an > implementation for x86. > > > --- > Diffs of the changes: (+6 -3) > > LiveIntervalAnalysis.cpp | 6 ++++-- > VirtRegMap.cpp | 3 ++- > 2 files changed, 6 insertions(+), 3 deletions(-) > > > Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp > diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.246 llvm/lib/ > CodeGen/LiveIntervalAnalysis.cpp:1.247 > --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.246 Fri Jun 8 > 12:18:56 2007 > +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Jun 14 15:50:44 2007 > @@ -336,12 +336,14 @@ > // time we see a vreg. > if (interval.empty()) { > // Remember if the definition can be rematerialized. All > load's from fixed > - // stack slots are re-materializable. > + // stack slots are re-materializable. The target may permit > other loads to > + // be re-materialized as well. > int FrameIdx = 0; > if (vi.DefInst && > (tii_->isReMaterializable(vi.DefInst->getOpcode()) || > (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) && > - mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)))) > + mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)) || > + tii_->isOtherReMaterializableLoad(vi.DefInst))) > interval.remat = vi.DefInst; > > // Get the Idx of the defining instructions. > > > Index: llvm/lib/CodeGen/VirtRegMap.cpp > diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.111 llvm/lib/CodeGen/ > VirtRegMap.cpp:1.112 > --- llvm/lib/CodeGen/VirtRegMap.cpp:1.111 Thu Apr 26 13:59:33 2007 > +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Jun 14 15:50:44 2007 > @@ -664,7 +664,8 @@ > // If this instruction is being rematerialized, just remove it! > int FrameIdx; > if ((TID->Flags & M_REMATERIALIZIBLE) || > - TII->isLoadFromStackSlot(&MI, FrameIdx)) { > + TII->isLoadFromStackSlot(&MI, FrameIdx) || > + TII->isOtherReMaterializableLoad(&MI)) { > bool Remove = true; > for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { > MachineOperand &MO = MI.getOperand(i); > > > > _______________________________________________ > 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 Sun Jun 17 19:17:38 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 17 Jun 2007 17:17:38 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp ARMInstrInfo.h In-Reply-To: <38A4060B-D4C6-44E3-BC18-AB39C5738E58@apple.com> References: <200706152115.l5FLFNXs031203@zion.cs.uiuc.edu> <38A4060B-D4C6-44E3-BC18-AB39C5738E58@apple.com> Message-ID: Geeze. I was sure I would've been yelled at had I made it into a targetinstrinfo bit. :-) Really didn't want to go with either approach. But I don't see a better alternative. Evan On Jun 15, 2007, at 2:37 PM, Chris Lattner wrote: > On Jun 15, 2007, at 2:15 PM, Evan Cheng wrote: >> Instructions with unique labels or embedded jumptables cannot be >> duplicated during ifcvt. > > Please turn this into a targetinstrinfo bit. Virtual methods should > only be used for properties whose behavior is a property of the > *operands* of the instruction in combination with the opcode. This > property seems to only depend on the opcode. > > -Chris > >> --- >> Diffs of the changes: (+31 -0) >> >> ARMInstrInfo.cpp | 29 +++++++++++++++++++++++++++++ >> ARMInstrInfo.h | 2 ++ >> 2 files changed, 31 insertions(+) >> >> >> Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp >> diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 llvm/lib/Target/ >> ARM/ARMInstrInfo.cpp:1.37 >> --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.36 Wed Jun 13 12:59:52 >> 2007 >> +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Fri Jun 15 16:15:00 2007 >> @@ -446,6 +446,35 @@ >> return PIdx != -1 && MI->getOperand(PIdx).getImmedValue() != >> ARMCC::AL; >> } >> >> +bool ARMInstrInfo::CanBeDuplicated(const MachineInstr *MI) const { >> + switch (MI->getOpcode()) { >> + default: return true; >> + // These have unique labels. >> + case ARM::PICADD: >> + case ARM::PICLD: >> + case ARM::PICLDZH: >> + case ARM::PICLDZB: >> + case ARM::PICLDH: >> + case ARM::PICLDB: >> + case ARM::PICLDSH: >> + case ARM::PICLDSB: >> + case ARM::PICSTR: >> + case ARM::PICSTRH: >> + case ARM::PICSTRB: >> + case ARM::LEApcrel: >> + case ARM::LEApcrelJT: >> + case ARM::tPICADD: >> + case ARM::tLEApcrel: >> + case ARM::tLEApcrelJT: >> + case ARM::CONSTPOOL_ENTRY: >> + // These embed jumptables. >> + case ARM::BR_JTr: >> + case ARM::BR_JTm: >> + case ARM::BR_JTadd: >> + return false; >> + } >> +} >> + >> bool ARMInstrInfo::PredicateInstruction(MachineInstr *MI, >> const std::vector >> &Pred) const { >> unsigned Opc = MI->getOpcode(); >> >> >> Index: llvm/lib/Target/ARM/ARMInstrInfo.h >> diff -u llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 llvm/lib/Target/ARM/ >> ARMInstrInfo.h:1.14 >> --- llvm/lib/Target/ARM/ARMInstrInfo.h:1.13 Tue May 29 13:42:18 2007 >> +++ llvm/lib/Target/ARM/ARMInstrInfo.h Fri Jun 15 16:15:00 2007 >> @@ -106,6 +106,8 @@ >> // Predication support. >> virtual bool isPredicated(const MachineInstr *MI) const; >> >> + virtual bool CanBeDuplicated(const MachineInstr *MI) const; >> + >> virtual >> bool PredicateInstruction(MachineInstr *MI, >> const std::vector >> &Pred) const; >> >> >> >> _______________________________________________ >> 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 resistor at mac.com Sun Jun 17 23:31:07 2007 From: resistor at mac.com (Owen Anderson) Date: Sun, 17 Jun 2007 23:31:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706180431.l5I4V7jj000418@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.34 -> 1.35 --- Log message: Don't perform an expensive check if it's not necessary. --- Diffs of the changes: (+12 -2) GVNPRE.cpp | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.34 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.35 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.34 Fri Jun 15 19:26:54 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Sun Jun 17 23:30:44 2007 @@ -329,7 +329,12 @@ lhsValid = true; break; } - lhsValid &= !dependsOnInvoke(BO->getOperand(0)); + + // Check for dependency on invoke insts + // NOTE: This check is expensive, so don't do it if we + // don't have to + if (lhsValid) + lhsValid = !dependsOnInvoke(BO->getOperand(0)); bool rhsValid = !isa(BO->getOperand(1)); if (!rhsValid) @@ -339,7 +344,12 @@ rhsValid = true; break; } - rhsValid &= !dependsOnInvoke(BO->getOperand(1)); + + // Check for dependency on invoke insts + // NOTE: This check is expensive, so don't do it if we + // don't have to + if (rhsValid) + rhsValid = !dependsOnInvoke(BO->getOperand(1)); if (!lhsValid || !rhsValid) set.erase(BO); From resistor at mac.com Sun Jun 17 23:31:44 2007 From: resistor at mac.com (Owen Anderson) Date: Sun, 17 Jun 2007 23:31:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706180431.l5I4Virs000438@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.35 -> 1.36 --- Log message: Fix indentation. --- Diffs of the changes: (+6 -6) GVNPRE.cpp | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.35 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.36 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.35 Sun Jun 17 23:30:44 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Sun Jun 17 23:31:21 2007 @@ -338,12 +338,12 @@ bool rhsValid = !isa(BO->getOperand(1)); if (!rhsValid) - for (std::set::iterator I = set.begin(), E = set.end(); - I != E; ++I) - if (VN[*I] == VN[BO->getOperand(1)]) { - rhsValid = true; - break; - } + for (std::set::iterator I = set.begin(), E = set.end(); + I != E; ++I) + if (VN[*I] == VN[BO->getOperand(1)]) { + rhsValid = true; + break; + } // Check for dependency on invoke insts // NOTE: This check is expensive, so don't do it if we From resistor at mac.com Sun Jun 17 23:42:51 2007 From: resistor at mac.com (Owen Anderson) Date: Sun, 17 Jun 2007 23:42:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp Message-ID: <200706180442.l5I4gpiL000644@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GVNPRE.cpp updated: 1.36 -> 1.37 --- Log message: Cache the results of dependsOnInvoke() --- Diffs of the changes: (+18 -4) GVNPRE.cpp | 22 ++++++++++++++++++---- 1 files changed, 18 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.36 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.37 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.36 Sun Jun 17 23:31:21 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Sun Jun 17 23:42:29 2007 @@ -103,6 +103,7 @@ std::map > availableOut; std::map > anticipatedIn; + std::map invokeDep; virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -135,6 +136,8 @@ std::map > availOut); void cleanup(); void elimination(); + + bool dependsOnInvoke(Value* V); }; @@ -285,11 +288,15 @@ } } -bool dependsOnInvoke(Value* V) { +bool GVNPRE::dependsOnInvoke(Value* V) { if (!isa(V)) return false; User* U = cast(V); + std::map::iterator I = invokeDep.find(U); + if (I != invokeDep.end()) + return I->second; + std::vector worklist(U->op_begin(), U->op_end()); std::set visited; @@ -304,9 +311,15 @@ return true; User* curr = cast(current); - for (unsigned i = 0; i < curr->getNumOperands(); ++i) - if (visited.find(curr->getOperand(i)) == visited.end()) - worklist.push_back(curr->getOperand(i)); + std::map::iterator CI = invokeDep.find(curr); + if (CI != invokeDep.end()) { + if (CI->second) + return true; + } else { + for (unsigned i = 0; i < curr->getNumOperands(); ++i) + if (visited.find(curr->getOperand(i)) == visited.end()) + worklist.push_back(curr->getOperand(i)); + } } return false; @@ -593,6 +606,7 @@ createdExpressions.clear(); availableOut.clear(); anticipatedIn.clear(); + invokeDep.clear(); std::map > generatedExpressions; std::map > generatedPhis;