From lattner at cs.uiuc.edu Mon Aug 2 03:26:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 03:26:07 -0500 Subject: [llvm-commits] CVS: llvm-www/Features.html Message-ID: <200408020826.DAA16955@apoc.cs.uiuc.edu> Changes in directory llvm-www: Features.html updated: 1.8 -> 1.9 --- Log message: Close some li tags --- Diffs of the changes: (+2 -2) Index: llvm-www/Features.html diff -u llvm-www/Features.html:1.8 llvm-www/Features.html:1.9 --- llvm-www/Features.html:1.8 Mon Jul 19 11:03:21 2004 +++ llvm-www/Features.html Mon Aug 2 03:25:57 2004 @@ -13,11 +13,11 @@
  • A stable implementation of the LLVM instruction set, which serves as both the online and offline code representation, together with assembly - (ASCII) and bytecode (binary) readers and writers, and a verifier. + (ASCII) and bytecode (binary) readers and writers, and a verifier.
  • A powerful pass-management system that automatically sequences passes (including analysis, transformation, and code-generation passes) based on - their dependences, and pipelines them for efficiency. + their dependences, and pipelines them for efficiency.
  • A wide range of global scalar optimizations.
  • From lattner at cs.uiuc.edu Mon Aug 2 05:10:18 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 05:10:18 -0500 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200408021010.FAA16378@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.30 -> 1.31 --- Log message: This pass has proven its metal, remove -disable option. --- Diffs of the changes: (+1 -5) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.30 llvm/tools/gccld/GenerateCode.cpp:1.31 --- llvm/tools/gccld/GenerateCode.cpp:1.30 Tue Jul 27 03:13:15 2004 +++ llvm/tools/gccld/GenerateCode.cpp Mon Aug 2 05:10:08 2004 @@ -38,9 +38,6 @@ cl::opt DisableOptimizations("disable-opt", cl::desc("Do not run any optimization passes")); - cl::opt - DisableGlobalsModRef("disable-globalsmodref", cl::Hidden, - cl::desc("Turn on the more aggressive alias analysis")); } /// CopyEnv - This function takes an array of environment variables and makes a @@ -200,8 +197,7 @@ addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. - if (!DisableGlobalsModRef) - addPass(Passes, createGlobalsModRefPass()); // IP alias analysis + addPass(Passes, createGlobalsModRefPass()); // IP alias analysis addPass(Passes, createLICMPass()); // Hoist loop invariants addPass(Passes, createLoadValueNumberingPass()); // GVN for load instrs From brukman at cs.uiuc.edu Mon Aug 2 08:59:21 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 2 Aug 2004 08:59:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Message-ID: <200408021359.IAA10491@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: ModuloScheduling.cpp updated: 1.21 -> 1.22 --- Log message: * ceil() requires #include for compilation * Alphabetize #includes * Fix some lines to fit within 80 cols --- Diffs of the changes: (+4 -3) Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.21 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.22 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.21 Fri Jul 30 18:36:10 2004 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Mon Aug 2 08:59:10 2004 @@ -9,6 +9,7 @@ // // This ModuloScheduling pass is based on the Swing Modulo Scheduling // algorithm. +// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "ModuloSched" @@ -26,13 +27,13 @@ #include "Support/Debug.h" #include "Support/GraphWriter.h" #include "Support/StringExtras.h" -#include -#include +#include #include #include +#include +#include #include "../../Target/SparcV9/SparcV9Internals.h" #include "../../Target/SparcV9/SparcV9RegisterInfo.h" - using namespace llvm; /// Create ModuloSchedulingPass From brukman at cs.uiuc.edu Mon Aug 2 09:02:31 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 2 Aug 2004 09:02:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp Message-ID: <200408021402.JAA11230@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: MSchedGraph.cpp updated: 1.5 -> 1.6 --- Log message: Add #include and abort() to silence a warning --- Diffs of the changes: (+6 -5) Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.5 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.6 --- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.5 Fri Jul 30 18:36:10 2004 +++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp Mon Aug 2 09:02:21 2004 @@ -1,4 +1,4 @@ -//===-- MSchedGraph.cpp - Scheduling Graph ------------------------*- C++ -*-===// +//===-- MSchedGraph.cpp - Scheduling Graph ----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,6 +17,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Target/TargetInstrInfo.h" #include "Support/Debug.h" +#include using namespace llvm; MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst, @@ -35,13 +36,13 @@ MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) { //Loop over all the successors of our predecessor //return the edge the corresponds to this in edge - for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), E = pred->succ_end(); - I != E; ++I) { - if(*I == this) + for (MSchedGraphNode::succ_iterator I = pred->succ_begin(), + E = pred->succ_end(); I != E; ++I) { + if (*I == this) return I.getEdge(); } assert(0 && "Should have found edge between this node and its predecessor!"); - + abort(); } unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) { From criswell at cs.uiuc.edu Mon Aug 2 10:12:40 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 10:12:40 -0500 Subject: [llvm-commits] CVS: llvm/test/QMTest/expectations.darwin.qmr expectations.linux.qmr expectations.sunos.qmr expectations.unknown.qmr Message-ID: <200408021512.KAA15324@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.darwin.qmr updated: 1.4 -> 1.5 expectations.linux.qmr updated: 1.11 -> 1.12 expectations.sunos.qmr updated: 1.11 -> 1.12 expectations.unknown.qmr updated: 1.6 -> 1.7 --- Log message: Set Regression.Transforms.IndVarsSimplify.subtract to XFAIL. Set Regression.CodeGen.Generic.2004-04-09-SameValueCoalescing to PASS. --- Diffs of the changes: (+4 -4) Index: llvm/test/QMTest/expectations.darwin.qmr diff -u llvm/test/QMTest/expectations.darwin.qmr:1.4 llvm/test/QMTest/expectations.darwin.qmr:1.5 --- llvm/test/QMTest/expectations.darwin.qmr:1.4 Fri Jul 16 09:20:20 2004 +++ llvm/test/QMTest/expectations.darwin.qmr Mon Aug 2 10:12:29 2004 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U9Regression.Transforms.Mem2Reg.2003-10-05-DeadPHIInsertionqh (h o}q(h}h}ubub.(hoq }q!(hhhUFAILq"h}h U.Regression.Transforms.CorrelatedExprs.looptestq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhh"h}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U2Regression.Assembler.2002-01-24-ValueRefine! AbsTypeq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-PredecessorProblemq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSub! Moveq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h UARegression.Transfo rms.CorrelatedExprs.2002-10-07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h URegression.Transforms.CorrelatedExprs.2002-10-08-DominatorTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.Linker! .testlink2q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Transforms.GCSE.RLE-Eliminateq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U4Regression.C++Frontend.2003-09-30-NestedFunctionDeclq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U=Regression.Transforms.CorrelatedExprs.2002-09-23-PHIUpdateBugq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U7Regression.Transforms.LowerSwitch.2003-05-01-PHIProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U2Regression.Transforms.ADCE.2003-09-15-InfLoopCrashq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.Transforms.DSAnalysis.recursionq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Jello.2003-01-15-AlignmentTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUFAILq?h}h UFeature.mc.simplecalltestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.CFrontend.2002-04-07-SwitchStmtq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U!Regression.Jello.2003-01-10-FUCOMq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Reg! ression.CFrontend.2003-08-21-StmtExprq?h (h o}q?(h}h}ubub.(hoq?}q?( hhhUPASSq?h}h U*Regression.Transforms.ScalarRepl.basictestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhh"h}h U6Regression.Transforms.LevelRaise.2002-02-11-ArrayShapeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U1Regression.Assembler.2003-03-03-DuplicateConstantq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U.Regression.Transforms.ModuloSched.arith-simpleq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U%Regression.Transforms.InstCombine.andq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Other.2002-08-02-DomSetProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Assembler.2002-07-25-ParserAssertionFailureq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.LevelRaise.2002-03-20-BadCodegenq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U%Regression.Transforms.ADCE.basictest1q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUFAILq?h}h UFeature.mc.recursivetypeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U$Regression.Transforms.InstCombine.orq?h (h o! }q?(h}h}ubub.(hoq?}q?(hhhhh}h U Regression.Verifier.AmbiguousPhiq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U'Regression.Analysis.DSGraph.constantizeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.GlobalDCE.2002-08-17-FunctionDGEq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U4Regression.Transforms.SimplifyCFG.2002-06-24-PHINodeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Linker.2003-05-15-TypeProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U#Regression.Transforms.SCCP.sccptestq?h (h o}q?(h}h}ubub.(hor--------- \ No newline at end of file +q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U>Regression.Transforms.LevelRaise.2002-05-02-BadCastEliminationq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-! PredecessorProblemq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U1Regression.CFrontend.2002-03-12-StructInitializerqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhUPASSqWh}h U$Regression.BugPoint.misopt-basictestqXh (h o}qY(h}h}ubub.(hoqZ}q[(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemq\h (h o}q](h}h}ubub.(hoq^}q_(hhhhh}h U)Regression.Transforms.Reassociate.subtestq`h (h o}qa(h}h}! ubub.(hoqb}qc(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExp rqdh (h o}qe(h}h}ubub.(hoqf}qg(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveqhh (h o}qi(h}h}ubub.(hoqj}qk(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqlh (h o}qm(h}h}ubub.(hoqn}qo(hhhhh}h U>Regression.Transforms.InstCombine.2003-06-22-ConstantExprCrashqph (h o}qq(h}h}ubub.(hoqr}qs(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqth (h o}qu(h}h}ubub.(hoqv}qw(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqxh (h o}qy(h}h}ubub.(hoqz}q{(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestq|h (h o}q}(h}h}ubub.(hoq~}q(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.(! hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10- 07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U>Regression.Transforms.InstCombine.2003-06-22-ConstantExprCrashqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsq{h (h o}q|(h}h}ubub.(hoq}}q~(hhhhh}h U(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-! 07-DominatorProblemq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3Reg ression.Transforms.PiNodeInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-Ag! ressiveSubMoveq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h UARegressi on.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h! UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqc h (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h URegression.Transforms.LevelRaise.2002-05-02-BadCastEliminationq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-! PredecessorProblemq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U Regression.Reoptimizer.ticm.ticmq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhUPASSqSh}h U$Regression.BugPoint.misopt-basictestqTh (h o}qU(h}h}ubub.(hoqV}qW(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqXh (h o}qY(h}h}ubub.(hoqZ}q[(hhhhh}h U)Regression.Transforms.Reassociate.subtestq\h (h o}q](h}h}ubub.(hoq^}q_(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq`h (h o}qa(h}h}ubub.(hoqb}qc(hhhhh}h U! =Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveqdh (h o }qe(h}h}ubub.(hoqf}qg(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqhh (h o}qi(h}h}ubub.(hoqj}qk(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqlh (h o}qm(h}h}ubub.(hoqn}qo(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqph (h o}qq(h}h}ubub.(hoqr}qs(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqth (h o}qu(h}h}ubub.(hoqv}qw(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qxh (h o}qy(h}h}ubub.(hoqz}q{(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsq|h (h o}q}(h}h}ubub.(hoq~}q(hhhhh}h U(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U Regression.Reoptimizer.ticm.ticmqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h! }ubub.(hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2 002-10-07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h URegression.Transforms.CorrelatedExprs.2002-10-08-DominatorTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.Linker.testlink2q?h (h o}q?! (h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Transforms.GCSE.RLE-Eliminateq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U4Regression.C++Frontend.2003-09-30-NestedFunctionDeclq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U=Regression.Transforms.CorrelatedExprs.2002-09-23-PHIUpdateBugq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U7Regression.Transforms.LowerSwitch.2003-05-01-PHIProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U2Regression.Transforms.ADCE.2003-09-15-InfLoopCrashq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.Transforms.DSAnalysis.recursionq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Jello.2003-01-15-AlignmentTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUFAILq?h}h UFeature.mc.simplecalltestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.CFrontend.2002-04-07-SwitchStmtq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U!Regression.Jello.2003-01-10-FUCOMq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.CFrontend.200! 3-08-21-StmtExprq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUPASSq?h}h U* Regression.Transforms.ScalarRepl.basictestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhh"h}h U6Regression.Transforms.LevelRaise.2002-02-11-ArrayShapeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U1Regression.Assembler.2003-03-03-DuplicateConstantq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U.Regression.Transforms.ModuloSched.arith-simpleq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U%Regression.Transforms.InstCombine.andq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Other.2002-08-02-DomSetProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Assembler.2002-07-25-ParserAssertionFailureq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.LevelRaise.2002-03-20-BadCodegenq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U%Regression.Transforms.ADCE.basictest1q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUFAILq?h}h UFeature.mc.recursivetypeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U$Regression.Transforms.InstCombine.orq?h (h o}q?(h}h}ubub.(hoq?! }q?(hhhhh}h U Regression.Verifier.AmbiguousPhiq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U'Regression.Analysis.DSGraph.constantizeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.GlobalDCE.2002-08-17-FunctionDGEq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U4Regression.Transforms.SimplifyCFG.2002-06-24-PHINodeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Linker.2003-05-15-TypeProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U#Regression.Transforms.SCCP.sccptestq?h (h o}q?(h}h}ubub.(hor+++++++++ \ No newline at end of file From lattner at cs.uiuc.edu Mon Aug 2 15:16:31 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:16:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200408022016.PAA18486@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.109 -> 1.110 --- Log message: Hide this option --- Diffs of the changes: (+1 -1) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.109 llvm/lib/Analysis/DataStructure/Local.cpp:1.110 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.109 Wed Jul 21 15:50:33 2004 +++ llvm/lib/Analysis/DataStructure/Local.cpp Mon Aug 2 15:16:21 2004 @@ -36,7 +36,7 @@ X("datastructure", "Local Data Structure Analysis"); static cl::opt -TrackIntegersAsPointers("dsa-track-integers", +TrackIntegersAsPointers("dsa-track-integers", cl::Hidden, cl::desc("If this is set, track integers as potential pointers")); namespace llvm { From lattner at cs.uiuc.edu Mon Aug 2 15:28:54 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:28:54 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408022028.PAA18527@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.221 -> 1.222 --- Log message: Substantially hack on and clean up the release notes --- Diffs of the changes: (+55 -68) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.221 llvm/docs/ReleaseNotes.html:1.222 --- llvm/docs/ReleaseNotes.html:1.221 Sun Jul 25 17:15:33 2004 +++ llvm/docs/ReleaseNotes.html Mon Aug 2 15:28:44 2004 @@ -71,15 +71,14 @@

    This is the fourth public release of the LLVM compiler infrastructure. This release primarily improves the performance of the -code produced by all aspects of the LLVM compiler and adds many new features, and fixes a few -bugs as well.

    +code produced by all aspects of the LLVM compiler, adds many new features, fixes a few +bugs, and speeds up the compiler.

    At this time, LLVM is known to correctly compile and run all C & C++ -SPEC CPU2000 benchmarks, the Olden benchmarks, and the Ptrdist benchmarks. It -has also been used to compile many other programs. LLVM now also works -with a broad variety of C++ programs, though it has still received less testing -than the C front-end.

    +SPEC CPU95 & 2000 benchmarks, the Olden benchmarks, and the Ptrdist +benchmarks, and many other programs. LLVM now also works +with a broad variety of C++ programs.

    @@ -97,8 +96,8 @@
  • Bugpoint can now narrow down code-generation bugs to a loop nest, where before it could only narrow them down to a function being miscompiled.
  • Bugpoint can now debug arbitrary -modes of llc and lli, by passing them command line flags (e.g., --regalloc=linearscan, -enable-correct-eh-support, etc.)
  • +modes of llc and lli, by passing them command line flags (e.g. +-regalloc=linearscan).
  • The Control Flow Graph in the native code generators is no longer constrained to be the same as the CFG for the LLVM input code.
  • The LLVM induction variable analysis routines have been rewritten.
  • @@ -108,8 +107,9 @@
  • LLVM now has first-class support for Accurate Garbage Collection, enabling the use of aggressive copying and generational collectors.
  • -
  • LLVM now includes an implementation of Andersen's interprocedural alias -analysis algorithm.
  • +
  • LLVM now includes a simple implementation of Andersen's interprocedural alias +analysis algorithm.
  • Bugpoint can extract individual basic blocks to track down reduce miscompilation testcases.
  • LLVM and the C front-end now work under Win32 using the @@ -117,29 +117,35 @@ This includes the JIT compiler.
  • The LLVM code generator is now being documented.
  • -
  • There is a new tool, llvm-bcanalyzer. This tool can compute basic -statistics and bytecode density statistics on a module or function basis and -also dump out bytecode in a textual format that is lower level than assembly -(values are not resolved from slot numbers). It should only be of interest to -(a) those who are working to improve the bytecode format and (b) those who -really want to understand or document the details of the bytecode format.
  • -
  • The LLVM Bytecode file format is now +
  • LLVM includes a new tool, llvm-bcanalyzer, This tool +can compute various statistics and dump information about LLVM bytecode +encoding.
  • +
  • The LLVM bytecode file format is now documented.
  • LLVM now provides an llvm.isunordered intrinsic for efficient implementation of unordered floating point comparisons.
  • The llvmgcc front-end now supports the GCC builtins for ISO C99 floating point comparison macros (e.g., __builtin_islessequal).
  • -
  • Now that there are more source files than can fit on a 32Kbyte command -line (Linux's limit), there's a new utility for searching the sources. The -llvmgrep tool in the utils directory combines an egrep and a find without -passing filenames through the command line. This improves performance -slightly. Simply run llvmgrep like you might egrep but leave off the file -names.
  • -
  • We now generate HTML documentation and man pages for the tools from a single -source (perl-style POD files).
  • +
  • We now generate HTML documentation and man pages +for the tools from a single source (perl-style POD files).
  • The LLVM code generator can now dynamically load targets from shared objects.
  • +
  • LLVM now includes a "skeleton" target, which makes it easier to get +started porting LLVM to new architectures.
  • +
  • The linear scan register allocator is now enabled by default in the +target-independent code generator.
  • +
  • LLVM now includes a dead store elimination pass.
  • +
  • Bugpoint can now debug miscompilations that lead to the program going +into an infinite loop.
  • +
  • LLVM now provides interfaces to support ML-style pattern matching on the +LLVM IR.
  • +
  • LLVM now includes a context-sensitive mod/ref analysis +for global variables, which is now enabled by default in gccld.
  • +
  • LLVM can now autogenerate assembly printers for code generators from the +tablegen description of the target (before they were hand coded).
  • @@ -161,6 +167,10 @@ with 64-bit pointers.
  • Bugpoint doesn't support uses of external fns by immediate constant exprs
  • +
  • Can't add function passes that +depend on immutable passes to the FunctionPassManager.
  • +
  • Archive file reader doesn't +understand abbreviated names in headers
  • @@ -189,6 +199,10 @@
  • Bytecode Enhancements Needed
  • [loopsimplify] Loop simplify is really slow on 252.eon
  • +
  • [code-cleanup] SymbolTable + class cleanup, Type should not derive from Value, eliminate + ConstantPointerRef class.
  • +
  • The memory footprint of the LLVM IR has been reduced substantially.
  • @@ -231,7 +245,7 @@
  • The -inline pass no longer misses obvious inlining opportunities just because the callee eventually calls into an external function.
  • -
  • The -simplifycfg pass can now "if convert" simple statements into the new +
  • The -simplifycfg pass can now "if convert" simple statements into the select instruction.
  • The -loopsimplify pass can now break The link-time optimizer now runs the -prune-eh pass (to remove unused exception handlers).
  • +
  • The link-time optimizer now runs dead store elimination and uses a simple +interprocedural alias analysis.
  • +
  • The -simplifycfg pass can now eliminate simple correlated branches (such as "if (A < B && A < B)", and can turn short-circuiting operators into the strict versions when useful (such as "if (A < B || A @@ -254,16 +271,14 @@ propagation of function calls. It currently supports a few math library functions like sqrt/sin/cos/etc.
  • -
  • The C backend now emits Syntactic +
  • The C backend now emits syntactic loops in the code to help C compilers whose optimizers do not recognize loops formed from gotos (like GCC).
  • -
  • Fixed: [sparcv9] null -often spilled to constant pool.
  • +
  • The SparcV9 backend no longers spills the null constant to the constant +pool.
  • -
  • Fixed: [code-cleanup] SymbolTable - class cleanup, Type should not derive from Value, eliminate - ConstantPointerRef class. All three changes have been made. @@ -274,7 +289,7 @@ - -
    -In this release, the following portability problems were fixed: -
    - - -
    Known Problems @@ -635,14 +627,15 @@
    • The C++ front-end inherits all problems afflicting the C front-end.
    • -
    -

    IA64 note: The C++ front-end does not use IA64 ABI compliant layout of vtables. +

  • IA-64 specific: The C++ front-end does not use IA64 ABI compliant layout of v-tables. In particular, it just stores function pointers instead of function descriptors in the vtable. This bug prevents mixing C++ code compiled with LLVM with C++ objects compiled by other C++ compilers.

    + + @@ -688,13 +681,7 @@
      -
    • Optimized (Release) versions of LLVM built with GCC 3.3.2 or 3.3.3 will - produce an llc tool that always enters an infinite loop due to what - appears to be an optimization bug (-O2 and -O3) in those versions of GCC. - This problem does not happen in GCC 3.3.1 nor GCC 3.4.0 nor does it happen if - you build a Debug version of LLVM. You are cautioned not to use GCC 3.3.2 or - GCC 3.3.3 to build Optimized versions of LLVM. It is unclear whether this problem - affects other backends but it is unlikely.
    • +
    • none yet
    @@ -770,7 +757,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/07/25 22:15:33 $ + Last modified: $Date: 2004/08/02 20:28:44 $ From lattner at cs.uiuc.edu Mon Aug 2 15:30:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:30:01 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408022030.PAA18554@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.222 -> 1.223 --- Log message: ... now real HTML 4.01 strict! --- Diffs of the changes: (+2 -2) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.222 llvm/docs/ReleaseNotes.html:1.223 --- llvm/docs/ReleaseNotes.html:1.222 Mon Aug 2 15:28:44 2004 +++ llvm/docs/ReleaseNotes.html Mon Aug 2 15:29:51 2004 @@ -632,7 +632,7 @@ href="http://llvm.cs.uiuc.edu/PR406">IA64 ABI compliant layout of v-tables. In particular, it just stores function pointers instead of function descriptors in the vtable. This bug prevents mixing C++ code compiled with -LLVM with C++ objects compiled by other C++ compilers.

    +LLVM with C++ objects compiled by other C++ compilers.
  • @@ -757,7 +757,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/02 20:28:44 $ + Last modified: $Date: 2004/08/02 20:29:51 $ From lattner at cs.uiuc.edu Mon Aug 2 15:32:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:32:02 -0500 Subject: [llvm-commits] CVS: llvm-www/Features.html Message-ID: <200408022032.PAA18577@apoc.cs.uiuc.edu> Changes in directory llvm-www: Features.html updated: 1.9 -> 1.10 --- Log message: Fix broken linkx --- Diffs of the changes: (+3 -3) Index: llvm-www/Features.html diff -u llvm-www/Features.html:1.9 llvm-www/Features.html:1.10 --- llvm-www/Features.html:1.9 Mon Aug 2 03:25:57 2004 +++ llvm-www/Features.html Mon Aug 2 15:31:51 2004 @@ -49,8 +49,8 @@
  • LLVM uses a simple low-level language with strictly defined semantics.
  • -
  • It includes front-ends for C, - C++, and It includes front-ends for C, + C++, and Stacker (a forth-like language). Front-ends for Java, Microsoft CLI, and O-Caml are in early development.
  • @@ -76,7 +76,7 @@ develop for. For example, the Stacker front-end was written in 4 days by someone who started knowing nothing about LLVM. Additionally, LLVM has tools to make development easier. + href="docs/CommandGuide/html/bugpoint.html">development easier.
  • LLVM is under active development and is constantly being extended, enhanced and improved. See the status updates on the left bar to see the rate From lattner at cs.uiuc.edu Mon Aug 2 15:33:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:33:05 -0500 Subject: [llvm-commits] CVS: llvm-www/Features.html Message-ID: <200408022033.PAA18597@apoc.cs.uiuc.edu> Changes in directory llvm-www: Features.html updated: 1.10 -> 1.11 --- Log message: change bugpoint link --- Diffs of the changes: (+1 -1) Index: llvm-www/Features.html diff -u llvm-www/Features.html:1.10 llvm-www/Features.html:1.11 --- llvm-www/Features.html:1.10 Mon Aug 2 15:31:51 2004 +++ llvm-www/Features.html Mon Aug 2 15:32:55 2004 @@ -76,7 +76,7 @@ develop for. For example, the Stacker front-end was written in 4 days by someone who started knowing nothing about LLVM. Additionally, LLVM has tools to make development easier.
  • + href="docs/Bugpoint.html">development easier.
  • LLVM is under active development and is constantly being extended, enhanced and improved. See the status updates on the left bar to see the rate From lattner at cs.uiuc.edu Mon Aug 2 15:33:48 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:33:48 -0500 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200408022033.PAA18620@apoc.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.108 -> 1.109 --- Log message: Fix broken link --- Diffs of the changes: (+1 -1) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.108 llvm-www/www-index.html:1.109 --- llvm-www/www-index.html:1.108 Fri Jul 16 23:23:31 2004 +++ llvm-www/www-index.html Mon Aug 2 15:33:38 2004 @@ -32,7 +32,7 @@
  • A compiler infrastructure - LLVM is also a collection of source code that implements the language and compilation strategy. The primary components of the LLVM infrastructure are a -GCC-based C & C++ front-end, a +GCC-based C & C++ front-end, a link-time optimization framework with a growing set of global and interprocedural analyses and transformations, static back-ends for the SPARC v9 and X86 architectures, a back-end which emits portable C code, and a From lattner at cs.uiuc.edu Mon Aug 2 15:53:40 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 15:53:40 -0500 Subject: [llvm-commits] CVS: llvm-www/Documentation.html Message-ID: <200408022053.PAA18675@apoc.cs.uiuc.edu> Changes in directory llvm-www: Documentation.html updated: 1.12 -> 1.13 --- Log message: Reorganize and update information about the documentation. Oh also get rid of the explicit tags that misha loves so much. --- Diffs of the changes: (+62 -47) Index: llvm-www/Documentation.html diff -u llvm-www/Documentation.html:1.12 llvm-www/Documentation.html:1.13 --- llvm-www/Documentation.html:1.12 Mon Jun 21 13:16:32 2004 +++ llvm-www/Documentation.html Mon Aug 2 15:53:30 2004 @@ -1,7 +1,9 @@ -

    LLVM Documentation
    +
    LLVM Documentation
    -LLVM Design: + +
    LLVM Design:
    + -LLVM User Guides: + +
    LLVM User Guides:
    +
    • The LLVM Getting Started Guide - @@ -25,12 +32,6 @@
    • LLVM Command Guide - A reference manual for the LLVM command line utilities ("man" pages for LLVM tools).
    • -
    • LLVM Project Guide - How-to guide and -templates for new projects that use the LLVM infrastructure. The -templates (directory organization, Makefiles, and test tree) allow the project -code to be located outside (or inside) the llvm/ tree, while using LLVM -header files and libraries.
    • -
    • How to Submit A Bug Report - Instructions for properly submitting information about any bugs you run into in the LLVM system.
    • @@ -42,44 +43,25 @@ Instructions for building the front-end from source.
    -Programming Documentation: + + +
    General LLVM Programming Documentation:
    + - -
    - LLVM Support -
    -
    + +
    LLVM Subsystem Documentation:
    + + +
      + +
    • Writing an LLVM Pass - Information +on how to write LLVM transformations and analyses.
    • + +
    • The LLVM Target-Independent Code +Generator - The design and implementation of the LLVM code generator. +Useful if you are working on retargetting LLVM to a new architecture, designing +a new codegen pass, or enhancing existing components.
    • + +
    • TableGen Fundamentals - +Describes the TableGen tool, which is used heavily by the LLVM code +generator.
    • + +
    • Alias Analysis in LLVM - Information +on how to write a new alias analysis implementation or how to use existing +analyses.
    • + +
    • The Stacker Cronicles - This document +describes both the Stacker language and LLVM frontend, but also some details +about LLVM useful for those writing front-ends.
    • + +
    • Accurate Garbage Collection with +LLVM - The interfaces source-language compilers should use for compiling +GC'd programs.
    • + +
    • Source Level Debugging with +LLVM - This document describes the design and philosophy behind the LLVM +source-level debugger.
    • + +
    • Bugpoint automatic bug finder and +test-case reducer description and usage information.
    • + +
    + + +
    LLVM Support
    +
    • Frequently Asked Questions - A list of common From lattner at cs.uiuc.edu Mon Aug 2 16:18:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:18:10 -0500 Subject: [llvm-commits] CVS: llvm-www/Documentation.html Message-ID: <200408022118.QAA18754@apoc.cs.uiuc.edu> Changes in directory llvm-www: Documentation.html updated: 1.13 -> 1.14 --- Log message: More changes --- Diffs of the changes: (+29 -14) Index: llvm-www/Documentation.html diff -u llvm-www/Documentation.html:1.13 llvm-www/Documentation.html:1.14 --- llvm-www/Documentation.html:1.13 Mon Aug 2 15:53:30 2004 +++ llvm-www/Documentation.html Mon Aug 2 16:18:00 2004 @@ -28,10 +28,13 @@ Discusses how to get up and running quickly with the LLVM infrastructure. Everything from unpacking and compilation of the distribution to execution of some tools.
    • - +
    • LLVM Command Guide - A reference manual for the LLVM command line utilities ("man" pages for LLVM tools).
    • +
    • Release notes for the current release +- This describes new features, known bugs, and other limitations.
    • +
    • How to Submit A Bug Report - Instructions for properly submitting information about any bugs you run into in the LLVM system.
    • @@ -134,24 +137,36 @@ for the proper way to submit information about a bug you ran into in the LLVM system. -
    • You can probably find help on the unofficial LLVM IRC channel. We often are -on irc.oftc.net in the #llvm channel.
    • +
    • You can probably find help on the unofficial LLVM IRC channel. We often +are on irc.oftc.net in the #llvm channel. If you are using the mozilla +browser, and have chatzilla installed, you can join by clicking here.
    • + +
    + +
    LLVM Mailing Lists:
    + +
      +
    • The +LLVM Announcements List: This is a low volume list that provides important +announcements regarding LLVM. It gets email about once a month.
    • -
    • LLVM Mailing Lists: -
        -
      1. The - -LLVM Announcements List
      2. The Developer's -List (LLVM user & developer support)
      3. +List: This list is for people who want to be included in technical +discussions of LLVM. People post to this list when they have questions about +writing code for or using the LLVM tools. It is relatively low volume. +
      4. The Bugs & -Patches Archive
      5. +Patches Archive: This list gets emailed every time a bug is opened and +closed, and when people submit patches to be included in LLVM. It is higher +volume than the LLVMdev list. +
      6. The CVS Commits -Archive
      7. -
    • +Archive: This list contains all commit messages that are made when LLVM +developers commit code changes to the CVS archive. It is useful for those who +want to stay on the bleeding edge of LLVM development. This list is very high +volume. -
    • Results from the LLVM Automated Nightly -Tester
    From lattner at cs.uiuc.edu Mon Aug 2 16:29:30 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:29:30 -0500 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200408022129.QAA18798@apoc.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.20 -> 1.21 --- Log message: Revamp the index page --- Diffs of the changes: (+145 -121) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.20 llvm/docs/index.html:1.21 --- llvm/docs/index.html:1.20 Fri Jul 9 00:05:39 2004 +++ llvm/docs/index.html Mon Aug 2 16:29:20 2004 @@ -1,3 +1,4 @@ + @@ -11,164 +12,189 @@ - - - + + + + + @@ -180,8 +206,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/07/09 05:05:39 $ + Last modified: $Date: 2004/08/02 21:29:20 $ - - From lattner at cs.uiuc.edu Mon Aug 2 16:32:18 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:32:18 -0500 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200408022132.QAA18825@apoc.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.21 -> 1.22 --- Log message: continue hacking --- Diffs of the changes: (+12 -27) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.21 llvm/docs/index.html:1.22 --- llvm/docs/index.html:1.21 Mon Aug 2 16:29:20 2004 +++ llvm/docs/index.html Mon Aug 2 16:32:08 2004 @@ -1,4 +1,3 @@ - @@ -16,11 +15,7 @@
  • LLVM User Guides
  • General LLVM Programming Documentation
  • LLVM Subsystem Documentation
  • -
  • LLVM Support - -
  • +
  • LLVM Mailing Lists
  • @@ -55,6 +50,9 @@
  • LLVM Command Guide - A reference manual for the LLVM command line utilities ("man" pages for LLVM tools).
  • +
  • Frequently Asked Questions - A list of common +questions and problems and their solutions.
  • +
  • Release notes for the current release - This describes new features, known bugs, and other limitations.
  • @@ -67,6 +65,12 @@
  • How to build the C/C++ front-end - Instructions for building the front-end from source.
  • + +
  • You can probably find help on the unofficial LLVM IRC channel. We often +are on irc.oftc.net in the #llvm channel. If you are using the mozilla +browser, and have chatzilla installed, you can join by clicking here.
  • + @@ -151,26 +155,7 @@ - - - -
      -
    • Frequently Asked Questions - A list of common -questions and problems and their solutions.
    • - -
    • How-To-Submit-A-Bug - Instructions -for the proper way to submit information about a bug you ran into in the LLVM -system.
    • - -
    • You can probably find help on the unofficial LLVM IRC channel. We often -are on irc.oftc.net in the #llvm channel. If you are using the mozilla -browser, and have chatzilla installed, you can join by clicking here.
    • - -
    - - - +
      @@ -206,6 +191,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/08/02 21:29:20 $ + Last modified: $Date: 2004/08/02 21:32:08 $ From lattner at cs.uiuc.edu Mon Aug 2 16:33:55 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:33:55 -0500 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200408022133.QAA18848@apoc.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.22 -> 1.23 --- Log message: Written by --- Diffs of the changes: (+5 -1) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.22 llvm/docs/index.html:1.23 --- llvm/docs/index.html:1.22 Mon Aug 2 16:32:08 2004 +++ llvm/docs/index.html Mon Aug 2 16:33:45 2004 @@ -19,6 +19,10 @@
    +
    +

    Written by The LLVM Team

    +
    + @@ -191,6 +195,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/02 21:32:08 $ + Last modified: $Date: 2004/08/02 21:33:45 $ From lattner at cs.uiuc.edu Mon Aug 2 16:35:14 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:35:14 -0500 Subject: [llvm-commits] CVS: llvm-www/www-index.html Features.html Message-ID: <200408022135.QAA18877@apoc.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.109 -> 1.110 Features.html updated: 1.11 -> 1.12 --- Log message: Point to the docs dir --- Diffs of the changes: (+3 -3) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.109 llvm-www/www-index.html:1.110 --- llvm-www/www-index.html:1.109 Mon Aug 2 15:33:38 2004 +++ llvm-www/www-index.html Mon Aug 2 16:35:04 2004 @@ -78,7 +78,7 @@
    Want to learn more?

    If you'd like to learn more about LLVM, please take a look at the extensive -documentation for LLVM. In particular, all of +documentation for LLVM. In particular, all of the tools distributed with LLVM are described in the LLVM Command Guide. If you're interested in what source-language features and optimizations we support, please check out the -

  • LLVM has extensive documentation and has +
  • LLVM has extensive documentation and has hosted many projects of various sorts.
  • Many third-party users have claimed that LLVM is easy to work with and @@ -115,7 +115,7 @@
    Want to Know More?

    -You can browse the documentation online, +You can browse the documentation online, try LLVM in your web browser, or download the source code.

    From lattner at cs.uiuc.edu Mon Aug 2 16:37:21 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:37:21 -0500 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200408022137.QAA18908@apoc.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.23 -> 1.24 --- Log message: Add link for IRC --- Diffs of the changes: (+4 -4) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.23 llvm/docs/index.html:1.24 --- llvm/docs/index.html:1.23 Mon Aug 2 16:33:45 2004 +++ llvm/docs/index.html Mon Aug 2 16:37:11 2004 @@ -70,9 +70,9 @@
  • How to build the C/C++ front-end - Instructions for building the front-end from source.
  • -
  • You can probably find help on the unofficial LLVM IRC channel. We often -are on irc.oftc.net in the #llvm channel. If you are using the mozilla -browser, and have chatzilla installed, you can join by You can probably find help on the unofficial LLVM IRC +channel. We often are on irc.oftc.net in the #llvm channel. If you are +using the mozilla browser, and have chatzilla installed, you can join by clicking here.
  • @@ -195,6 +195,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/02 21:33:45 $ + Last modified: $Date: 2004/08/02 21:37:11 $ From lattner at cs.uiuc.edu Mon Aug 2 16:37:41 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:37:41 -0500 Subject: [llvm-commits] CVS: llvm-www/header.incl Message-ID: <200408022137.QAA18928@apoc.cs.uiuc.edu> Changes in directory llvm-www: header.incl updated: 1.23 -> 1.24 --- Log message: Point into the docs directory --- Diffs of the changes: (+3 -3) Index: llvm-www/header.incl diff -u llvm-www/header.incl:1.23 llvm-www/header.incl:1.24 --- llvm-www/header.incl:1.23 Mon Jul 12 17:44:33 2004 +++ llvm-www/header.incl Mon Aug 2 16:37:31 2004 @@ -19,9 +19,9 @@
    Overview
    Features
    -Documentation
    +Documentation
    Command Guide
    -Support
    +Support
    FAQ
    Publications
    LLVM Projects
    @@ -78,7 +78,7 @@

    IRC Channel:
    - irc.oftc.net #llvm + irc.oftc.net #llvm

    From criswell at cs.uiuc.edu Mon Aug 2 16:40:50 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 16:40:50 -0500 Subject: [llvm-commits] CVS: llvm/test/QMTest/llvm.py Message-ID: <200408022140.QAA22643@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: llvm.py updated: 1.29 -> 1.30 --- Log message: Fixed up whitespace. --- Diffs of the changes: (+10 -10) Index: llvm/test/QMTest/llvm.py diff -u llvm/test/QMTest/llvm.py:1.29 llvm/test/QMTest/llvm.py:1.30 --- llvm/test/QMTest/llvm.py:1.29 Mon Jun 21 01:37:11 2004 +++ llvm/test/QMTest/llvm.py Mon Aug 2 16:40:39 2004 @@ -869,16 +869,16 @@ environment['PATH'] = buildroot + '/tools/' + buildtype + ':' + srcroot + '/test/Scripts:' + environment['PATH'] environment['QMV_llvmgcc'] = context['llvmgcc'] - # Extract the RUN: script (making the following substitutions:) - extractEnv = { 's': srcfile, - 't': scriptfile + '.tmp', - 'llvmgcc': context['llvmgcc'], - 'llvmgxx': context['llvmgxx'] } - try: - self.extractScript (srcfile, scriptfile, extractEnv) - except EnvironmentError: - result.Fail ('Failed to extract script from ' + srcfile) - return + # Extract the RUN: script (making the following substitutions:) + extractEnv = { 's': srcfile, + 't': scriptfile + '.tmp', + 'llvmgcc': context['llvmgcc'], + 'llvmgxx': context['llvmgxx'] } + try: + self.extractScript (srcfile, scriptfile, extractEnv) + except EnvironmentError: + result.Fail ('Failed to extract script from ' + srcfile) + return # Execute the script using TestRunner. mypath = os.getcwd () From lattner at cs.uiuc.edu Mon Aug 2 16:42:23 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:42:23 -0500 Subject: [llvm-commits] CVS: llvm-www/Documentation.html Message-ID: <200408022142.QAA18960@apoc.cs.uiuc.edu> Changes in directory llvm-www: Documentation.html updated: 1.14 -> 1.15 --- Log message: This file is obsolete. Instead we just point into docs/ --- Diffs of the changes: (+3 -168) Index: llvm-www/Documentation.html diff -u llvm-www/Documentation.html:1.14 llvm-www/Documentation.html:1.15 --- llvm-www/Documentation.html:1.14 Mon Aug 2 16:18:00 2004 +++ llvm-www/Documentation.html Mon Aug 2 16:42:12 2004 @@ -1,172 +1,7 @@ -
    LLVM Documentation
    +
    Obsolete link
    - -
    LLVM Design:
    - - - - - -
    LLVM User Guides:
    - - - - - - -
    General LLVM Programming Documentation:
    - - - - - -
    LLVM Subsystem Documentation:
    - - -
      - -
    • Writing an LLVM Pass - Information -on how to write LLVM transformations and analyses.
    • - -
    • The LLVM Target-Independent Code -Generator - The design and implementation of the LLVM code generator. -Useful if you are working on retargetting LLVM to a new architecture, designing -a new codegen pass, or enhancing existing components.
    • - -
    • TableGen Fundamentals - -Describes the TableGen tool, which is used heavily by the LLVM code -generator.
    • - -
    • Alias Analysis in LLVM - Information -on how to write a new alias analysis implementation or how to use existing -analyses.
    • - -
    • The Stacker Cronicles - This document -describes both the Stacker language and LLVM frontend, but also some details -about LLVM useful for those writing front-ends.
    • - -
    • Accurate Garbage Collection with -LLVM - The interfaces source-language compilers should use for compiling -GC'd programs.
    • - -
    • Source Level Debugging with -LLVM - This document describes the design and philosophy behind the LLVM -source-level debugger.
    • - -
    • Bugpoint automatic bug finder and -test-case reducer description and usage information.
    • - -
    - - -
    LLVM Support
    - - -
      -
    • Frequently Asked Questions - A list of common -questions and problems and their solutions.
    • - -
    • How-To-Submit-A-Bug - Instructions -for the proper way to submit information about a bug you ran into in the LLVM -system.
    • - -
    • You can probably find help on the unofficial LLVM IRC channel. We often -are on irc.oftc.net in the #llvm channel. If you are using the mozilla -browser, and have chatzilla installed, you can join by clicking here.
    • - -
    - -
    LLVM Mailing Lists:
    - -
      -
    • The -LLVM Announcements List: This is a low volume list that provides important -announcements regarding LLVM. It gets email about once a month.
    • - -
    • The Developer's -List: This list is for people who want to be included in technical -discussions of LLVM. People post to this list when they have questions about -writing code for or using the LLVM tools. It is relatively low volume.
    • - -
    • The Bugs & -Patches Archive: This list gets emailed every time a bug is opened and -closed, and when people submit patches to be included in LLVM. It is higher -volume than the LLVMdev list.
    • - -
    • The CVS Commits -Archive: This list contains all commit messages that are made when LLVM -developers commit code changes to the CVS archive. It is useful for those who -want to stay on the bleeding edge of LLVM development. This list is very high -volume.
    • - -
    +This link is obsolete. Please update your bookmarks to point here. From lattner at cs.uiuc.edu Mon Aug 2 16:43:24 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 16:43:24 -0500 Subject: [llvm-commits] CVS: llvm-www/RandomBoxes/010-Docs.html Message-ID: <200408022143.QAA18984@apoc.cs.uiuc.edu> Changes in directory llvm-www/RandomBoxes: 010-Docs.html updated: 1.2 -> 1.3 --- Log message: Update link --- Diffs of the changes: (+1 -1) Index: llvm-www/RandomBoxes/010-Docs.html diff -u llvm-www/RandomBoxes/010-Docs.html:1.2 llvm-www/RandomBoxes/010-Docs.html:1.3 --- llvm-www/RandomBoxes/010-Docs.html:1.2 Fri May 28 14:26:03 2004 +++ llvm-www/RandomBoxes/010-Docs.html Mon Aug 2 16:43:14 2004 @@ -1,4 +1,4 @@ -LLVM has extensive Documentation +LLVM has extensive Documentation describing the high-level aspects of the compiler system in good detail. LLVM also includes doxygen and CVSWeb documentation for the From criswell at cs.uiuc.edu Mon Aug 2 17:24:50 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:24:50 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.config.in Message-ID: <200408022224.RAA09583@choi.cs.uiuc.edu> Changes in directory llvm: Makefile.config.in updated: 1.28 -> 1.29 --- Log message: Set a variable so that we can find the python interpreter. --- Diffs of the changes: (+3 -0) Index: llvm/Makefile.config.in diff -u llvm/Makefile.config.in:1.28 llvm/Makefile.config.in:1.29 --- llvm/Makefile.config.in:1.28 Thu Jun 17 10:39:58 2004 +++ llvm/Makefile.config.in Mon Aug 2 17:24:39 2004 @@ -28,6 +28,9 @@ # Path to the CC binary, which use used by testcases for native builds. CC := @CC@ +# Path to the Python interpreter +PYTHON := @PYTHON@ + # Linker flags. LDFLAGS+=@LDFLAGS@ From criswell at cs.uiuc.edu Mon Aug 2 17:29:00 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:29:00 -0500 Subject: [llvm-commits] CVS: llvm/test/Scripts/prcontext.py Message-ID: <200408022229.RAA09606@choi.cs.uiuc.edu> Changes in directory llvm/test/Scripts: prcontext.py added (r1.1) --- Log message: New python script that print a specified number of lines surrounding a located pattern. In other words, grep -C for Solaris. --- Diffs of the changes: (+29 -0) Index: llvm/test/Scripts/prcontext.py diff -c /dev/null llvm/test/Scripts/prcontext.py:1.1 *** /dev/null Mon Aug 2 17:29:00 2004 --- llvm/test/Scripts/prcontext.py Mon Aug 2 17:28:50 2004 *************** *** 0 **** --- 1,29 ---- + # + # Usage: + # prcontext <# lines of context> + # + + import sys + + # + # Get the arguments + # + pattern=sys.argv[1] + num=int(sys.argv[2]) + + # + # Get all of the lines in the file. + # + lines=sys.stdin.readlines() + + index=0 + for line in lines: + if ((line.find(pattern)) != -1): + if (index-num < 0): + bottom=0 + else: + bottom=index-num + for output in lines[bottom:index+num+1]: + print output[:-1] + index=index+1 + From criswell at cs.uiuc.edu Mon Aug 2 17:29:48 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:29:48 -0500 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200408022229.RAA09622@choi.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.53 -> 1.54 --- Log message: Add support for using the prcontext python script instead of grep -C. --- Diffs of the changes: (+2 -1) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.53 llvm/test/Makefile:1.54 --- llvm/test/Makefile:1.53 Mon Mar 29 14:23:11 2004 +++ llvm/test/Makefile Mon Aug 2 17:29:38 2004 @@ -51,7 +51,8 @@ -c "cxx=$(CXX)" \ -c "llvmgcc=$(LLVMGCC)" \ -c "llvmgxx=$(LLVMGXX)" \ - -c "make=$(MAKE)" + -c "make=$(MAKE)" \ + -c "python=$(PYTHON)" # # Location of the QMTest program. From criswell at cs.uiuc.edu Mon Aug 2 17:29:51 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:29:51 -0500 Subject: [llvm-commits] CVS: llvm/test/QMTest/llvm.py Message-ID: <200408022229.RAA09630@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: llvm.py updated: 1.30 -> 1.31 --- Log message: Add support for using the prcontext python script instead of grep -C. --- Diffs of the changes: (+2 -1) Index: llvm/test/QMTest/llvm.py diff -u llvm/test/QMTest/llvm.py:1.30 llvm/test/QMTest/llvm.py:1.31 --- llvm/test/QMTest/llvm.py:1.30 Mon Aug 2 16:40:39 2004 +++ llvm/test/QMTest/llvm.py Mon Aug 2 17:29:41 2004 @@ -873,7 +873,8 @@ extractEnv = { 's': srcfile, 't': scriptfile + '.tmp', 'llvmgcc': context['llvmgcc'], - 'llvmgxx': context['llvmgxx'] } + 'llvmgxx': context['llvmgxx'], + 'prcontext': context['python'] + ' ' + srcroot + '/test/Scripts/prcontext.py'} try: self.extractScript (srcfile, scriptfile, extractEnv) except EnvironmentError: From criswell at cs.uiuc.edu Mon Aug 2 17:30:35 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:30:35 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll 2003-08-04-TrappingInstOkHoist.ll 2003-12-13-VolatilePromote.ll call_sink_const_function.ll call_sink_pure_function.ll sink_critical_edge.ll sink_inst.ll sink_load.ll sink_multiple.ll sink_multiple_exits.ll sink_only_some_exits.ll sink_phi_node_use.ll sink_trapping_inst.ll Message-ID: <200408022230.RAA09671@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: 2003-08-04-TrappingInstHoist.ll updated: 1.3 -> 1.4 2003-08-04-TrappingInstOkHoist.ll updated: 1.4 -> 1.5 2003-12-13-VolatilePromote.ll updated: 1.1 -> 1.2 call_sink_const_function.ll updated: 1.1 -> 1.2 call_sink_pure_function.ll updated: 1.1 -> 1.2 sink_critical_edge.ll updated: 1.1 -> 1.2 sink_inst.ll updated: 1.2 -> 1.3 sink_load.ll updated: 1.1 -> 1.2 sink_multiple.ll updated: 1.1 -> 1.2 sink_multiple_exits.ll updated: 1.2 -> 1.3 sink_only_some_exits.ll updated: 1.1 -> 1.2 sink_phi_node_use.ll updated: 1.1 -> 1.2 sink_trapping_inst.ll updated: 1.1 -> 1.2 --- Log message: Use the new prcontext script. --- Diffs of the changes: (+13 -13) Index: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll diff -u llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll:1.3 llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll:1.4 --- llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll:1.3 Tue Dec 9 10:49:12 2003 +++ llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstHoist.ll Mon Aug 2 17:30:25 2004 @@ -1,7 +1,7 @@ ; This testcase tests for a problem where LICM hoists ; potentially trapping instructions when they are not guaranteed to execute. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C2 "IfUnEqual" | grep div +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext "IfUnEqual" 2 | grep div %X = global int 0 declare void %foo() Index: llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll diff -u llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll:1.4 llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll:1.5 --- llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll:1.4 Thu Dec 11 15:06:43 2003 +++ llvm/test/Regression/Transforms/LICM/2003-08-04-TrappingInstOkHoist.ll Mon Aug 2 17:30:25 2004 @@ -1,7 +1,7 @@ ; This testcase tests to make sure a trapping instruction is hoisted when ; it is guaranteed to execute. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C2 "test" | grep div +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext "test" 2 | grep div %X = global int 0 declare void %foo(int) Index: llvm/test/Regression/Transforms/LICM/2003-12-13-VolatilePromote.ll diff -u llvm/test/Regression/Transforms/LICM/2003-12-13-VolatilePromote.ll:1.1 llvm/test/Regression/Transforms/LICM/2003-12-13-VolatilePromote.ll:1.2 --- llvm/test/Regression/Transforms/LICM/2003-12-13-VolatilePromote.ll:1.1 Sat Dec 13 22:46:07 2003 +++ llvm/test/Regression/Transforms/LICM/2003-12-13-VolatilePromote.ll Mon Aug 2 17:30:25 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 volatile | grep Loop +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext volatile 1 | grep Loop %X = global int 7 Index: llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll diff -u llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll:1.1 llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll:1.2 --- llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll:1.1 Sun Mar 14 22:10:08 2004 +++ llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll Mon Aug 2 17:30:25 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | grep -C1 sin | grep Out: +; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | %prcontext sin 1 | grep Out: declare double %sin(double) declare void %foo() Index: llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll diff -u llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll:1.1 llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll:1.2 --- llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll:1.1 Sun Mar 14 22:10:08 2004 +++ llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll Mon Aug 2 17:30:25 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | grep -C1 strlen | grep Out: +; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | %prcontext strlen 1 | grep Out: declare int %strlen(sbyte*) declare void %foo() Index: llvm/test/Regression/Transforms/LICM/sink_critical_edge.ll diff -u llvm/test/Regression/Transforms/LICM/sink_critical_edge.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_critical_edge.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_critical_edge.ll:1.1 Tue Dec 9 16:05:08 2003 +++ llvm/test/Regression/Transforms/LICM/sink_critical_edge.ll Mon Aug 2 17:30:25 2004 @@ -1,7 +1,7 @@ ; This testcase checks to make sure the sinker does not cause problems with ; critical edges. -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 add | grep Exit +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext add 1 | grep Exit implementation ; Functions: Index: llvm/test/Regression/Transforms/LICM/sink_inst.ll diff -u llvm/test/Regression/Transforms/LICM/sink_inst.ll:1.2 llvm/test/Regression/Transforms/LICM/sink_inst.ll:1.3 --- llvm/test/Regression/Transforms/LICM/sink_inst.ll:1.2 Tue Dec 9 14:50:20 2003 +++ llvm/test/Regression/Transforms/LICM/sink_inst.ll Mon Aug 2 17:30:25 2004 @@ -2,7 +2,7 @@ ; the instruction to the exit blocks instead of executing it on every ; iteration of the loop. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 mul | grep Out: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext mul 1 | grep Out: int %test(int %N) { Entry: Index: llvm/test/Regression/Transforms/LICM/sink_load.ll diff -u llvm/test/Regression/Transforms/LICM/sink_load.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_load.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_load.ll:1.1 Tue Dec 9 10:56:51 2003 +++ llvm/test/Regression/Transforms/LICM/sink_load.ll Mon Aug 2 17:30:25 2004 @@ -2,7 +2,7 @@ ; result of the load is only used outside of the loop, sink the load instead of ; hoisting it! ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 load | grep Out: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext load 1 | grep Out: %X = global int 5 Index: llvm/test/Regression/Transforms/LICM/sink_multiple.ll diff -u llvm/test/Regression/Transforms/LICM/sink_multiple.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_multiple.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_multiple.ll:1.1 Fri Dec 19 00:54:37 2003 +++ llvm/test/Regression/Transforms/LICM/sink_multiple.ll Mon Aug 2 17:30:25 2004 @@ -3,7 +3,7 @@ ; instructions from the loop. Instead they got hoisted, which is better than ; leaving them in the loop, but increases register pressure pointlessly. -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 getelementptr | grep Out: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext getelementptr 1 | grep Out: %Ty = type { int, int } %X = external global %Ty Index: llvm/test/Regression/Transforms/LICM/sink_multiple_exits.ll diff -u llvm/test/Regression/Transforms/LICM/sink_multiple_exits.ll:1.2 llvm/test/Regression/Transforms/LICM/sink_multiple_exits.ll:1.3 --- llvm/test/Regression/Transforms/LICM/sink_multiple_exits.ll:1.2 Tue Dec 9 15:45:23 2003 +++ llvm/test/Regression/Transforms/LICM/sink_multiple_exits.ll Mon Aug 2 17:30:25 2004 @@ -1,7 +1,7 @@ ; This testcase ensures that we can sink instructions from loops with ; multiple exits. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 mul | grep 'Out[12]:' +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext mul 1 | grep 'Out[12]:' int %test(int %N, bool %C) { Entry: Index: llvm/test/Regression/Transforms/LICM/sink_only_some_exits.ll diff -u llvm/test/Regression/Transforms/LICM/sink_only_some_exits.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_only_some_exits.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_only_some_exits.ll:1.1 Tue Dec 9 23:42:23 2003 +++ llvm/test/Regression/Transforms/LICM/sink_only_some_exits.ll Mon Aug 2 17:30:25 2004 @@ -2,7 +2,7 @@ ; some exits out of the loop, and that we can do so without breaking dominator ; info. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 add | grep exit2: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext add 1 | grep exit2: implementation ; Functions: Index: llvm/test/Regression/Transforms/LICM/sink_phi_node_use.ll diff -u llvm/test/Regression/Transforms/LICM/sink_phi_node_use.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_phi_node_use.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_phi_node_use.ll:1.1 Tue Dec 9 17:29:25 2003 +++ llvm/test/Regression/Transforms/LICM/sink_phi_node_use.ll Mon Aug 2 17:30:25 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 add | grep preheader.loopexit: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext add 1 | grep preheader.loopexit: implementation Index: llvm/test/Regression/Transforms/LICM/sink_trapping_inst.ll diff -u llvm/test/Regression/Transforms/LICM/sink_trapping_inst.ll:1.1 llvm/test/Regression/Transforms/LICM/sink_trapping_inst.ll:1.2 --- llvm/test/Regression/Transforms/LICM/sink_trapping_inst.ll:1.1 Tue Dec 9 10:56:51 2003 +++ llvm/test/Regression/Transforms/LICM/sink_trapping_inst.ll Mon Aug 2 17:30:25 2004 @@ -1,7 +1,7 @@ ; Potentially trapping instructions may be sunk as long as they are guaranteed ; to be executed. ; -; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -C1 div | grep Out: +; RUN: llvm-as < %s | opt -licm | llvm-dis | %prcontext div 1 | grep Out: int %test(int %N) { Entry: From criswell at cs.uiuc.edu Mon Aug 2 17:32:06 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:32:06 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll Message-ID: <200408022232.RAA09707@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstantMerge: 2003-10-28-MergeExternalConstants.ll updated: 1.2 -> 1.3 --- Log message: Use the new prcontext script. --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll diff -u llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll:1.2 llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll:1.3 --- llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll:1.2 Wed Nov 19 12:37:06 2003 +++ llvm/test/Regression/Transforms/ConstantMerge/2003-10-28-MergeExternalConstants.ll Mon Aug 2 17:31:56 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -constmerge | llvm-dis | grep -C2 foo | grep bar +; RUN: llvm-as < %s | opt -constmerge | llvm-dis | %prcontext foo 2 | grep bar %foo = constant int 6 %bar = constant int 6 From criswell at cs.uiuc.edu Mon Aug 2 17:32:07 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:32:07 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll Message-ID: <200408022232.RAA09714@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IndVarsSimplify: 2003-09-23-NotAtTop.ll updated: 1.3 -> 1.4 --- Log message: Use the new prcontext script. --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll diff -u llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll:1.3 llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll:1.4 --- llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll:1.3 Fri Apr 2 14:25:26 2004 +++ llvm/test/Regression/Transforms/IndVarsSimplify/2003-09-23-NotAtTop.ll Mon Aug 2 17:31:57 2004 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep -C1 Loop: | grep %indvar +; RUN: llvm-as < %s | opt -indvars | llvm-dis | %prcontext Loop: 1 | grep %indvar ; The indvar simplification code should ensure that the first PHI in the block ; is the canonical one! From criswell at cs.uiuc.edu Mon Aug 2 17:32:08 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon, 2 Aug 2004 17:32:08 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Inline/alloca_test.ll Message-ID: <200408022232.RAA09721@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Inline: alloca_test.ll updated: 1.3 -> 1.4 --- Log message: Use the new prcontext script. --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/Inline/alloca_test.ll diff -u llvm/test/Regression/Transforms/Inline/alloca_test.ll:1.3 llvm/test/Regression/Transforms/Inline/alloca_test.ll:1.4 --- llvm/test/Regression/Transforms/Inline/alloca_test.ll:1.3 Tue Dec 9 10:48:52 2003 +++ llvm/test/Regression/Transforms/Inline/alloca_test.ll Mon Aug 2 17:31:58 2004 @@ -1,7 +1,7 @@ ; This test ensures that alloca instructions in the entry block for an inlined ; function are moved to the top of the function they are inlined into. ; -; RUN: llvm-as < %s | opt -inline | llvm-dis | grep -C1 alloca | grep Entry: +; RUN: llvm-as < %s | opt -inline | llvm-dis | %prcontext alloca 1 | grep Entry: int %func(int %i) { %X = alloca int From lattner at cs.uiuc.edu Mon Aug 2 19:17:31 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 19:17:31 -0500 Subject: [llvm-commits] CVS: llvm/docs/Stacker.html Message-ID: <200408030017.TAA19231@apoc.cs.uiuc.edu> Changes in directory llvm/docs: Stacker.html updated: 1.15 -> 1.16 --- Log message: Simplify the first example, as the LLVM IR interfaces have evolved. Other examples in this doc could also be simplified dramatically in similar ways. --- Diffs of the changes: (+14 -17) Index: llvm/docs/Stacker.html diff -u llvm/docs/Stacker.html:1.15 llvm/docs/Stacker.html:1.16 --- llvm/docs/Stacker.html:1.15 Thu Jun 3 18:47:34 2004 +++ llvm/docs/Stacker.html Mon Aug 2 19:17:21 2004 @@ -131,31 +131,28 @@ classes were derived from the Value class. The full power of that simple design only became fully understood once I started constructing executable expressions for Stacker.

    +

    This really makes your programming go faster. Think about compiling code for the following C/C++ expression: (a|b)*((x+1)/(y+1)). Assuming the values are on the stack in the order a, b, x, y, this could be expressed in stacker as: 1 + SWAP 1 + / ROT2 OR *. -You could write a function using LLVM that computes this expression like this:

    -
    
    +You could write a function using LLVM that computes this expression like 
    +this: 

    + +
     Value* 
     expression(BasicBlock* bb, Value* a, Value* b, Value* x, Value* y )
     {
    -    Instruction* tail = bb->getTerminator();
    -    ConstantSInt* one = ConstantSInt::get( Type::IntTy, 1);
    -    BinaryOperator* or1 = 
    -	BinaryOperator::create( Instruction::Or, a, b, "", tail );
    -    BinaryOperator* add1 = 
    -	BinaryOperator::create( Instruction::Add, x, one, "", tail );
    -    BinaryOperator* add2 =
    -	BinaryOperator::create( Instruction::Add, y, one, "", tail );
    -    BinaryOperator* div1 = 
    -	BinaryOperator::create( Instruction::Div, add1, add2, "", tail);
    -    BinaryOperator* mult1 = 
    -	BinaryOperator::create( Instruction::Mul, or1, div1, "", tail );
    -
    +    ConstantSInt* one = ConstantSInt::get(Type::IntTy, 1);
    +    BinaryOperator* or1 = BinaryOperator::createOr(a, b, "", bb);
    +    BinaryOperator* add1 = BinaryOperator::createAdd(x, one, "", bb);
    +    BinaryOperator* add2 = BinaryOperator::createAdd(y, one, "", bb);
    +    BinaryOperator* div1 = BinaryOperator::createDiv(add1, add2, "", bb);
    +    BinaryOperator* mult1 = BinaryOperator::createMul(or1, div1, "", bb);
         return mult1;
     }
    -
    +
    +

    "Okay, big deal," you say? It is a big deal. Here's why. Note that I didn't have to tell this function which kinds of Values are being passed in. They could be Instructions, Constants, GlobalVariables, or @@ -1410,7 +1407,7 @@ Reid Spencer
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/03 23:47:34 $ + Last modified: $Date: 2004/08/03 00:17:21 $ From lattner at cs.uiuc.edu Mon Aug 2 23:15:13 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 23:15:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/Notes.txt Message-ID: <200408030415.XAA19580@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: Notes.txt added (r1.1) --- Log message: Move this file out of the top-level docs directory --- Diffs of the changes: (+197 -0) Index: llvm/lib/Target/SparcV9/RegAlloc/Notes.txt diff -c /dev/null llvm/lib/Target/SparcV9/RegAlloc/Notes.txt:1.1 *** /dev/null Mon Aug 2 23:15:13 2004 --- llvm/lib/Target/SparcV9/RegAlloc/Notes.txt Mon Aug 2 23:15:02 2004 *************** *** 0 **** --- 1,197 ---- + =================== + Register Allocation + =================== + + + 1. Introduction + =============== + + Purpose: This file contains implementation information about register + allocation. + Author : Ruchira Sasanka + Date : Dec 8, 2001 + + + 2. Entry Point + ============== + class PhyRegAlloc (PhyRegAlloc.h) is the main class for the register + allocation. PhyRegAlloc::allocateRegisters() starts the register allocation + and contains the major steps for register allocation. + + 2. Usage + ======== + Register allocation must be done as: + + MethodLiveVarInfo LVI(*MethodI ); // compute LV info + LVI.analyze(); + + TargetMachine &target = .... // target description + + + PhyRegAlloc PRA(*MethodI, target, &LVI); // allocate regs + PRA.allocateRegisters(); + + + 4. Input and Preconditions + ========================== + Register allocation is done using machine instructions. The constructor + to the class takes a pointer to a method, a target machine description and + a live variable information for the method. + + The preconditions are: + + 1. Instruction selection is complete (i.e., machine instructions are + generated) for the method before the live variable analysis + + 2. Phi elimination is complete. + + + 5. Assumptions + ============== + + All variables (llvm Values) are defined before they are used. However, a + constant may not be defined in the machine instruction stream if it can be + used as an immediate value within a machine instruction. However, register + allocation does not have to worry about immediate constants since they + do not require registers. + + Since an llvm Value has a list of uses associated, it is sufficient to + record only the defs in a Live Range. + + + + + 6. Overall Design + ================= + There are sperate reigster classes - e.g., Int, Float, + IntConditionCode, FloatConditionCode register classes for Sparc. + + Registerallocation consists of the following main steps: + + 1. Construct Live-ranges & Suggest colors (machine specific) if required + 2. Create Interference graphs + 3. Coalescing live ranges + 4. Color all live ranges in each RegClass using graph coloring algo + 5. Insert additional (machine specific) code for calls/returns/incoming args + 6. Update instruction stream and insert spill code + + All the above methods are called from PhyRegAlloc::allocateRegisters(). + + All steps above except step 5 and suggesting colors in step 1 are indepenedent + of a particular target architecture. Targer independent code is availble in + ../lib/CodeGen/RegAlloc. Target specific code for Sparc is available in + ../lib/Target/Sparc. + + + 6.1. Construct Live-ranges & Suggest colors (machine specific) if required + -------------------------------------------------------------------------- + Live range construction is done using machine instructions. Since there must + be at least one definition for each variable in the machine instruction, we + consider only definitions in creating live ranges. After live range + construction is complete, there is a live range for all variables defined in + the instruction stream. Note however that, live ranges are not constructed for + constants which are not defined in the instruction stream. + + A LiveRange is a set of Values (only defs) in that live range. Live range + construction is done in combination for all register classes. All the live + ranges for a method are entered to a LiveRangeMap which can be accessed using + any Value in the LiveRange. + + After live ranges have been constructed, we call machine specific code to + suggest colors for speical live ranges. For instance, incoming args, call args, + return values must be placed in special registers for most architectures. By + suggesting colors for such special live ranges before we do the actual register + allocation using graph coloring, the graph coloring can try its best to assign + the required color for such special live ranges. This will reduce unnecessary + copy instructions needed to move values to special registers. However, there + is no guarantee that a live range will receive its suggested color. If the + live range does not receive the suggested color, we have to insert explicit + copy instructions to move the value into requred registers and its done in + step 5 above. + + See LiveRange.h, LiveRangeInfo.h (and LiveRange.cpp, LiveRangeInfo.cpp) for + algorithms and details. See SparcRegInfo.cpp for suggesting colors for + incoming/call arguments and return values. + + + 6.2. Create Interference graphs + ------------------------------- + Once live ranges are constructed, we can build interference graphs for each + register class. Though each register class must have a separate interference + graph, building all interference graphs is performed in one pass. Also, the + adjacency list for each live range is built in this phase. Consequently, each + register class has an interference graph (which is a bit matrix) and each + LiveRange has an adjacency list to record its neighbors. Live variable info + is used for finding the interferences. + + See IGNode.h, InterferenceGraph.h (and IGNode.h, InterferenceGraph.h) for + data structures and PhyRegAlloc::createIGNodeListsAndIGs() for the starting + point for interference graph construction. + + + 6.3. Coalescing live ranges + --------------------------- + We coalesce live ranges to reduce the number of live ranges. + + See LiveRangeInfo.h (and LiveRangeInfo.cpp). The entire algorithm for + coalesing is given in LiveRangeInfo::coalesceLRs(). + + + 6.4. Color all live ranges in each RegClass using graph coloring algo + --------------------------------------------------------------------- + Each register class is colored separately using the graph coloring algo. When + assigning colors, preference is given to live ranges with suggested colors + so that if such a live range receives a color (i.e., not spilled), then + we try to assign the color suggested for that live range. When this phase + is complete it is possible that some live ranges do not have colors (i.e., + those that must be spilled). + + + 6.5. Insert additional (machine specific) code for calls/returns/incoming args + ------------------------------------------------------------------------------ + This code is machine specific. Currently, the code for Sparc is implemented + in SparcRegInfo.cpp. This code is more complex because of the complex + requirements of assigning some values to special registers. When a special + value as an incoming argument receives a color through the graph coloring + alogorithm, we have to make sure that it received the correct color (for + instance the first incoming int argument must be colored to %i0 on Sparc). If + it didn't receive the correct color, we have to insert instruction to to move + the value to the required register. Also, this phase produces the caller + saving code. All adition code produced is kept separately until the last + phase (see 6.6) + + + 6.6. Update instruction stream and insert spill code + ----------------------------------------------------- + After we have assigned registers for all values and after we have produced + additional code to be inserted before some instructions, we update the + machine instruction stream. While we are updating the machine instruction + stream, if an instruction referes to a spilled value, we insert spill + instructions before/after that instruction. Also, we prepend/append additonal + instructions that have been produced for that instruction by the register + allocation (e.g., caller saving code) + + + 7. Furture work + =============== + If it is necessary to port the register allocator to another architecture + than Sparc, only the target specific code in ../lib/Target/Sparc needs to + be rewritten. Methods defined in class MachineRegInfo must be provided for + the new architecure. + + 7.1 Using ReservedColorList in RegClass + ---------------------------------------- + The register allocator allows reserving a set of registers - i.e. the reserved + registers are not used by the register allocator. Currently, there are no + reserved registers. It it is necessary to make some registers unavailable to + a particular method, this feature will become handy. To do that, the reserved + register list must be passed to the register allocator. See PhyRegAlloc.cpp + + + 7.2 %g registers on Sparc + ------------------------- + Currently, %g registers are not allocated on Sparc. If it is necessary to + allocate these %g registers, the enumeration of registers in SparcIntRegClass + in SparcRegClassInfo.h must be changed. %g registers can be easily added as + volatile registers just by moving them above in the eneumeration - see + SparcRegClassInfo.h From lattner at cs.uiuc.edu Mon Aug 2 23:15:42 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 2 Aug 2004 23:15:42 -0500 Subject: [llvm-commits] CVS: llvm/docs/RegisterAllocatorInfo.txt Message-ID: <200408030415.XAA19606@apoc.cs.uiuc.edu> Changes in directory llvm/docs: RegisterAllocatorInfo.txt (r1.4) removed --- Log message: Moved into SparcV9 directory --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Tue Aug 3 02:52:22 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue, 3 Aug 2004 02:52:22 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408030752.CAA17695@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.71 -> 1.72 --- Log message: When the types of static calls do not match, cast to the correct type. --- Diffs of the changes: (+4 -2) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.71 llvm-java/lib/Compiler/Compiler.cpp:1.72 --- llvm-java/lib/Compiler/Compiler.cpp:1.71 Wed Jul 28 05:10:27 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Tue Aug 3 02:52:11 2004 @@ -844,9 +844,11 @@ FunctionType* funcType = cast(getType(nameAndType->getDescriptor())); std::vector params(funcType->getNumParams(), NULL); - for (unsigned i = funcType->getNumParams(); i > 0; ) { + for (unsigned i = 0, e = funcType->getNumParams(); i != e; ++i) { Value* p = opStack_.top(); opStack_.pop(); - params[--i] = p; + const Type* paramTy = funcType->getParamType(i); + params[i] = p->getType() == paramTy ? p : + new CastInst(p, paramTy, TMP, getBBAt(bcI)); } Function* function = From alkis at cs.uiuc.edu Tue Aug 3 07:10:43 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue, 3 Aug 2004 07:10:43 -0500 Subject: [llvm-commits] CVS: llvm-java/tools/class2llvm/class2llvm.cpp Message-ID: <200408031210.HAA28624@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/class2llvm: class2llvm.cpp updated: 1.11 -> 1.12 --- Log message: When developing a frontend the verifier is your friend :-) --- Diffs of the changes: (+2 -0) Index: llvm-java/tools/class2llvm/class2llvm.cpp diff -u llvm-java/tools/class2llvm/class2llvm.cpp:1.11 llvm-java/tools/class2llvm/class2llvm.cpp:1.12 --- llvm-java/tools/class2llvm/class2llvm.cpp:1.11 Tue Jul 13 18:21:34 2004 +++ llvm-java/tools/class2llvm/class2llvm.cpp Tue Aug 3 07:10:33 2004 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ compiler.compile(module, InputClass); PassManager passes; + passes.add(createVerifierPass()); passes.add(new WriteBytecodePass(&std::cout)); passes.run(module); } From alkis at cs.uiuc.edu Tue Aug 3 07:14:46 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue, 3 Aug 2004 07:14:46 -0500 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/Makefile.singlesrc Message-ID: <200408031214.HAA28723@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource: Makefile.singlesrc updated: 1.2 -> 1.3 --- Log message: Make rule append to classpath so that it can find classes in the Output directory. --- Diffs of the changes: (+2 -1) Index: llvm-java/test/Programs/SingleSource/Makefile.singlesrc diff -u llvm-java/test/Programs/SingleSource/Makefile.singlesrc:1.2 llvm-java/test/Programs/SingleSource/Makefile.singlesrc:1.3 --- llvm-java/test/Programs/SingleSource/Makefile.singlesrc:1.2 Sat Jul 24 15:05:42 2004 +++ llvm-java/test/Programs/SingleSource/Makefile.singlesrc Tue Aug 3 07:14:36 2004 @@ -9,6 +9,7 @@ # rule to build raw bytecode from a classfile %.raw.bc: %.class $(CLASS2LLVM) - $(CLASS2LLVM) $(subst /,.,$*) | $(LOPT) -mem2reg > $@ + @$(ECHO) Compiling $< + $(CLASS2LLVM) -cp $(CLASSPATH):Output $(subst /,.,$(*F)) | $(LOPT) -mem2reg > $@ include $(LEVEL)/test/Makefile.test From criswell at cs.uiuc.edu Tue Aug 3 10:48:32 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Aug 2004 10:48:32 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.tests Message-ID: <200408031548.KAA03689@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.tests updated: 1.1 -> 1.2 --- Log message: Added the $LLVMGCCDIR/bytecode-libs directory to the list of places to look for libraries. This should allow the test suite to work regardless of the user's LLVM_LIB_SEARCH_PATH setting. --- Diffs of the changes: (+2 -1) Index: llvm/test/Programs/Makefile.tests diff -u llvm/test/Programs/Makefile.tests:1.1 llvm/test/Programs/Makefile.tests:1.2 --- llvm/test/Programs/Makefile.tests:1.1 Mon Jun 21 21:28:05 2004 +++ llvm/test/Programs/Makefile.tests Tue Aug 3 10:48:21 2004 @@ -41,7 +41,8 @@ LLI = $(LLVMTOOLCURRENT)/lli$(EXEEXT) LLC = $(LLVMTOOLCURRENT)/llc$(EXEEXT) LGCCAS = $(LLVMTOOLCURRENT)/gccas$(EXEEXT) -LGCCLD = $(LGCCLDPROG) -L$(LLVMGCCLIBDIR) -L$(LLVMGCCDIR)/lib +LGCCLD = $(LGCCLDPROG) -L$(LLVMGCCLIBDIR) -L$(LLVMGCCDIR)/lib \ + -L$(LLVMGCCDIR)/bytecode-libs LDIS = $(LLVMTOOLCURRENT)/llvm-dis$(EXEEXT) LOPT = $(LLVMTOOLCURRENT)/opt$(EXEEXT) LLINK = $(LLVMTOOLCURRENT)/llvm-link$(EXEEXT) From gaeke at cs.uiuc.edu Tue Aug 3 14:04:28 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 3 Aug 2004 14:04:28 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408031904.OAA06582@seraph.cs.uiuc.edu> Mail::Send=HASH(0x12a6c0) From gaeke at cs.uiuc.edu Tue Aug 3 14:06:22 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 3 Aug 2004 14:06:22 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408031906.OAA06681@seraph.cs.uiuc.edu> Mail::Send=HASH(0x12a6d8) From gaeke at cs.uiuc.edu Tue Aug 3 14:07:33 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 3 Aug 2004 14:07:33 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408031907.OAA06706@seraph.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.18 -> 1.19 Responsible party: gaeke --- Log message: Testing... One more time... --- Diffs of the changes: (+1 -1) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.18 llvm/CREDITS.TXT:1.19 --- llvm/CREDITS.TXT:1.18 Tue Aug 3 14:06:08 2004 +++ llvm/CREDITS.TXT Tue Aug 3 14:07:20 2004 @@ -38,7 +38,7 @@ E: gaeke at uiuc.edu W: http://www.students.uiuc.edu/~gaeke/ D: Portions of X86 static and JIT compilers. -D: Dynamic trace optimizer +D: Dynamic trace optimizer D: FreeBSD/X86 compatibility fixes, the llvm-nm tool N: Chris Lattner From llvm at cs.uiuc.edu Tue Aug 3 14:20:28 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue, 3 Aug 2004 14:20:28 -0500 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200408031920.OAA31344@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.20 -> 1.21 Responsible party: reid --- Log message: Properly wrap some lines. --- Diffs of the changes: (+16 -18) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.20 llvm/docs/BytecodeFormat.html:1.21 --- llvm/docs/BytecodeFormat.html:1.20 Wed Jul 28 19:13:04 2004 +++ llvm/docs/BytecodeFormat.html Tue Aug 3 14:20:18 2004 @@ -238,42 +238,40 @@ uint32_vbr - A 32-bit unsigned integer that occupies from -one to five bytes using variable bit rate encoding. + A 32-bit unsigned integer that occupies from one to + five bytes using variable bit rate encoding. uint64_vbr - A 64-bit unsigned integer that occupies from -one to ten bytes using variable bit rate encoding. + A 64-bit unsigned integer that occupies from one to ten + bytes using variable bit rate encoding. int64_vbr - A 64-bit signed integer that occupies from -one to ten bytes using the signed variable bit rate encoding. + A 64-bit signed integer that occupies from one to ten + bytes using the signed variable bit rate encoding. char - A single unsigned character encoded into one -byte + A single unsigned character encoded into one byte bit(n-m) - A set of bit within some larger integer -field. The values of n and m specify the -inclusive range of bits that define the subfield. The value for m -may be omitted if its the same as n. + A set of bit within some larger integer field. The values + of n and m specify the inclusive range of bits + that define the subfield. The value for m may be omitted if + its the same as n. float - A floating -point value encoded as a 32-bit IEEE value written in little-endian -form.
    + A floating point value encoded + as a 32-bit IEEE value written in little-endian form.
    double - A floating -point value encoded as a64-bit IEEE value written in little-endian form + A floating point value encoded + as a64-bit IEEE value written in little-endian form string @@ -1629,7 +1627,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2004/07/29 00:13:04 $ +Last modified: $Date: 2004/08/03 19:20:18 $ From criswell at cs.uiuc.edu Tue Aug 3 14:45:04 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Aug 2004 14:45:04 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp Message-ID: <200408031945.OAA00684@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++: echo.cpp updated: 1.2 -> 1.3 Responsible party: criswell --- Log message: Hardcoded the value of "any interface value" to be 127.0.0.1, in network byte order. This gets around htonl() being implemented in in-line asm in system header files, although it makes the assumption that the loopback interface is 127.0.0.1. In my experience, that's a pretty good bet on any UNIX platform. --- Diffs of the changes: (+9 -1) Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.2 llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.3 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.2 Tue Jun 15 15:48:16 2004 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp Tue Aug 3 14:44:53 2004 @@ -1,5 +1,5 @@ // -*- mode: c++ -*- -// $Id: echo.cpp,v 1.2 2004/06/15 20:48:16 lattner Exp $ +// $Id: echo.cpp,v 1.3 2004/08/03 19:44:53 criswell Exp $ // http://www.bagley.org/~doug/shootout/ #include @@ -33,7 +33,11 @@ sysabort("server/setsockopt"); memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; +#if 0 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +#else + sin.sin_addr.s_addr = 0x0100007f; +#endif sin.sin_port = 0; if (bind(ss, (sockaddr *)&sin, sizeof(sin)) == -1) sysabort("server/bind"); @@ -59,7 +63,11 @@ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) sysabort("client/socket"); sin.sin_family = AF_INET; +#if 0 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +#else + sin.sin_addr.s_addr = 0x0100007f; +#endif sin.sin_port = port; if (connect(sock, (sockaddr *)&sin, sizeof(sin)) == -1) sysabort("client/connect"); From gaeke at cs.uiuc.edu Tue Aug 3 15:03:05 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 3 Aug 2004 15:03:05 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408032003.PAA12847@seraph.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.22 -> 1.23 --- Log message: Let's try it again. --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Tue Aug 3 15:14:16 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue, 3 Aug 2004 15:14:16 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408032014.PAA12921@seraph.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.23 -> 1.24 --- Log message: Testing the commit-diffs script again. --- Diffs of the changes: (+0 -0) From reid at x10sys.com Tue Aug 3 15:21:16 2004 From: reid at x10sys.com (reid at x10sys.com) Date: Tue, 3 Aug 2004 15:21:16 -0500 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200408032021.PAA19163@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.21 -> 1.22 --- Log message: Fix line lengths. --- Diffs of the changes: (+5 -3) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.21 llvm/docs/BytecodeFormat.html:1.22 --- llvm/docs/BytecodeFormat.html:1.21 Tue Aug 3 14:20:18 2004 +++ llvm/docs/BytecodeFormat.html Tue Aug 3 15:21:05 2004 @@ -4,10 +4,12 @@ LLVM Bytecode File Format @@ -1627,7 +1629,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2004/08/03 19:20:18 $ +Last modified: $Date: 2004/08/03 20:21:05 $ From reid at x10sys.com Tue Aug 3 15:34:06 2004 From: reid at x10sys.com (reid at x10sys.com) Date: Tue, 3 Aug 2004 15:34:06 -0500 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200408032034.PAA22170@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.22 -> 1.23 --- Log message: Fix some indentation (so brg can test commit script). --- Diffs of the changes: (+5 -5) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.22 llvm/docs/BytecodeFormat.html:1.23 --- llvm/docs/BytecodeFormat.html:1.22 Tue Aug 3 15:21:05 2004 +++ llvm/docs/BytecodeFormat.html Tue Aug 3 15:33:56 2004 @@ -121,10 +121,10 @@

    -

    To support cross-platform differences, the bytecode file is aligned -on certain boundaries. This means that a small amount of padding (at -most 3 bytes) will be added to ensure that the next entry is aligned to -a 32-bit boundary.

    +

    To support cross-platform differences, the bytecode file is aligned on + certain boundaries. This means that a small amount of padding (at most 3 + bytes) will be added to ensure that the next entry is aligned to a 32-bit + boundary.

    Variable Bit-Rate Encoding @@ -1629,7 +1629,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2004/08/03 20:21:05 $ +Last modified: $Date: 2004/08/03 20:33:56 $ From reid at x10sys.com Tue Aug 3 15:58:07 2004 From: reid at x10sys.com (reid at x10sys.com) Date: Tue, 3 Aug 2004 15:58:07 -0500 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200408032058.PAA25132@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.23 -> 1.24 --- Log message: Line length <= 80 cols. --- Diffs of the changes: (+3 -2) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.23 llvm/docs/BytecodeFormat.html:1.24 --- llvm/docs/BytecodeFormat.html:1.23 Tue Aug 3 15:33:56 2004 +++ llvm/docs/BytecodeFormat.html Tue Aug 3 15:57:56 2004 @@ -233,7 +233,8 @@ byte with the lowest file offset (little endian). - uint24_vbr + + uint24_vbr A 24-bit unsigned integer that occupies from one to four bytes using variable bit rate encoding. @@ -1629,7 +1630,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2004/08/03 20:33:56 $ +Last modified: $Date: 2004/08/03 20:57:56 $ From lattner at cs.uiuc.edu Tue Aug 3 18:41:41 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 18:41:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Reader.h Message-ID: <200408032341.SAA27589@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.120 -> 1.121 Reader.h updated: 1.9 -> 1.10 --- Log message: Do not do a linear std::find to reconstruct information we had, but later threw away. This speeds up by .bc reader by 30% in a profile build on 252.eon. --- Diffs of the changes: (+24 -29) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.120 llvm/lib/Bytecode/Reader/Reader.cpp:1.121 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.120 Mon Jul 26 21:34:49 2004 +++ llvm/lib/Bytecode/Reader/Reader.cpp Tue Aug 3 18:41:28 2004 @@ -26,7 +26,6 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "Support/StringExtras.h" #include - using namespace llvm; namespace { @@ -294,7 +293,7 @@ if (!CompactionTypes.empty()) { if (ID >= CompactionTypes.size()) error("Type ID out of range for compaction table!"); - return CompactionTypes[ID]; + return CompactionTypes[ID].first; } // Is it a module-level type? @@ -337,12 +336,11 @@ // Scan the compaction table for the type if needed. if (!CompactionTypes.empty()) { - std::vector::const_iterator I = - find(CompactionTypes.begin(), CompactionTypes.end(), Ty); + for (unsigned i = 0, e = CompactionTypes.size(); i != e; ++i) + if (CompactionTypes[i].first == Ty) + return Type::FirstDerivedTyID + i; - if (I == CompactionTypes.end()) - error("Couldn't find type specified in compaction table!"); - return Type::FirstDerivedTyID + (&*I - &CompactionTypes[0]); + error("Couldn't find type specified in compaction table!"); } // Check the function level types first... @@ -403,15 +401,10 @@ // By default, the global type id is the type id passed in unsigned GlobalTyID = type; - // If the type plane was compactified, figure out the global type ID - // by adding the derived type ids and the distance. - if (!CompactionTypes.empty() && type >= Type::FirstDerivedTyID) { - const Type *Ty = CompactionTypes[type-Type::FirstDerivedTyID]; - TypeListTy::iterator I = - find(ModuleTypes.begin(), ModuleTypes.end(), Ty); - assert(I != ModuleTypes.end()); - GlobalTyID = Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]); - } + // If the type plane was compactified, figure out the global type ID by + // adding the derived type ids and the distance. + if (!CompactionTypes.empty() && type >= Type::FirstDerivedTyID) + GlobalTyID = CompactionTypes[type-Type::FirstDerivedTyID].second; if (hasImplicitNull(GlobalTyID)) { if (Num == 0) @@ -1053,7 +1046,7 @@ if (read_typeid(TypeSlot)) error("Invalid type in compaction table: type type"); const Type *Typ = getGlobalTableType(TypeSlot); - CompactionTypes.push_back(Typ); + CompactionTypes.push_back(std::make_pair(Typ, TypeSlot)); if (Handler) Handler->handleCompactionTableType(i, TypeSlot, Typ); } } Index: llvm/lib/Bytecode/Reader/Reader.h diff -u llvm/lib/Bytecode/Reader/Reader.h:1.9 llvm/lib/Bytecode/Reader/Reader.h:1.10 --- llvm/lib/Bytecode/Reader/Reader.h:1.9 Sun Jul 25 16:32:51 2004 +++ llvm/lib/Bytecode/Reader/Reader.h Tue Aug 3 18:41:28 2004 @@ -193,7 +193,7 @@ void ParseFunctionBody(Function* Func); /// @brief Parse the type list portion of a compaction table - void BytecodeReader::ParseCompactionTypes( unsigned NumEntries ); + void ParseCompactionTypes(unsigned NumEntries); /// @brief Parse a compaction table void ParseCompactionTable(); @@ -243,12 +243,13 @@ BufPtr At; ///< Where we're currently parsing at /// Information about the module, extracted from the bytecode revision number. + /// unsigned char RevisionNum; // The rev # itself /// Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0) - /// Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo - /// block. This was fixed to be like all other blocks in 1.2 + /// Revision #0 had an explicit alignment of data only for the + /// ModuleGlobalInfo block. This was fixed to be like all other blocks in 1.2 bool hasInconsistentModuleGlobalInfo; /// Revision #0 also explicitly encoded zero values for primitive types like @@ -270,12 +271,12 @@ bool hasTypeDerivedFromValue; /// LLVM 1.2 and earlier encoded block headers as two uint (8 bytes), one for - /// the size and one for the type. This is a bit wasteful, especially for small - /// files where the 8 bytes per block is a large fraction of the total block - /// size. In LLVM 1.3, the block type and length are encoded into a single - /// uint32 by restricting the number of block types (limit 31) and the maximum - /// size of a block (limit 2^27-1=134,217,727). Note that the module block - /// still uses the 8-byte format so the maximum size of a file can be + /// the size and one for the type. This is a bit wasteful, especially for + /// small files where the 8 bytes per block is a large fraction of the total + /// block size. In LLVM 1.3, the block type and length are encoded into a + /// single uint32 by restricting the number of block types (limit 31) and the + /// maximum size of a block (limit 2^27-1=134,217,727). Note that the module + /// block still uses the 8-byte format so the maximum size of a file can be /// 2^32-1 bytes long. bool hasLongBlockHeaders; @@ -295,9 +296,10 @@ /// LLVM 1.2 and earlier encoded the file version as part of the module block /// but this information may be needed to - /// CompactionTable - If a compaction table is active in the current function, - /// this is the mapping that it contains. - std::vector CompactionTypes; + /// CompactionTypes - If a compaction table is active in the current function, + /// this is the mapping that it contains. We keep track of what resolved type + /// it is as well as what global type entry it is. + std::vector > CompactionTypes; /// @brief If a compaction table is active in the current function, /// this is the mapping that it contains. From lattner at cs.uiuc.edu Tue Aug 3 19:18:50 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 19:18:50 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/BytecodeHandler.h Message-ID: <200408040018.TAA32739@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: BytecodeHandler.h updated: 1.4 -> 1.5 --- Log message: The Type* is redundant with the TypeSlot --- Diffs of the changes: (+1 -2) Index: llvm/include/llvm/Bytecode/BytecodeHandler.h diff -u llvm/include/llvm/Bytecode/BytecodeHandler.h:1.4 llvm/include/llvm/Bytecode/BytecodeHandler.h:1.5 --- llvm/include/llvm/Bytecode/BytecodeHandler.h:1.4 Sat Jul 17 18:23:30 2004 +++ llvm/include/llvm/Bytecode/BytecodeHandler.h Tue Aug 3 19:18:37 2004 @@ -158,8 +158,7 @@ virtual void handleCompactionTableValue( unsigned i, ///< Index in the compaction table's type plane unsigned TypSlot, ///< The slot (plane) of the type of this value - unsigned ValSlot, ///< The global value slot of the value - const Type* ///< The resolved type of the value. + unsigned ValSlot ///< The global value slot of the value ) {} /// @brief Handle end of a compaction table From lattner at cs.uiuc.edu Tue Aug 3 19:19:34 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 19:19:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Analyzer.cpp Reader.cpp Reader.h Message-ID: <200408040019.TAA32754@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Analyzer.cpp updated: 1.11 -> 1.12 Reader.cpp updated: 1.121 -> 1.122 Reader.h updated: 1.10 -> 1.11 --- Log message: Make getGlobalTableValue not use getTypeSlot, this speeds up the bc reader by 5% on eon --- Diffs of the changes: (+34 -32) Index: llvm/lib/Bytecode/Reader/Analyzer.cpp diff -u llvm/lib/Bytecode/Reader/Analyzer.cpp:1.11 llvm/lib/Bytecode/Reader/Analyzer.cpp:1.12 --- llvm/lib/Bytecode/Reader/Analyzer.cpp:1.11 Sat Jul 17 19:10:36 2004 +++ llvm/lib/Bytecode/Reader/Analyzer.cpp Tue Aug 3 19:19:23 2004 @@ -218,14 +218,10 @@ << " is " << Ty->getDescription() << "\n"; } - virtual void handleCompactionTableValue( - unsigned i, - unsigned TypSlot, - unsigned ValSlot, - const Type* Ty ) { + virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot, + unsigned ValSlot) { dump << " Value: " << i << " TypSlot: " << TypSlot - << " ValSlot:" << ValSlot << " is " << Ty->getDescription() - << "\n"; + << " ValSlot:" << ValSlot << "\n"; } virtual void handleCompactionTableEnd() { Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.121 llvm/lib/Bytecode/Reader/Reader.cpp:1.122 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.121 Tue Aug 3 18:41:28 2004 +++ llvm/lib/Bytecode/Reader/Reader.cpp Tue Aug 3 19:19:23 2004 @@ -439,23 +439,31 @@ /// This is just like getValue, but when a compaction table is in use, it /// is ignored. Also, no forward references or other fancy features are /// supported. -Value* BytecodeReader::getGlobalTableValue(const Type *Ty, unsigned SlotNo) { - // FIXME: getTypeSlot is inefficient! - unsigned TyID = getGlobalTableTypeSlot(Ty); - - if (TyID != Type::LabelTyID) { - if (SlotNo == 0) - return Constant::getNullValue(Ty); - --SlotNo; +Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) { + if (SlotNo == 0) + return Constant::getNullValue(getType(TyID)); + + if (!CompactionTypes.empty() && TyID >= Type::FirstDerivedTyID) { + TyID -= Type::FirstDerivedTyID; + if (TyID >= CompactionTypes.size()) + error("Type ID out of range for compaction table!"); + TyID = CompactionTypes[TyID].second; } + --SlotNo; + if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0 || SlotNo >= ModuleValues[TyID]->size()) { - error("Corrupt compaction table entry!" - + utostr(TyID) + ", " + utostr(SlotNo) + ": " - + utostr(ModuleValues.size()) + ", " - + utohexstr(intptr_t((void*)ModuleValues[TyID])) + ", " - + utostr(ModuleValues[TyID]->size())); + if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0) + error("Corrupt compaction table entry!" + + utostr(TyID) + ", " + utostr(SlotNo) + ": " + + utostr(ModuleValues.size())); + else + error("Corrupt compaction table entry!" + + utostr(TyID) + ", " + utostr(SlotNo) + ": " + + utostr(ModuleValues.size()) + ", " + + utohexstr(intptr_t((void*)ModuleValues[TyID])) + ", " + + utostr(ModuleValues[TyID]->size())); } return ModuleValues[TyID]->getOperand(SlotNo); } @@ -1096,30 +1104,27 @@ if (isTypeType) { ParseCompactionTypes(NumEntries); } else { - // Make sure we have enough room for the plane + // Make sure we have enough room for the plane. if (Ty >= CompactionValues.size()) CompactionValues.resize(Ty+1); - // Make sure the plane is empty or we have some kind of error + // Make sure the plane is empty or we have some kind of error. if (!CompactionValues[Ty].empty()) error("Compaction table plane contains multiple entries!"); - // Notify handler about the plane + // Notify handler about the plane. if (Handler) Handler->handleCompactionTablePlane(Ty, NumEntries); - // Convert the type slot to a type - const Type *Typ = getType(Ty); - - // Push the implicit zero - CompactionValues[Ty].push_back(Constant::getNullValue(Typ)); + // Push the implicit zero. + CompactionValues[Ty].push_back(Constant::getNullValue(getType(Ty))); // Read in each of the entries, put them in the compaction table // and notify the handler that we have a new compaction table value. for (unsigned i = 0; i != NumEntries; ++i) { unsigned ValSlot = read_vbr_uint(); - Value *V = getGlobalTableValue(Typ, ValSlot); + Value *V = getGlobalTableValue(Ty, ValSlot); CompactionValues[Ty].push_back(V); - if (Handler) Handler->handleCompactionTableValue(i, Ty, ValSlot, Typ); + if (Handler) Handler->handleCompactionTableValue(i, Ty, ValSlot); } } } Index: llvm/lib/Bytecode/Reader/Reader.h diff -u llvm/lib/Bytecode/Reader/Reader.h:1.10 llvm/lib/Bytecode/Reader/Reader.h:1.11 --- llvm/lib/Bytecode/Reader/Reader.h:1.10 Tue Aug 3 18:41:28 2004 +++ llvm/lib/Bytecode/Reader/Reader.h Tue Aug 3 19:19:23 2004 @@ -395,8 +395,9 @@ /// @brief Get a value from its typeid and slot number Value* getValue(unsigned TypeID, unsigned num, bool Create = true); - /// @brief Get a value from its type and slot number, ignoring compaction tables. - Value *getGlobalTableValue(const Type *Ty, unsigned SlotNo); + /// @brief Get a value from its type and slot number, ignoring compaction + /// tables. + Value *getGlobalTableValue(unsigned TyID, unsigned SlotNo); /// @brief Get a basic block for current function BasicBlock *getBasicBlock(unsigned ID); From reid at x10sys.com Tue Aug 3 19:34:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Aug 2004 19:34:59 -0500 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200408040034.TAA27537@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.96 -> 1.97 --- Log message: Change the package identification to use one less level of quoting so that PACKAGE_VERSION = "1.3" instead of "[1.3]". Rebuild configure script. --- Diffs of the changes: (+1 -1) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.96 llvm/autoconf/configure.ac:1.97 --- llvm/autoconf/configure.ac:1.96 Fri Jul 23 10:40:57 2004 +++ llvm/autoconf/configure.ac Tue Aug 3 19:34:49 2004 @@ -1,5 +1,5 @@ dnl Initialize autoconf -AC_INIT([[[LLVM]]],[[[1.3]]],[llvmbugs at cs.uiuc.edu]) +AC_INIT([[LLVM]],[[1.3]],[llvmbugs at cs.uiuc.edu]) dnl Place all of the extra autoconf files into the config subdirectory AC_CONFIG_AUX_DIR([autoconf]) From reid at x10sys.com Tue Aug 3 19:34:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Aug 2004 19:34:59 -0500 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200408040034.TAA27536@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.100 -> 1.101 --- Log message: Change the package identification to use one less level of quoting so that PACKAGE_VERSION = "1.3" instead of "[1.3]". Rebuild configure script. --- Diffs of the changes: (+1952 -782) Index: llvm/configure diff -u llvm/configure:1.100 llvm/configure:1.101 --- llvm/configure:1.100 Fri Jul 23 10:40:53 2004 +++ llvm/configure Tue Aug 3 19:34:48 2004 @@ -1,11 +1,10 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for [LLVM] [1.3]. +# Generated by GNU Autoconf 2.59 for LLVM 1.3. # # Report bugs to . # -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## @@ -22,9 +21,10 @@ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi +DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false @@ -43,7 +43,7 @@ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do - if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var @@ -220,16 +220,17 @@ if mkdir -p . 2>/dev/null; then as_mkdir_p=: else + test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS @@ -420,10 +421,10 @@ : ${ac_max_here_lines=38} # Identity of this package. -PACKAGE_NAME='[LLVM]' -PACKAGE_TARNAME='--llvm--' -PACKAGE_VERSION='[1.3]' -PACKAGE_STRING='[LLVM] [1.3]' +PACKAGE_NAME='LLVM' +PACKAGE_TARNAME='-llvm-' +PACKAGE_VERSION='1.3' +PACKAGE_STRING='LLVM 1.3' PACKAGE_BUGREPORT='llvmbugs at cs.uiuc.edu' ac_subdirs_all="$ac_subdirs_all projects/${i}" @@ -824,7 +825,7 @@ # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir + localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in @@ -864,10 +865,10 @@ # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -954,7 +955,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures [LLVM] [1.3] to adapt to many kinds of systems. +\`configure' configures LLVM 1.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -979,9 +980,9 @@ cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -1016,7 +1017,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of [LLVM] [1.3]:";; + short | recursive ) echo "Configuration of LLVM 1.3:";; esac cat <<\_ACEOF @@ -1102,12 +1103,45 @@ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. @@ -1118,7 +1152,7 @@ echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then + test -f $ac_srcdir/configure.in; then echo $ac_configure --help else @@ -1131,11 +1165,10 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -[LLVM] configure [1.3] -generated by GNU Autoconf 2.57 +LLVM configure 1.3 +generated by GNU Autoconf 2.59 -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1146,8 +1179,8 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by [LLVM] $as_me [1.3], which was -generated by GNU Autoconf 2.57. Invocation command line was +It was created by LLVM $as_me 1.3, which was +generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1224,19 +1257,19 @@ 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. + ac_must_keep_next=false # Got value, back to normal. else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. @@ -1270,12 +1303,12 @@ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } @@ -1304,7 +1337,7 @@ for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi @@ -1323,7 +1356,7 @@ echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 - rm -f core core.* *.core && + rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 @@ -1403,7 +1436,7 @@ # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" @@ -1420,13 +1453,13 @@ ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: + ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. @@ -1701,6 +1734,7 @@ # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 @@ -1717,6 +1751,7 @@ case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. @@ -1724,20 +1759,20 @@ # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi done done ;; @@ -2022,7 +2057,6 @@ (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2042,8 +2076,8 @@ # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -echo "$as_me:$LINENO: checking for C++ compiler default output" >&5 -echo $ECHO_N "checking for C++ compiler default output... $ECHO_C" >&6 +echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 +echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 @@ -2063,23 +2097,23 @@ test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; + ;; conftest.$ac_ext ) - # This is the source file. - ;; + # This is the source file. + ;; [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; + # We found the default executable, but exeext='' is most + # certainly right. + break;; *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; * ) - break;; + break;; esac done else @@ -2153,8 +2187,8 @@ case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; + export ac_cv_exeext + break;; * ) break;; esac done @@ -2179,7 +2213,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2230,7 +2263,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2250,11 +2282,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2267,7 +2309,7 @@ ac_compiler_gnu=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi @@ -2283,7 +2325,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2300,11 +2341,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2317,7 +2368,7 @@ ac_cv_prog_cxx_g=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 @@ -2337,8 +2388,7 @@ fi fi for ac_declaration in \ - ''\ - '#include ' \ + '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -2346,14 +2396,13 @@ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include $ac_declaration +#include int main () { @@ -2364,11 +2413,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2381,9 +2440,8 @@ continue fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2400,11 +2458,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2416,7 +2484,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then @@ -2555,7 +2623,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2575,11 +2642,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2592,7 +2669,7 @@ ac_compiler_gnu=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi @@ -2608,7 +2685,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2625,11 +2701,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2642,7 +2728,7 @@ ac_cv_prog_cc_g=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 @@ -2669,7 +2755,6 @@ ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2697,6 +2782,16 @@ va_end (v); return s; } + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -2723,11 +2818,21 @@ CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2740,7 +2845,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext +rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC @@ -2768,19 +2873,28 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - ''\ - '#include ' \ + '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -2788,14 +2902,13 @@ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include $ac_declaration +#include int main () { @@ -2806,11 +2919,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2823,9 +2946,8 @@ continue fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2842,11 +2964,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2858,7 +2990,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then @@ -2872,7 +3004,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2907,7 +3039,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2918,7 +3049,7 @@ #else # include #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -2930,6 +3061,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -2950,7 +3082,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2968,6 +3099,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -3014,7 +3146,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3025,7 +3156,7 @@ #else # include #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -3037,6 +3168,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -3057,7 +3189,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3075,6 +3206,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -3225,7 +3357,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-lfl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3249,11 +3380,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3266,7 +3407,8 @@ ac_cv_lib_fl_yywrap=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 @@ -3282,7 +3424,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ll $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3306,11 +3447,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3323,7 +3474,8 @@ ac_cv_lib_l_yywrap=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 @@ -3385,11 +3537,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3401,7 +3563,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS rm -f "${LEX_OUTPUT_ROOT}.c" @@ -4056,7 +4219,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4059 "configure"' > conftest.$ac_ext + echo '#line 4222 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4153,7 +4316,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4170,11 +4332,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4187,7 +4359,8 @@ lt_cv_cc_needs_belf=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4215,7 +4388,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4236,11 +4408,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4253,12 +4435,11 @@ ac_cv_header_stdc=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4280,7 +4461,6 @@ if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4305,7 +4485,6 @@ : else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4317,9 +4496,9 @@ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif @@ -4330,7 +4509,7 @@ int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) + || toupper (i) != TOUPPER (i)) exit(2); exit (0); } @@ -4355,7 +4534,7 @@ ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi @@ -4380,7 +4559,7 @@ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h + inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 @@ -4389,7 +4568,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4401,11 +4579,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4418,7 +4606,7 @@ eval "$as_ac_Header=no" fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 @@ -4449,7 +4637,6 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4460,11 +4647,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4477,7 +4674,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -4485,7 +4682,6 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4503,6 +4699,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -4522,33 +4719,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -4559,7 +4755,7 @@ if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - eval "$as_ac_Header=$ac_header_preproc" + eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 @@ -4598,7 +4794,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4609,7 +4804,7 @@ #else # include #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -4621,6 +4816,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi @@ -4641,7 +4837,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4659,6 +4854,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi @@ -4705,7 +4901,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4716,7 +4911,7 @@ #else # include #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -4728,6 +4923,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi @@ -4748,7 +4944,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -4766,6 +4961,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi @@ -4810,7 +5006,7 @@ ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then - for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 @@ -4852,7 +5048,7 @@ fi if test -z "$F77"; then ac_ct_F77=$F77 - for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4897,7 +5093,7 @@ # Provide some information about the compiler. -echo "$as_me:4900:" \ +echo "$as_me:5096:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -4915,9 +5111,10 @@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } +rm -f a.out # If we don't use `.F' as extension, the preprocessor is not run on the -# input file. +# input file. (Note that this only needs to work for GNU compilers.) ac_save_ext=$ac_ext ac_ext=F echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 @@ -4935,11 +5132,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4952,14 +5159,13 @@ ac_compiler_gnu=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_f77_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 ac_ext=$ac_save_ext -G77=`test $ac_compiler_gnu = yes && echo yes` ac_test_FFLAGS=${FFLAGS+set} ac_save_FFLAGS=$FFLAGS FFLAGS= @@ -4976,11 +5182,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4993,7 +5209,7 @@ ac_cv_prog_f77_g=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 @@ -5001,18 +5217,20 @@ if test "$ac_test_FFLAGS" = set; then FFLAGS=$ac_save_FFLAGS elif test $ac_cv_prog_f77_g = yes; then - if test "$G77" = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-g -O2" else FFLAGS="-g" fi else - if test "$G77" = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-O2" else FFLAGS= fi fi + +G77=`test $ac_compiler_gnu = yes && echo yes` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -5878,6 +6096,10 @@ +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... lt_prog_compiler_no_builtin_flag= @@ -5902,11 +6124,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5905: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6127: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5909: \$? = $ac_status" >&5 + echo "$as_me:6131: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6134,11 +6356,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6137: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6359: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6141: \$? = $ac_status" >&5 + echo "$as_me:6363: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6201,11 +6423,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6204: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6426: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6208: \$? = $ac_status" >&5 + echo "$as_me:6430: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -6541,7 +6763,6 @@ allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -6558,11 +6779,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6579,7 +6810,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -6592,7 +6824,6 @@ else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -6609,11 +6840,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6630,7 +6871,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -7729,7 +7971,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -7753,11 +7994,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -7770,7 +8021,8 @@ ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -7794,21 +8046,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef shl_load + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -7839,11 +8098,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -7856,7 +8125,8 @@ ac_cv_func_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6 @@ -7871,7 +8141,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -7895,11 +8164,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -7912,7 +8191,8 @@ ac_cv_lib_dld_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 @@ -7926,21 +8206,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef dlopen + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -7971,11 +8258,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -7988,7 +8285,8 @@ ac_cv_func_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6 @@ -8003,7 +8301,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -8027,24 +8324,35 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -8060,7 +8368,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -8084,11 +8391,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -8101,7 +8418,8 @@ ac_cv_lib_svld_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 @@ -8117,7 +8435,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -8141,11 +8458,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -8158,7 +8485,8 @@ ac_cv_lib_dld_dld_link=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 @@ -8213,7 +8541,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -9364,11 +9691,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -9385,7 +9722,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -9399,7 +9737,6 @@ else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -9416,11 +9753,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -9437,7 +9784,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -10056,6 +10404,10 @@ GCC_CXX="$GXX" LD_CXX="$LD" +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... cat > conftest.$ac_ext <&5) + (eval echo "\"\$as_me:10798: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10450: \$? = $ac_status" >&5 + echo "$as_me:10802: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -10510,11 +10862,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10513: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10865: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10517: \$? = $ac_status" >&5 + echo "$as_me:10869: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11269,7 +11621,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -11293,11 +11644,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11310,7 +11671,8 @@ ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -11334,21 +11696,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef shl_load + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -11379,11 +11748,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11396,7 +11775,8 @@ ac_cv_func_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6 @@ -11411,7 +11791,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -11435,11 +11814,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11452,7 +11841,8 @@ ac_cv_lib_dld_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 @@ -11466,21 +11856,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef dlopen + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -11511,11 +11908,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11528,7 +11935,8 @@ ac_cv_func_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6 @@ -11543,7 +11951,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -11567,11 +11974,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11584,7 +12001,8 @@ ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -11600,7 +12018,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -11624,11 +12041,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11641,7 +12068,8 @@ ac_cv_lib_svld_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 @@ -11657,7 +12085,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -11681,11 +12108,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11698,7 +12135,8 @@ ac_cv_lib_dld_dld_link=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 @@ -11753,7 +12191,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:13114: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12680: \$? = $ac_status" >&5 + echo "$as_me:13118: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -12740,11 +13178,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12743: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13181: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12747: \$? = $ac_status" >&5 + echo "$as_me:13185: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13086,11 +13524,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -13107,7 +13555,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -13126,11 +13575,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -13147,7 +13606,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -14656,6 +15116,10 @@ # GCJ did not exist at the time GCC didn't implicitly link libc in. archive_cmds_need_lc_GCJ=no +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... lt_prog_compiler_no_builtin_flag_GCJ= @@ -14680,11 +15144,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14683: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15147: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14687: \$? = $ac_status" >&5 + echo "$as_me:15151: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14912,11 +15376,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14915: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15379: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14919: \$? = $ac_status" >&5 + echo "$as_me:15383: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14979,11 +15443,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14982: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15446: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14986: \$? = $ac_status" >&5 + echo "$as_me:15450: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15319,7 +15783,6 @@ allow_undefined_flag_GCJ='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -15336,11 +15799,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -15357,7 +15830,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -15370,7 +15844,6 @@ else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -15387,11 +15860,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -15408,7 +15891,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -16507,7 +16991,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -16531,11 +17014,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16548,7 +17041,8 @@ ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -16572,21 +17066,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef shl_load + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -16617,11 +17118,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16634,7 +17145,8 @@ ac_cv_func_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6 @@ -16649,7 +17161,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -16673,11 +17184,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16690,7 +17211,8 @@ ac_cv_lib_dld_shl_load=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 @@ -16704,21 +17226,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef dlopen + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -16749,11 +17278,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16766,7 +17305,8 @@ ac_cv_func_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6 @@ -16781,7 +17321,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -16805,11 +17344,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16822,7 +17371,8 @@ ac_cv_lib_dl_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 @@ -16838,7 +17388,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -16862,11 +17411,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16879,7 +17438,8 @@ ac_cv_lib_svld_dlopen=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 @@ -16895,7 +17455,6 @@ ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -16919,11 +17478,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -16936,7 +17505,8 @@ ac_cv_lib_dld_dld_link=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 @@ -16991,7 +17561,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18329,11 +18898,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18346,7 +18925,8 @@ ac_cv_lib_elf_elf_begin=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf_begin" >&5 @@ -18369,7 +18949,6 @@ ac_func_search_save_LIBS=$LIBS ac_cv_search_dlopen=no cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18393,11 +18972,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18409,12 +18998,12 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_dlopen" = no; then for ac_lib in dl; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18438,11 +19027,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18455,7 +19054,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS @@ -18483,7 +19083,6 @@ ac_func_search_save_LIBS=$LIBS ac_cv_search_mallinfo=no cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18507,11 +19106,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18523,12 +19132,12 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_mallinfo" = no; then for ac_lib in malloc; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18552,11 +19161,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18569,7 +19188,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS @@ -18594,7 +19214,6 @@ ac_func_search_save_LIBS=$LIBS ac_cv_search_pthread_mutex_lock=no cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18618,11 +19237,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18634,12 +19263,12 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_pthread_mutex_lock" = no; then for ac_lib in pthread; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18663,11 +19292,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18680,7 +19319,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS @@ -18702,7 +19342,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18723,11 +19362,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18740,12 +19389,11 @@ ac_cv_header_stdc=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18767,7 +19415,6 @@ if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18792,7 +19439,6 @@ : else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18804,9 +19450,9 @@ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif @@ -18817,7 +19463,7 @@ int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) + || toupper (i) != TOUPPER (i)) exit(2); exit (0); } @@ -18842,7 +19488,7 @@ ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi @@ -18862,7 +19508,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18889,11 +19534,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18906,7 +19561,7 @@ ac_cv_header_sys_wait_h=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 @@ -18946,7 +19601,6 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -18957,11 +19611,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -18974,7 +19638,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -18982,7 +19646,6 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19000,6 +19663,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -19019,33 +19683,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -19056,7 +19719,7 @@ if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - eval "$as_ac_Header=$ac_header_preproc" + eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 @@ -19085,7 +19748,6 @@ echo "$as_me:$LINENO: checking sys/types.h usability" >&5 echo $ECHO_N "checking sys/types.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19096,11 +19758,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19113,7 +19785,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -19121,7 +19793,6 @@ echo "$as_me:$LINENO: checking sys/types.h presence" >&5 echo $ECHO_N "checking sys/types.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19139,6 +19810,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -19158,33 +19830,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/types.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/types.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/types.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: sys/types.h: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: sys/types.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/types.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/types.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/types.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/types.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: sys/types.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/types.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/types.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/types.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/types.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/types.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/types.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/types.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/types.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/types.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/types.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -19222,7 +19893,6 @@ echo "$as_me:$LINENO: checking inttypes.h usability" >&5 echo $ECHO_N "checking inttypes.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19233,11 +19903,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19250,7 +19930,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -19258,7 +19938,6 @@ echo "$as_me:$LINENO: checking inttypes.h presence" >&5 echo $ECHO_N "checking inttypes.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19276,6 +19955,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -19295,33 +19975,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: inttypes.h: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: inttypes.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: inttypes.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: inttypes.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: inttypes.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: inttypes.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: inttypes.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: inttypes.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: inttypes.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: inttypes.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: inttypes.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -19359,7 +20038,6 @@ echo "$as_me:$LINENO: checking stdint.h usability" >&5 echo $ECHO_N "checking stdint.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19370,11 +20048,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19387,7 +20075,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -19395,7 +20083,6 @@ echo "$as_me:$LINENO: checking stdint.h presence" >&5 echo $ECHO_N "checking stdint.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19413,6 +20100,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -19432,33 +20120,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: stdint.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdint.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: stdint.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: stdint.h: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: stdint.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: stdint.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdint.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdint.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: stdint.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: stdint.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: stdint.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: stdint.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: stdint.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: stdint.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: stdint.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: stdint.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdint.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdint.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: stdint.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: stdint.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -19491,7 +20178,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19511,11 +20197,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19528,7 +20224,7 @@ ac_cv_type_pid_t=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6 @@ -19548,7 +20244,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19568,11 +20263,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19585,7 +20290,7 @@ ac_cv_type_size_t=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 @@ -19605,7 +20310,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19625,11 +20329,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19642,7 +20356,7 @@ ac_cv_type_int64_t=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_int64_t" >&5 echo "${ECHO_T}$ac_cv_type_int64_t" >&6 @@ -19665,7 +20379,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19685,11 +20398,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19702,7 +20425,7 @@ ac_cv_type_uint64_t=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 echo "${ECHO_T}$ac_cv_type_uint64_t" >&6 @@ -19725,7 +20448,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19746,11 +20468,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19763,7 +20495,7 @@ ac_cv_header_time=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 @@ -19781,7 +20513,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19800,11 +20531,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19817,7 +20558,7 @@ ac_cv_struct_tm=sys/time.h fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 echo "${ECHO_T}$ac_cv_struct_tm" >&6 @@ -19849,7 +20590,6 @@ { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19896,7 +20636,7 @@ ( exit $ac_status ) ac_c_printf_a=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -19922,7 +20662,6 @@ else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19944,11 +20683,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19956,7 +20705,6 @@ (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -19978,11 +20726,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -19995,7 +20753,7 @@ ac_cv_c_bigendian=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -20005,7 +20763,6 @@ # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20027,11 +20784,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20053,10 +20820,9 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20095,10 +20861,10 @@ ( exit $ac_status ) ac_cv_c_bigendian=yes fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 @@ -20132,7 +20898,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20149,11 +20914,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20166,7 +20941,7 @@ ac_cv_cxx_namespaces=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20200,7 +20975,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20220,11 +20994,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20237,7 +21021,7 @@ ac_cv_cxx_have_std_ext_hash_map=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20268,7 +21052,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20288,11 +21071,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20305,7 +21098,7 @@ ac_cv_cxx_have_gnu_ext_hash_map=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20336,7 +21129,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20353,11 +21145,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20370,7 +21172,7 @@ ac_cv_cxx_have_global_hash_map=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20401,7 +21203,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20421,11 +21222,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20438,7 +21249,7 @@ ac_cv_cxx_have_std_ext_hash_set=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20469,7 +21280,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20489,11 +21299,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20506,7 +21326,7 @@ ac_cv_cxx_have_gnu_ext_hash_set=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20537,7 +21357,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20554,11 +21373,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20571,7 +21400,7 @@ ac_cv_cxx_have_global_hash_set=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20602,7 +21431,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20622,11 +21450,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20639,7 +21477,7 @@ ac_cv_cxx_have_std_iterator=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20671,7 +21509,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20691,11 +21528,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20708,7 +21555,7 @@ ac_cv_cxx_have_bi_iterator=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20740,7 +21587,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20760,11 +21606,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20777,7 +21633,7 @@ ac_cv_cxx_have_fwd_iterator=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20808,7 +21664,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20819,11 +21674,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20836,7 +21701,7 @@ ac_cv_func_isnan_in_math_h=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20866,7 +21731,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20877,11 +21741,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20894,7 +21768,7 @@ ac_cv_func_isnan_in_cmath=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20924,7 +21798,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20935,11 +21808,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -20952,7 +21835,7 @@ ac_cv_func_std_isnan_in_cmath=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20984,7 +21867,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -20995,11 +21877,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21012,7 +21904,7 @@ ac_cv_func_isinf_in_math_h=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -21042,7 +21934,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21053,11 +21944,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21070,7 +21971,7 @@ ac_cv_func_isinf_in_cmath=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -21100,7 +22001,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21111,11 +22011,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21128,7 +22038,7 @@ ac_cv_func_std_isinf_in_cmath=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -21158,7 +22068,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21169,11 +22078,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21186,7 +22105,7 @@ ac_cv_func_finite_in_ieeefp_h=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -21214,7 +22133,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21231,11 +22149,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21248,7 +22176,8 @@ ac_cv_working_alloca_h=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 @@ -21266,7 +22195,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21303,11 +22231,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21320,7 +22258,8 @@ ac_cv_func_alloca_works=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 @@ -21350,7 +22289,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21383,21 +22321,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef $ac_func + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -21428,11 +22373,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21445,7 +22400,8 @@ eval "$as_ac_var=no" fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 @@ -21470,7 +22426,6 @@ ac_cv_c_stack_direction=0 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21516,7 +22471,7 @@ ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 @@ -21547,7 +22502,6 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21558,11 +22512,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21575,7 +22539,7 @@ ac_header_compiler=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 @@ -21583,7 +22547,6 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21601,6 +22564,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -21620,33 +22584,32 @@ echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - ( - cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes ;; - no:yes ) + no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX -## ------------------------------------ ## -## Report this to bug-autoconf at gnu.org. ## -## ------------------------------------ ## +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 @@ -21657,7 +22620,7 @@ if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - eval "$as_ac_Header=$ac_header_preproc" + eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 @@ -21682,21 +22645,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef $ac_func + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -21727,11 +22697,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -21744,7 +22724,8 @@ eval "$as_ac_var=no" fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 @@ -21765,7 +22746,6 @@ ac_cv_func_mmap_fixed_mapped=no else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -21873,9 +22853,9 @@ data2 = (char *) malloc (2 * pagesize); if (!data2) exit (1); - data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED, fd, 0L)) + MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit (1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) @@ -21918,7 +22898,7 @@ ( exit $ac_status ) ac_cv_func_mmap_fixed_mapped=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 @@ -21958,7 +22938,6 @@ { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -22001,7 +22980,7 @@ ( exit $ac_status ) ac_cv_func_mmap_file=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -22042,7 +23021,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -22061,11 +23039,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -22078,7 +23066,7 @@ ac_cv_header_mmap_anon=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -22103,7 +23091,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -22130,11 +23117,21 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -22147,7 +23144,7 @@ ac_cv_type_signal=int fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 echo "${ECHO_T}$ac_cv_type_signal" >&6 @@ -22175,21 +23172,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef $ac_func + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -22220,11 +23224,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -22237,7 +23251,8 @@ eval "$as_ac_var=no" fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 @@ -22255,21 +23270,28 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define mprotect to an innocuous variant, in case declares mprotect. + For example, HP-UX 11i declares gettimeofday. */ +#define mprotect innocuous_mprotect + /* System header to define __stub macros and hopefully few prototypes, which can conflict with char mprotect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ + #ifdef __STDC__ # include #else # include #endif + +#undef mprotect + /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" @@ -22300,11 +23322,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -22317,7 +23349,8 @@ ac_cv_func_mprotect=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_mprotect" >&5 echo "${ECHO_T}$ac_cv_func_mprotect" >&6 @@ -22348,11 +23381,21 @@ _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 + (eval $ac_link) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -22365,7 +23408,8 @@ ac_cv_link_use_r=no fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS="$oldcflags" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -22718,13 +23762,13 @@ # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | @@ -22754,13 +23798,13 @@ # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ + ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; +s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; -s/^[^=]*=[ ]*$//; +s/^[^=]*=[ ]*$//; }' fi @@ -22771,7 +23815,7 @@ for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' @@ -22815,9 +23859,10 @@ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi +DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false @@ -22836,7 +23881,7 @@ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do - if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var @@ -23015,16 +24060,17 @@ if mkdir -p . 2>/dev/null; then as_mkdir_p=: else + test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS @@ -23050,8 +24096,8 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by [LLVM] $as_me [1.3], which was -generated by GNU Autoconf 2.57. Invocation command line was +This file was extended by LLVM $as_me 1.3, which was +generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -23095,9 +24141,9 @@ -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] - instantiate the configuration file FILE + instantiate the configuration file FILE --header=FILE[:TEMPLATE] - instantiate the configuration header FILE + instantiate the configuration header FILE Configuration files: $config_files @@ -23113,12 +24159,11 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -[LLVM] config.status [1.3] -configured by $0, generated by GNU Autoconf 2.57, +LLVM config.status 1.3 +configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir @@ -23532,9 +24577,9 @@ (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end @@ -23552,21 +24597,21 @@ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -23582,10 +24627,10 @@ as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -23623,12 +24668,45 @@ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac case $INSTALL in @@ -23650,7 +24728,7 @@ configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." + sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. @@ -23659,24 +24737,24 @@ case $f in -) echo $tmp/stdin ;; [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } - echo $f;; + echo "$f";; *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } - fi;; + fi;; esac done` || { (exit 1); exit 1; } _ACEOF @@ -23718,12 +24796,12 @@ # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='[ ].*$,\1#\2' +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' @@ -23732,11 +24810,11 @@ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac @@ -23750,28 +24828,29 @@ case $f in -) echo $tmp/stdin ;; [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } - echo $f;; + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } - fi;; + fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. - sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF @@ -23794,9 +24873,9 @@ s,[\\$`],\\&,g t clear : clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times @@ -23810,13 +24889,13 @@ # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF -s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS -echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail @@ -23825,7 +24904,7 @@ # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. - echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS @@ -23852,7 +24931,7 @@ # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' - echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS @@ -23886,10 +24965,10 @@ else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -23905,10 +24984,10 @@ as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -23940,16 +25019,41 @@ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. if test "$ac_dir" != .; then @@ -23975,12 +25079,45 @@ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 @@ -24126,10 +25263,10 @@ as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -24167,12 +25304,45 @@ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac cd $ac_dir @@ -24196,15 +25366,15 @@ case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative path. - ac_sub_cache_file=$ac_top_builddir$cache_file ;; + ac_sub_cache_file=$ac_top_builddir$cache_file ;; esac { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval $ac_sub_configure $ac_sub_configure_args \ - --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || - { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 + --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || + { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} { (exit 1); exit 1; }; } fi From reid at x10sys.com Tue Aug 3 19:36:17 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Aug 2004 19:36:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/CommandLine.cpp Message-ID: <200408040036.TAA27552@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: CommandLine.cpp updated: 1.46 -> 1.47 --- Log message: Add a --version option for every tool that prints out: Low Level Virtual Machine ($PACKAGE_NAME) $PACKAGE_VERSION --- Diffs of the changes: (+18 -1) Index: llvm/lib/Support/CommandLine.cpp diff -u llvm/lib/Support/CommandLine.cpp:1.46 llvm/lib/Support/CommandLine.cpp:1.47 --- llvm/lib/Support/CommandLine.cpp:1.46 Sun Jul 18 16:56:20 2004 +++ llvm/lib/Support/CommandLine.cpp Tue Aug 3 19:36:06 2004 @@ -16,6 +16,7 @@ // //===----------------------------------------------------------------------===// +#include "Config/config.h" #include "Support/CommandLine.h" #include #include @@ -176,7 +177,7 @@ /// them later. /// static void ParseCStringVector (std::vector &output, - const char *input) { + const char *input) { // Characters which will be treated as token separators: static const char *delims = " \v\f\t\r\n"; @@ -891,6 +892,16 @@ } }; +class VersionPrinter { +public: + void operator=(bool OptionWasSpecified) { + if (OptionWasSpecified) { + std::cerr << "Low Level Virtual Machine (" << PACKAGE_NAME << ") " + << PACKAGE_VERSION << " (see http://llvm.org/)\n"; + exit(1); + } + } +}; // Define the two HelpPrinter instances that are used to print out help, or @@ -907,4 +918,10 @@ HHOp("help-hidden", cl::desc("display all available options"), cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed); +// Define the --version option that prints out the LLVM version for the tool +VersionPrinter VersionPrinterInstance; +cl::opt > +VersOp("version", cl::desc("display the version"), + cl::location(VersionPrinterInstance), cl::ValueDisallowed); + } // End anonymous namespace From lattner at cs.uiuc.edu Tue Aug 3 19:37:43 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 19:37:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/SymbolTable.cpp Message-ID: <200408040037.TAA00770@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: SymbolTable.cpp updated: 1.47 -> 1.48 --- Log message: Change SymbolTable::insertEntry to be more careful about how many map lookups it does. This shaves another 5% off of bcreading 252.eon. Note that the proper solution to this problem is to fix PR411: http://llvm.cs.uiuc.edu/PR411 , but that will have to wait until later. --- Diffs of the changes: (+22 -15) Index: llvm/lib/VMCore/SymbolTable.cpp diff -u llvm/lib/VMCore/SymbolTable.cpp:1.47 llvm/lib/VMCore/SymbolTable.cpp:1.48 --- llvm/lib/VMCore/SymbolTable.cpp:1.47 Sat Jul 17 18:57:36 2004 +++ llvm/lib/VMCore/SymbolTable.cpp Tue Aug 3 19:37:31 2004 @@ -74,9 +74,9 @@ // lookup a value - Returns null on failure... Value *SymbolTable::lookup(const Type *Ty, const std::string &Name) const { plane_const_iterator PI = pmap.find(Ty); - if (PI != pmap.end()) { // We have symbols in that plane... + if (PI != pmap.end()) { // We have symbols in that plane. value_const_iterator VI = PI->second.find(Name); - if (VI != PI->second.end()) // and the name is in our hash table... + if (VI != PI->second.end()) // and the name is in our hash table. return VI->second; } return 0; @@ -181,15 +181,9 @@ // insertEntry - Insert a value into the symbol table with the specified name. void SymbolTable::insertEntry(const std::string &Name, const Type *VTy, Value *V) { - // Check to see if there is a naming conflict. If so, rename this value! - if (lookup(VTy, Name)) { - std::string UniqueName = getUniqueName(VTy, Name); - assert(InternallyInconsistent == false && "Infinite loop inserting value!"); - InternallyInconsistent = true; - V->setName(UniqueName, this); - InternallyInconsistent = false; - return; - } + plane_iterator PI = pmap.find(VTy); // Plane iterator + value_iterator VI; // Actual value iterator + ValueMap *VM; // The plane we care about. #if DEBUG_SYMBOL_TABLE dump(); @@ -197,11 +191,10 @@ << VTy->getDescription() << "\n"; #endif - plane_iterator PI = pmap.find(VTy); if (PI == pmap.end()) { // Not in collection yet... insert dummy entry // Insert a new empty element. I points to the new elements. - PI = pmap.insert(make_pair(VTy, ValueMap())).first; - assert(PI != pmap.end() && "How did insert fail?"); + VM = &pmap.insert(make_pair(VTy, ValueMap())).first->second; + VI = VM->end(); // Check to see if the type is abstract. If so, it might be refined in the // future, which would cause the plane of the old type to get merged into @@ -214,9 +207,23 @@ << "\n"; #endif } + + } else { + // Check to see if there is a naming conflict. If so, rename this value! + VM = &PI->second; + VI = VM->lower_bound(Name); + if (VI != VM->end() && VI->first == Name) { + std::string UniqueName = getUniqueName(VTy, Name); + assert(InternallyInconsistent == false && + "Infinite loop inserting value!"); + InternallyInconsistent = true; + V->setName(UniqueName, this); + InternallyInconsistent = false; + return; + } } - PI->second.insert(make_pair(Name, V)); + VM->insert(VI, make_pair(Name, V)); } From reid at x10sys.com Tue Aug 3 19:44:00 2004 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Aug 2004 19:44:00 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408040044.TAA27661@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.223 -> 1.224 --- Log message: Added note for PR413: http://llvm.cs.uiuc.edu/PR413 Tools now respond to the --version option. --- Diffs of the changes: (+4 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.223 llvm/docs/ReleaseNotes.html:1.224 --- llvm/docs/ReleaseNotes.html:1.223 Mon Aug 2 15:29:51 2004 +++ llvm/docs/ReleaseNotes.html Tue Aug 3 19:43:50 2004 @@ -146,6 +146,9 @@ for global variables, which is now enabled by default in gccld.
  • LLVM can now autogenerate assembly printers for code generators from the tablegen description of the target (before they were hand coded).
  • +
  • All LLVM tools will now respond to the +--version option which +will tell you the version of LLVM on which the tool is based.
  • @@ -757,7 +760,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/02 20:29:51 $ + Last modified: $Date: 2004/08/04 00:43:50 $ From lattner at cs.uiuc.edu Tue Aug 3 21:27:29 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 21:27:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Globals.cpp Message-ID: <200408040227.VAA05013@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Globals.cpp updated: 1.3 -> 1.4 --- Log message: Add a cast --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/Globals.cpp diff -u llvm/lib/VMCore/Globals.cpp:1.3 llvm/lib/VMCore/Globals.cpp:1.4 --- llvm/lib/VMCore/Globals.cpp:1.3 Sun Jul 18 19:55:35 2004 +++ llvm/lib/VMCore/Globals.cpp Tue Aug 3 21:27:17 2004 @@ -120,7 +120,7 @@ "Attempt to replace GVar initializer with non-constant"); // Okay, preconditions out of the way, replace the constant initializer. - this->setOperand(0,To); + this->setOperand(0, cast(To)); } // vim: sw=2 ai From lattner at cs.uiuc.edu Tue Aug 3 21:42:33 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 21:42:33 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200408040242.VAA31553@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.52 -> 1.53 --- Log message: Add a special version of getType for ConstantPointerNull, exposing the fact that all Null pointers have pointer type --- Diffs of the changes: (+7 -0) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.52 llvm/include/llvm/Constants.h:1.53 --- llvm/include/llvm/Constants.h:1.52 Mon Jul 19 16:11:45 2004 +++ llvm/include/llvm/Constants.h Tue Aug 3 21:42:17 2004 @@ -454,6 +454,13 @@ virtual void destroyConstant(); + /// getType - Specialize the getType() method to always return an PointerType, + /// which reduces the amount of casting needed in parts of the compiler. + /// + inline const PointerType *getType() const { + return reinterpret_cast(Value::getType()); + } + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantPointerNull *) { return true; } static bool classof(const Value *V) { From lattner at cs.uiuc.edu Tue Aug 3 21:43:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 21:43:12 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Message-ID: <200408040243.VAA00332@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.16 -> 1.17 --- Log message: Now that ConstantPointerRef is gone, it is the case that all operands of constants are themselves constants. This should allow us to reduce a significant amount of casting in the sourcebase. --- Diffs of the changes: (+12 -0) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.16 llvm/include/llvm/Constant.h:1.17 --- llvm/include/llvm/Constant.h:1.16 Mon Jul 19 16:22:02 2004 +++ llvm/include/llvm/Constant.h Tue Aug 3 21:43:00 2004 @@ -40,6 +40,18 @@ virtual void print(std::ostream &O) const; + // Specialize get/setOperand for Constant's as their operands are always + // constants as well. + Constant *getOperand(unsigned i) { + return static_cast(User::getOperand(i)); + } + const Constant *getOperand(unsigned i) const { + return static_cast(User::getOperand(i)); + } + void setOperand(unsigned i, Constant *C) { + User::setOperand(i, C); + } + /// destroyConstant - Called if some element of this constant is no longer /// valid. At this point only other constants may be on the use_list for this /// constant. Any constants on our Use list must also be destroy'd. The From lattner at cs.uiuc.edu Tue Aug 3 22:52:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 22:52:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Message-ID: <200408040352.WAA29756@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: ModuloScheduling.cpp updated: 1.22 -> 1.23 --- Log message: Squelch warnings in release mode --- Diffs of the changes: (+3 -3) Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.22 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.23 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.22 Mon Aug 2 08:59:10 2004 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Tue Aug 3 22:51:55 2004 @@ -631,8 +631,8 @@ int distance = 0; int RecMII = II; //Starting value MSchedGraphNode *last = node; - MSchedGraphNode *srcBackEdge; - MSchedGraphNode *destBackEdge; + MSchedGraphNode *srcBackEdge = 0; + MSchedGraphNode *destBackEdge = 0; @@ -1736,7 +1736,7 @@ //Update last epilogue exit branch BranchInst *branchVal = (BranchInst*) dyn_cast(BB->getBasicBlock()->getTerminator()); //Find where we are supposed to branch to - BasicBlock *nextBlock; + BasicBlock *nextBlock = 0; for(unsigned j=0; j getNumSuccessors(); ++j) { if(branchVal->getSuccessor(j) != BB->getBasicBlock()) nextBlock = branchVal->getSuccessor(j); From lattner at cs.uiuc.edu Tue Aug 3 23:45:54 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 23:45:54 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/AbstractTypeUser.h Value.h Message-ID: <200408040445.XAA11136@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: AbstractTypeUser.h updated: 1.21 -> 1.22 Value.h updated: 1.61 -> 1.62 --- Log message: New methods --- Diffs of the changes: (+8 -0) Index: llvm/include/llvm/AbstractTypeUser.h diff -u llvm/include/llvm/AbstractTypeUser.h:1.21 llvm/include/llvm/AbstractTypeUser.h:1.22 --- llvm/include/llvm/AbstractTypeUser.h:1.21 Wed Jul 14 15:10:26 2004 +++ llvm/include/llvm/AbstractTypeUser.h Tue Aug 3 23:45:42 2004 @@ -164,6 +164,10 @@ return operator=(H.Ty); } + /// getRawType - This should only be used to implement the vmcore library. + /// + const Type *getRawType() const { return Ty; } + private: void addRef(); void dropRef(); Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.61 llvm/include/llvm/Value.h:1.62 --- llvm/include/llvm/Value.h:1.61 Fri Jul 30 01:59:15 2004 +++ llvm/include/llvm/Value.h Tue Aug 3 23:45:42 2004 @@ -141,6 +141,10 @@ return true; // Values are always values. } + /// getRawType - This should only be used to implement the vmcore library. + /// + const Type *getRawType() const { return Ty.getRawType(); } + private: /// FIXME: this is a gross hack, needed by another gross hack. Eliminate! void setValueType(unsigned VT) { SubclassID = VT; } From lattner at cs.uiuc.edu Tue Aug 3 23:46:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 23:46:10 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PatternMatch.h Message-ID: <200408040446.XAA11140@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PatternMatch.h updated: 1.2 -> 1.3 --- Log message: Minor efficiency improvements --- Diffs of the changes: (+3 -3) Index: llvm/include/llvm/Support/PatternMatch.h diff -u llvm/include/llvm/Support/PatternMatch.h:1.2 llvm/include/llvm/Support/PatternMatch.h:1.3 --- llvm/include/llvm/Support/PatternMatch.h:1.2 Fri Jul 30 09:33:07 2004 +++ llvm/include/llvm/Support/PatternMatch.h Tue Aug 3 23:45:29 2004 @@ -36,8 +36,8 @@ namespace PatternMatch { template -bool match(Val *V, Pattern P) { - return P.match(V); +bool match(Val *V, const Pattern &P) { + return const_cast(P).match(V); } template @@ -52,7 +52,7 @@ template struct bind_ty { Class *&VR; - bind_ty(Class*& V) :VR(V) {} + bind_ty(Class *&V) : VR(V) {} template bool match(ITy *V) { From lattner at cs.uiuc.edu Tue Aug 3 23:48:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Aug 2004 23:48:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200408040448.XAA11148@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.97 -> 1.98 --- Log message: Implement a FIXME, by not searching linearly through a map to remove an element. This speeds up the bytecode reader from 12.86s to 8.72s on 252.eon. --- Diffs of the changes: (+34 -8) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.97 llvm/lib/VMCore/Constants.cpp:1.98 --- llvm/lib/VMCore/Constants.cpp:1.97 Thu Jul 29 12:20:21 2004 +++ llvm/lib/VMCore/Constants.cpp Tue Aug 3 23:48:01 2004 @@ -606,13 +606,10 @@ } void remove(ConstantClass *CP) { - // FIXME: This should not use a linear scan. If this gets to be a - // performance problem, someone should look at this. - MapIterator I = Map.begin(); - for (MapIterator E = Map.end(); I != E && I->second != CP; ++I) - /* empty */; - + MapIterator I = Map.find(MapKey((TypeClass*)CP->getRawType(), + getValType(CP))); assert(I != Map.end() && "Constant not found in constant table!"); + assert(I->second == CP && "Didn't find correct element?"); // Now that we found the entry, make sure this isn't the entry that // the AbstractTypeMap points to. @@ -687,8 +684,6 @@ }; } - - //---- ConstantUInt::get() and ConstantSInt::get() implementations... // static ValueMap< int64_t, Type, ConstantSInt> SIntConstants; @@ -785,6 +780,8 @@ static ValueMap AggZeroConstants; +static char getValType(ConstantAggregateZero *CPZ) { return 0; } + Constant *ConstantAggregateZero::get(const Type *Ty) { return AggZeroConstants.getOrCreate(Ty, 0); } @@ -822,6 +819,14 @@ }; } +static std::vector getValType(ConstantArray *CA) { + std::vector Elements; + Elements.reserve(CA->getNumOperands()); + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + Elements.push_back(cast(CA->getOperand(i))); + return Elements; +} + static ValueMap, ArrayType, ConstantArray> ArrayConstants; @@ -914,6 +919,14 @@ static ValueMap, StructType, ConstantStruct> StructConstants; +static std::vector getValType(ConstantStruct *CS) { + std::vector Elements; + Elements.reserve(CS->getNumOperands()); + for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) + Elements.push_back(cast(CS->getOperand(i))); + return Elements; +} + Constant *ConstantStruct::get(const StructType *Ty, const std::vector &V) { // Create a ConstantAggregateZero value if all elements are zeros... @@ -965,6 +978,11 @@ static ValueMap NullPtrConstants; +static char getValType(ConstantPointerNull *) { + return 0; +} + + ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { return NullPtrConstants.getOrCreate(Ty, 0); } @@ -1042,6 +1060,14 @@ } // end namespace llvm +static ExprMapKeyType getValType(ConstantExpr *CE) { + std::vector Operands; + Operands.reserve(CE->getNumOperands()); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) + Operands.push_back(cast(CE->getOperand(i))); + return ExprMapKeyType(CE->getOpcode(), Operands); +} + static ValueMap ExprConstants; Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) { From lattner at cs.uiuc.edu Wed Aug 4 00:11:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 00:11:01 -0500 Subject: [llvm-commits] CVS: llvm/docs/ProgrammersManual.html Message-ID: <200408040511.AAA11224@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ProgrammersManual.html updated: 1.67 -> 1.68 --- Log message: Fix linkage types --- Diffs of the changes: (+4 -4) Index: llvm/docs/ProgrammersManual.html diff -u llvm/docs/ProgrammersManual.html:1.67 llvm/docs/ProgrammersManual.html:1.68 --- llvm/docs/ProgrammersManual.html:1.67 Sun Jul 18 16:44:13 2004 +++ llvm/docs/ProgrammersManual.html Wed Aug 4 00:10:48 2004 @@ -1371,12 +1371,12 @@ -

    The core LLVM infrastructure uses GNU autoconf to adapt itself to the machine and operating system on which it is built. However, minor @@ -396,9 +398,11 @@ components, please contact us on the llvmdev list.

      +
    • The PowerPC backend is incomplete and is known to miscompile several SPEC +benchmarks. The file llvm/lib/Target/PowerPC/README.txt has +details.
    • The following passes are incomplete or buggy: -pgmdep, -memdep, -ipmodref, -cee
    • -
    • The -pre pass is incomplete (there are cases it doesn't handle that it should) and not thoroughly tested.
    • The llvm-ar tool is incomplete and probably buggy.
    • @@ -761,7 +765,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/08/04 08:00:45 $ + Last modified: $Date: 2004/08/05 21:04:03 $ From lattner at cs.uiuc.edu Thu Aug 5 16:53:26 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Aug 2004 16:53:26 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408052153.QAA21341@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.226 -> 1.227 --- Log message: More prominantly mention ppc support, more accurately describe its status --- Diffs of the changes: (+6 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.226 llvm/docs/ReleaseNotes.html:1.227 --- llvm/docs/ReleaseNotes.html:1.226 Thu Aug 5 16:04:03 2004 +++ llvm/docs/ReleaseNotes.html Thu Aug 5 16:53:13 2004 @@ -73,7 +73,8 @@ release primarily improves the performance of the code produced by all aspects of the LLVM compiler, adds many new features, fixes a few -bugs, and speeds up the compiler.

      +bugs, speeds up the compiler, and introduces a new (experimental) +PowerPC code generator.

      At this time, LLVM is known to correctly compile and run all C & C++ SPEC CPU95 & 2000 benchmarks, the Olden benchmarks, and the Ptrdist @@ -349,8 +350,10 @@

    • Intel and AMD machines running Red Hat Linux and FreeBSD (and probably other unix-like systems).
    • Sun UltraSPARC workstations running Solaris 8.
    • -
    • PowerPC-based Mac OS X boxes, running 10.2 and above.
    • Intel and AMD machines running on Win32 with the Cygwin libraries.
    • +
    • PowerPC-based Mac OS X boxes, running 10.2 and above. Note that no JIT +support is available yet, and LLC support is beta. The C backend can be used +to produce stable code for this platform.

    The core LLVM infrastructure uses @@ -765,7 +768,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/05 21:04:03 $ + Last modified: $Date: 2004/08/05 21:53:13 $ From criswell at cs.uiuc.edu Thu Aug 5 18:46:37 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 18:46:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/LICENSE.TXT Message-ID: <200408052346.SAA29360@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: LICENSE.TXT updated: 1.1 -> 1.2 --- Log message: Added Louis Gerbarg. Louis is given credit in the CREDITS.TXT file, so I assume Louis also holds copyright. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/PowerPC/LICENSE.TXT diff -u llvm/lib/Target/PowerPC/LICENSE.TXT:1.1 llvm/lib/Target/PowerPC/LICENSE.TXT:1.2 --- llvm/lib/Target/PowerPC/LICENSE.TXT:1.1 Thu Aug 5 15:36:00 2004 +++ llvm/lib/Target/PowerPC/LICENSE.TXT Thu Aug 5 18:46:27 2004 @@ -3,5 +3,5 @@ The PowerPC Backend is licensed under the Illinois Open Source License and has the following additional copyright: -Copyright (C) 2004 Nate Begeman +Copyright (C) 2004 Nate Begeman and Louis Gerbarg From lattner at cs.uiuc.edu Fri Aug 6 01:59:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 01:59:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCPEI.cpp PowerPC.h PowerPC.td PowerPCISelSimple.cpp PowerPCRegisterInfo.cpp PowerPCTargetMachine.cpp README.txt Message-ID: <200408060659.BAA23316@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCPEI.cpp added (r1.1) PowerPC.h updated: 1.2 -> 1.3 PowerPC.td updated: 1.4 -> 1.5 PowerPCISelSimple.cpp updated: 1.53 -> 1.54 PowerPCRegisterInfo.cpp updated: 1.23 -> 1.24 PowerPCTargetMachine.cpp updated: 1.21 -> 1.22 README.txt updated: 1.10 -> 1.11 --- Log message: Changes commited for Nate Begeman: Use a PowerPC specific prolog epilog inserter to control where spilled callee save regs are placed on the stack. Get rid of implicit return address stack slot, save return address reg (LR) in appropriate slot Improve code generated for functions that don't have calls or access globals Note from Chris: PowerPCPEI will eventually be eliminated, once the functionality is merged into CodeGen/PrologEpilogInserter.cpp --- Diffs of the changes: (+388 -96) Index: llvm/lib/Target/PowerPC/PowerPCPEI.cpp diff -c /dev/null llvm/lib/Target/PowerPC/PowerPCPEI.cpp:1.1 *** /dev/null Fri Aug 6 01:59:00 2004 --- llvm/lib/Target/PowerPC/PowerPCPEI.cpp Fri Aug 6 01:58:50 2004 *************** *** 0 **** --- 1,326 ---- + //===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This pass is responsible for finalizing the functions frame layout, saving + // callee saved registers, and for emitting prolog & epilog code for the + // function. + // + // This pass must be run after register allocation. After this pass is + // executed, it is illegal to construct MO_FrameIndex operands. + // + //===----------------------------------------------------------------------===// + // + // FIXME: The contents of this file should be merged with the target generic + // CodeGen/PrologEpilogInserter.cpp + // + //===----------------------------------------------------------------------===// + + #include "PowerPC.h" + #include "llvm/CodeGen/Passes.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/MRegisterInfo.h" + #include "llvm/Target/TargetFrameInfo.h" + #include "llvm/Target/TargetInstrInfo.h" + #include "Support/Debug.h" + using namespace llvm; + + namespace { + struct PPCPEI : public MachineFunctionPass { + const char *getPassName() const { + return "PowerPC Frame Finalization & Prolog/Epilog Insertion"; + } + + /// runOnMachineFunction - Insert prolog/epilog code and replace abstract + /// frame indexes with appropriate references. + /// + bool runOnMachineFunction(MachineFunction &Fn) { + RegsToSave.clear(); + StackSlots.clear(); + + // Scan the function for modified caller saved registers and insert spill + // code for any caller saved registers that are modified. Also calculate + // the MaxCallFrameSize and HasCalls variables for the function's frame + // information and eliminates call frame pseudo instructions. + calculateCallerSavedRegisters(Fn); + + // Calculate actual frame offsets for all of the abstract stack objects... + calculateFrameObjectOffsets(Fn); + + // Add prolog and epilog code to the function. + insertPrologEpilogCode(Fn); + + // Add register spills and fills before prolog and after epilog so that in + // the event of a very large fixed size alloca, we don't have to do + // anything weird. + saveCallerSavedRegisters(Fn); + + // Replace all MO_FrameIndex operands with physical register references + // and actual offsets. + // + replaceFrameIndices(Fn); + return true; + } + + private: + std::vector RegsToSave; + std::vector StackSlots; + + void calculateCallerSavedRegisters(MachineFunction &Fn); + void saveCallerSavedRegisters(MachineFunction &Fn); + void calculateFrameObjectOffsets(MachineFunction &Fn); + void replaceFrameIndices(MachineFunction &Fn); + void insertPrologEpilogCode(MachineFunction &Fn); + }; + } + + + /// createPowerPCPEI - This function returns a pass that inserts + /// prolog and epilog code, and eliminates abstract frame references. + /// + FunctionPass *llvm::createPowerPCPEI() { return new PPCPEI(); } + + + /// calculateCallerSavedRegisters - Scan the function for modified caller saved + /// registers. Also calculate the MaxCallFrameSize and HasCalls variables for + /// the function's frame information and eliminates call frame pseudo + /// instructions. + /// + void PPCPEI::calculateCallerSavedRegisters(MachineFunction &Fn) { + const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + const TargetFrameInfo &FrameInfo = *Fn.getTarget().getFrameInfo(); + + // Get the callee saved register list... + const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); + + // Get the function call frame set-up and tear-down instruction opcode + int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); + int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); + + // Early exit for targets which have no callee saved registers and no call + // frame setup/destroy pseudo instructions. + if ((CSRegs == 0 || CSRegs[0] == 0) && + FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) + return; + + // This bitset contains an entry for each physical register for the target... + std::vector ModifiedRegs(RegInfo->getNumRegs()); + unsigned MaxCallFrameSize = 0; + bool HasCalls = false; + + for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) + for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) + if (I->getOpcode() == FrameSetupOpcode || + I->getOpcode() == FrameDestroyOpcode) { + assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" + " instructions should have a single immediate argument!"); + unsigned Size = I->getOperand(0).getImmedValue(); + if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; + HasCalls = true; + RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); + } else { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + MachineOperand &MO = I->getOperand(i); + if (MO.isRegister() && MO.isDef()) { + assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && + "Register allocation must be performed!"); + ModifiedRegs[MO.getReg()] = true; // Register is modified + } + } + ++I; + } + + MachineFrameInfo *FFI = Fn.getFrameInfo(); + FFI->setHasCalls(HasCalls); + FFI->setMaxCallFrameSize(MaxCallFrameSize); + + // Now figure out which *callee saved* registers are modified by the current + // function, thus needing to be saved and restored in the prolog/epilog. + // + for (unsigned i = 0; CSRegs[i]; ++i) { + unsigned Reg = CSRegs[i]; + if (ModifiedRegs[Reg]) { + RegsToSave.push_back(Reg); // If modified register... + } else { + for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); + *AliasSet; ++AliasSet) { // Check alias registers too... + if (ModifiedRegs[*AliasSet]) { + RegsToSave.push_back(Reg); + break; + } + } + } + } + + // FIXME: should we sort the regs to save so that we always get the regs in + // the correct order? + + // Now that we know which registers need to be saved and restored, allocate + // stack slots for them. + int Offset = 0; + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + unsigned RegSize = RegInfo->getRegClass(RegsToSave[i])->getSize(); + int FrameIdx; + + if (RegsToSave[i] == PPC32::LR) { + FrameIdx = FFI->CreateFixedObject(RegSize, 8); // LR lives at +8 + } else { + Offset -= RegSize; + FrameIdx = FFI->CreateFixedObject(RegSize, Offset); + } + StackSlots.push_back(FrameIdx); + } + } + + + /// saveCallerSavedRegisters - Insert spill code for any caller saved registers + /// that are modified in the function. + /// + void PPCPEI::saveCallerSavedRegisters(MachineFunction &Fn) { + // Early exit if no caller saved registers are modified! + if (RegsToSave.empty()) + return; + + const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + + // Now that we have a stack slot for each register to be saved, insert spill + // code into the entry block... + MachineBasicBlock *MBB = Fn.begin(); + MachineBasicBlock::iterator I = MBB->begin(); + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); + // Insert the spill to the stack frame... + RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], RC); + } + + // Add code to restore the callee-save registers in each exiting block. + const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); + for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) { + // If last instruction is a return instruction, add an epilogue + if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { + MBB = FI; + I = MBB->end(); --I; + + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i], RC); + --I; // Insert in reverse order + } + } + } + } + + + /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the + /// abstract stack objects... + /// + void PPCPEI::calculateFrameObjectOffsets(MachineFunction &Fn) { + const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); + + bool StackGrowsDown = + TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; + + // Loop over all of the stack objects, assigning sequential addresses... + MachineFrameInfo *FFI = Fn.getFrameInfo(); + + unsigned StackAlignment = TFI.getStackAlignment(); + + // Start at the beginning of the local area. + // The Offset is the distance from the stack top in the direction + // of stack growth -- so it's always positive. + int Offset = TFI.getOffsetOfLocalArea(); + if (StackGrowsDown) + Offset = -Offset; + assert(Offset >= 0 + && "Local area offset should be in direction of stack growth"); + + // If there are fixed sized objects that are preallocated in the local area, + // non-fixed objects can't be allocated right at the start of local area. + // We currently don't support filling in holes in between fixed sized objects, + // so we adjust 'Offset' to point to the end of last fixed sized + // preallocated object. + for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { + int FixedOff; + if (StackGrowsDown) { + // The maximum distance from the stack pointer is at lower address of + // the object -- which is given by offset. For down growing stack + // the offset is negative, so we negate the offset to get the distance. + FixedOff = -FFI->getObjectOffset(i); + } else { + // The maximum distance from the start pointer is at the upper + // address of the object. + FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); + } + if (FixedOff > Offset) Offset = FixedOff; + } + + for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { + // If stack grows down, we need to add size of find the lowest + // address of the object. + if (StackGrowsDown) + Offset += FFI->getObjectSize(i); + + unsigned Align = FFI->getObjectAlignment(i); + assert(Align <= StackAlignment && "Cannot align stack object to higher " + "alignment boundary than the stack itself!"); + Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... + + if (StackGrowsDown) { + FFI->setObjectOffset(i, -Offset); // Set the computed offset + } else { + FFI->setObjectOffset(i, Offset); + Offset += FFI->getObjectSize(i); + } + } + + // Set the final value of the stack pointer... + FFI->setStackSize(Offset); + } + + + /// insertPrologEpilogCode - Scan the function for modified caller saved + /// registers, insert spill code for these caller saved registers, then add + /// prolog and epilog code to the function. + /// + void PPCPEI::insertPrologEpilogCode(MachineFunction &Fn) { + // Add prologue to the function... + Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); + + // Add epilogue to restore the callee-save registers in each exiting block + const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); + for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { + // If last instruction is a return instruction, add an epilogue + if (!I->empty() && TII.isReturn(I->back().getOpcode())) + Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); + } + } + + + /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical + /// register references and actual offsets. + /// + void PPCPEI::replaceFrameIndices(MachineFunction &Fn) { + if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? + + const TargetMachine &TM = Fn.getTarget(); + assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); + const MRegisterInfo &MRI = *TM.getRegisterInfo(); + + for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) + for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (I->getOperand(i).isFrameIndex()) { + // If this instruction has a FrameIndex operand, we need to use that + // target machine register info object to eliminate it. + MRI.eliminateFrameIndex(Fn, I); + break; + } + } Index: llvm/lib/Target/PowerPC/PowerPC.h diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.2 llvm/lib/Target/PowerPC/PowerPC.h:1.3 --- llvm/lib/Target/PowerPC/PowerPC.h:1.2 Tue Jul 27 13:33:06 2004 +++ llvm/lib/Target/PowerPC/PowerPC.h Fri Aug 6 01:58:50 2004 @@ -26,6 +26,7 @@ // passes. For example: FunctionPass *createPPCSimpleInstructionSelector(TargetMachine &TM); FunctionPass *createPPCCodePrinterPass(std::ostream &OS, TargetMachine &TM); +FunctionPass *createPowerPCPEI(); FunctionPass *createPPCBranchSelectionPass(); } // end namespace llvm; Index: llvm/lib/Target/PowerPC/PowerPC.td diff -u llvm/lib/Target/PowerPC/PowerPC.td:1.4 llvm/lib/Target/PowerPC/PowerPC.td:1.5 --- llvm/lib/Target/PowerPC/PowerPC.td:1.4 Fri Jul 30 10:51:51 2004 +++ llvm/lib/Target/PowerPC/PowerPC.td Fri Aug 6 01:58:50 2004 @@ -33,11 +33,11 @@ let PointerType = i32; // According to the Mach-O Runtime ABI, these regs are nonvolatile across - // calls: put LR in here someday when we can Do The Right Thing + // calls let CalleeSavedRegisters = [R1, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, - F30, F31, CR2, CR3, CR4]; + F30, F31, CR2, CR3, CR4, LR]; // Pull in Instruction Info: let InstructionSet = PowerPCInstrInfo; Index: llvm/lib/Target/PowerPC/PowerPCISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PowerPCISelSimple.cpp:1.53 llvm/lib/Target/PowerPC/PowerPCISelSimple.cpp:1.54 --- llvm/lib/Target/PowerPC/PowerPCISelSimple.cpp:1.53 Wed Jul 28 14:13:49 2004 +++ llvm/lib/Target/PowerPC/PowerPCISelSimple.cpp Fri Aug 6 01:58:50 2004 @@ -646,11 +646,8 @@ /// LoadArgumentsToVirtualRegs - Load all of the arguments to this function from /// the stack into virtual registers. -/// -/// FIXME: When we can calculate which args are coming in via registers -/// source them from there instead. void ISel::LoadArgumentsToVirtualRegs(Function &Fn) { - unsigned ArgOffset = 20; // FIXME why is this not 24? + unsigned ArgOffset = 24; unsigned GPR_remaining = 8; unsigned FPR_remaining = 13; unsigned GPR_idx = 0, FPR_idx = 0; @@ -1412,8 +1409,10 @@ /// void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI, const std::vector &Args, bool isVarArg) { - // Count how many bytes are to be pushed on the stack... - unsigned NumBytes = 0; + // Count how many bytes are to be pushed on the stack, including the linkage + // area, and parameter passing area. + unsigned NumBytes = 24; + unsigned ArgOffset = 24; if (!Args.empty()) { for (unsigned i = 0, e = Args.size(); i != e; ++i) @@ -1430,12 +1429,16 @@ default: assert(0 && "Unknown class!"); } + // Just to be safe, we'll always reserve the full 32 bytes worth of + // argument passing space in case any called code gets funky on us. + if (NumBytes < 24 + 32) NumBytes = 24 + 32; + // Adjust the stack pointer for the new arguments... - BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addSImm(NumBytes); + // These functions are automatically eliminated by the prolog/epilog pass + BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addImm(NumBytes); // Arguments go on the stack in reverse order, as specified by the ABI. // Offset to the paramater area on the stack is 24. - unsigned ArgOffset = 24; int GPR_remaining = 8, FPR_remaining = 13; unsigned GPR_idx = 0, FPR_idx = 0; static const unsigned GPR[] = { @@ -1573,12 +1576,14 @@ GPR_idx++; } } else { - BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addSImm(0); + BuildMI(BB, PPC32::ADJCALLSTACKDOWN, 1).addImm(0); } BuildMI(BB, PPC32::IMPLICIT_DEF, 0, PPC32::LR); BB->push_back(CallMI); - BuildMI(BB, PPC32::ADJCALLSTACKUP, 1).addSImm(NumBytes); + + // These functions are automatically eliminated by the prolog/epilog pass + BuildMI(BB, PPC32::ADJCALLSTACKUP, 1).addImm(NumBytes); // If there is a return value, scavenge the result from the location the call // leaves it in... @@ -1592,11 +1597,11 @@ // Integral results are in r3 BuildMI(BB, PPC32::OR, 2, Ret.Reg).addReg(PPC32::R3).addReg(PPC32::R3); break; - case cFP32: // Floating-point return values live in f1 + case cFP32: // Floating-point return values live in f1 case cFP64: BuildMI(BB, PPC32::FMR, 1, Ret.Reg).addReg(PPC32::F1); break; - case cLong: // Long values are in r3 hi:r4 lo + case cLong: // Long values are in r3:r4 BuildMI(BB, PPC32::OR, 2, Ret.Reg).addReg(PPC32::R3).addReg(PPC32::R3); BuildMI(BB, PPC32::OR, 2, Ret.Reg+1).addReg(PPC32::R4).addReg(PPC32::R4); break; Index: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.23 llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.24 --- llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.23 Fri Jul 30 10:50:45 2004 +++ llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp Fri Aug 6 01:58:50 2004 @@ -64,11 +64,12 @@ unsigned OC = Opcode[getIdx(RC)]; if (SrcReg == PPC32::LR) { MBB.insert(MI, BuildMI(PPC32::MFLR, 0, PPC32::R0)); - OC = PPC32::STW; - SrcReg = PPC32::R0; + MBB.insert(MI, addFrameReference(BuildMI(OC,3).addReg(PPC32::R0),FrameIdx)); + return 2; + } else { + MBB.insert(MI, addFrameReference(BuildMI(OC, 3).addReg(SrcReg),FrameIdx)); + return 1; } - MBB.insert(MI, addFrameReference(BuildMI(OC, 3).addReg(SrcReg),FrameIdx)); - return 1; } int @@ -80,17 +81,14 @@ PPC32::LBZ, PPC32::LHZ, PPC32::LWZ, PPC32::LFS, PPC32::LFD }; unsigned OC = Opcode[getIdx(RC)]; - bool LoadLR = false; if (DestReg == PPC32::LR) { - DestReg = PPC32::R0; - LoadLR = true; - OC = PPC32::LWZ; - } - MBB.insert(MI, addFrameReference(BuildMI(OC, 2, DestReg), FrameIdx)); - if (LoadLR) + MBB.insert(MI, addFrameReference(BuildMI(OC, 2, PPC32::R0), FrameIdx)); MBB.insert(MI, BuildMI(PPC32::MTLR, 1).addReg(PPC32::R0)); - - return 1; + return 2; + } else { + MBB.insert(MI, addFrameReference(BuildMI(OC, 2, DestReg), FrameIdx)); + return 1; + } } int PowerPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, @@ -128,10 +126,10 @@ MachineBasicBlock::iterator I) const { if (hasFP(MF)) { // If we have a frame pointer, convert as follows: - // adjcallstackdown instruction => 'sub r1, r1, ' and - // adjcallstackup instruction => 'add r1, r1, ' + // ADJCALLSTACKDOWN -> addi, r1, r1, -amount + // ADJCALLSTACKUP -> addi, r1, r1, amount MachineInstr *Old = I; - int Amount = Old->getOperand(0).getImmedValue(); + unsigned Amount = Old->getOperand(0).getImmedValue(); if (Amount != 0) { // We need to keep the stack aligned properly. To do this, we round the // amount of space needed for the outgoing arguments up to the next @@ -174,15 +172,20 @@ // Take into account whether it's an add or mem instruction unsigned OffIdx = (i == 2) ? 1 : 2; + // Now add the frame object offset to the offset from r1. int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + - MI.getOperand(OffIdx).getImmedValue()+4; + MI.getOperand(OffIdx).getImmedValue(); - if (!hasFP(MF)) + // Fixed offsets have a negative frame index. Fixed negative offests denote + // spilled callee save regs. Fixed positive offset is the va_start offset, + // and needs to be added to the amount we decremented the stack pointer. + // Positive frame indices are regular offsets from the stack pointer, and + // also need the stack size added. + if (FrameIndex >= 0 || (FrameIndex < 0 && Offset >= 24)) Offset += MF.getFrameInfo()->getStackSize(); MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset); - DEBUG(std::cerr << "offset = " << Offset << std::endl); } @@ -195,36 +198,25 @@ // Get the number of bytes to allocate from the FrameInfo unsigned NumBytes = MFI->getStackSize(); - // If we have calls, save the LR value on the stack - if (MFI->hasCalls() || true) { - // When we have no frame pointer, we reserve argument space for call sites - // in the function immediately on entry to the current function. This - // eliminates the need for add/sub brackets around call sites. - NumBytes += MFI->getMaxCallFrameSize() + - 24 + // Predefined PowerPC link area - 32 + // Predefined PowerPC params area - 0 + // local variables - managed by LLVM - 0 * 4 + // volatile GPRs used - managed by LLVM - 0 * 8; // volatile FPRs used - managed by LLVM - - // Round the size to a multiple of the alignment (don't forget the 4 byte - // offset though). - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - NumBytes = ((NumBytes+4)+Align-1)/Align*Align - 4; - - // Store the incoming LR so it is preserved across calls - MI = BuildMI(PPC32::MFLR, 0, PPC32::R0); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC32::STW, 3).addReg(PPC32::R0).addSImm(8).addReg(PPC32::R1); - MBB.insert(MBBI, MI); + // If we have calls, we cannot use the red zone to store callee save registers + // and we must set up a stack frame, so calculate the necessary size here. + if (MFI->hasCalls()) { + // We reserve argument space for call sites in the function immediately on + // entry to the current function. This eliminates the need for add/sub + // brackets around call sites. + NumBytes += MFI->getMaxCallFrameSize(); } - // Update frame info to pretend that this is part of the stack... - MFI->setStackSize(NumBytes); - // Do we need to allocate space on the stack? if (NumBytes == 0) return; + // Round the size to a multiple of the alignment + unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); + NumBytes = (NumBytes+Align-1)/Align*Align; + + // Update frame info to pretend that this is part of the stack... + MFI->setStackSize(NumBytes); + // adjust stack pointer: r1 -= numbytes if (NumBytes <= 32768) { MI = BuildMI(PPC32::STWU, 3).addReg(PPC32::R1).addSImm(-NumBytes) @@ -254,35 +246,9 @@ // Get the number of bytes allocated from the FrameInfo... unsigned NumBytes = MFI->getStackSize(); - if (NumBytes == 0 && (MFI->hasCalls() || true)) { - // Don't need to adjust the stack pointer, just gotta fix up the LR - MI = BuildMI(PPC32::LWZ, 2,PPC32::R0).addSImm(NumBytes+8).addReg(PPC32::R1); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC32::MTLR, 1).addReg(PPC32::R0); - MBB.insert(MBBI, MI); - } else if (NumBytes <= 32767-8) { - // We're within range to load the return address and restore the stack - // pointer with immediate offsets only. - if (MFI->hasCalls() || true) { - MI = BuildMI(PPC32::LWZ,2,PPC32::R0).addSImm(NumBytes+8).addReg(PPC32::R1); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC32::MTLR, 1).addReg(PPC32::R0); - MBB.insert(MBBI, MI); - } - MI = BuildMI(PPC32::ADDI, 2, PPC32::R1).addReg(PPC32::R1).addSImm(NumBytes); - MBB.insert(MBBI, MI); - } else { + if (NumBytes != 0) { MI = BuildMI(PPC32::LWZ, 2, PPC32::R1).addSImm(0).addReg(PPC32::R1); MBB.insert(MBBI, MI); - // We're not within range to load the return address with an immediate - // offset before restoring the stack pointer, so do it after from its spot - // in the linkage area. - if (MFI->hasCalls() || true) { - MI = BuildMI(PPC32::LWZ, 2, PPC32::R0).addSImm(8).addReg(PPC32::R1); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC32::MTLR, 1).addReg(PPC32::R0); - MBB.insert(MBBI, MI); - } } } Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.21 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.22 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.21 Tue Jul 27 13:39:34 2004 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Fri Aug 6 01:58:50 2004 @@ -85,7 +85,10 @@ if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); - PM.add(createPrologEpilogCodeInserter()); + // I want a PowerPC specific prolog/epilog code inserter so I can put the + // fills/spills in the right spots. + PM.add(createPowerPCPEI()); + // Must run branch selection immediately preceding the printer PM.add(createPPCBranchSelectionPass()); PM.add(createPPCCodePrinterPass(Out, *this)); Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.10 llvm/lib/Target/PowerPC/README.txt:1.11 --- llvm/lib/Target/PowerPC/README.txt:1.10 Fri Jul 30 10:53:09 2004 +++ llvm/lib/Target/PowerPC/README.txt Fri Aug 6 01:58:50 2004 @@ -3,9 +3,6 @@ * signed right shift of long by reg Current bugs: -* large fixed-size allocas not correct, although should - be closer to working. Added code in PPCRegisterInfo.cpp - to do >16bit subtractions to the stack pointer. * ulong to double. ahhh, here's the problem: floatdidf assumes signed longs. so if the high but of a ulong just happens to be set, you get the wrong sign. The fix for this @@ -25,19 +22,14 @@ * linking llvmg++ .s files with gcc instead of g++ Codegen improvements needed: -* no alias analysis causes us to generate slow code for Shootout/matrix +* PowerPCPEI.cpp needs to save/restore regs in the opposite order * setCondInst needs to know branchless versions of seteq/setne/etc * cast elimination pass (uint -> sbyte -> short, kill the byte -> short) * should hint to the branch select pass that it doesn't need to print the second unconditional branch, so we don't end up with things like: -.LBBl42__2E_expand_function_8_21: ; LeafBlock37 - cmplwi cr0, r29, 11 - bne cr0, $+8 b .LBBl42__2E_expand_function_8_674 ; loopentry.24 b .LBBl42__2E_expand_function_8_42 ; NewDefault b .LBBl42__2E_expand_function_8_42 ; NewDefault -* conditional restore of link register (tricky, temporarily backed out - part of first attempt) Current hacks: * lazy insert of GlobalBaseReg definition at front of first MBB @@ -49,7 +41,6 @@ Currently failing tests: * SingleSource `- Regression - | `- 2003-05-22-VarSizeArray | `- casts (ulong to fp failure) `- Benchmarks | `- Shootout-C++ : most programs fail, miscompilations From lattner at cs.uiuc.edu Fri Aug 6 02:45:50 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 02:45:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCPEI.cpp Message-ID: <200408060745.CAA23456@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCPEI.cpp updated: 1.1 -> 1.2 --- Log message: Now without stinky dos newlines! --- Diffs of the changes: (+326 -326) Index: llvm/lib/Target/PowerPC/PowerPCPEI.cpp diff -u llvm/lib/Target/PowerPC/PowerPCPEI.cpp:1.1 llvm/lib/Target/PowerPC/PowerPCPEI.cpp:1.2 --- llvm/lib/Target/PowerPC/PowerPCPEI.cpp:1.1 Fri Aug 6 01:58:50 2004 +++ llvm/lib/Target/PowerPC/PowerPCPEI.cpp Fri Aug 6 02:45:37 2004 @@ -1,326 +1,326 @@ -//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass is responsible for finalizing the functions frame layout, saving -// callee saved registers, and for emitting prolog & epilog code for the -// function. -// -// This pass must be run after register allocation. After this pass is -// executed, it is illegal to construct MO_FrameIndex operands. -// -//===----------------------------------------------------------------------===// -// -// FIXME: The contents of this file should be merged with the target generic -// CodeGen/PrologEpilogInserter.cpp -// -//===----------------------------------------------------------------------===// - -#include "PowerPC.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/MRegisterInfo.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "Support/Debug.h" -using namespace llvm; - -namespace { - struct PPCPEI : public MachineFunctionPass { - const char *getPassName() const { - return "PowerPC Frame Finalization & Prolog/Epilog Insertion"; - } - - /// runOnMachineFunction - Insert prolog/epilog code and replace abstract - /// frame indexes with appropriate references. - /// - bool runOnMachineFunction(MachineFunction &Fn) { - RegsToSave.clear(); - StackSlots.clear(); - - // Scan the function for modified caller saved registers and insert spill - // code for any caller saved registers that are modified. Also calculate - // the MaxCallFrameSize and HasCalls variables for the function's frame - // information and eliminates call frame pseudo instructions. - calculateCallerSavedRegisters(Fn); - - // Calculate actual frame offsets for all of the abstract stack objects... - calculateFrameObjectOffsets(Fn); - - // Add prolog and epilog code to the function. - insertPrologEpilogCode(Fn); - - // Add register spills and fills before prolog and after epilog so that in - // the event of a very large fixed size alloca, we don't have to do - // anything weird. - saveCallerSavedRegisters(Fn); - - // Replace all MO_FrameIndex operands with physical register references - // and actual offsets. - // - replaceFrameIndices(Fn); - return true; - } - - private: - std::vector RegsToSave; - std::vector StackSlots; - - void calculateCallerSavedRegisters(MachineFunction &Fn); - void saveCallerSavedRegisters(MachineFunction &Fn); - void calculateFrameObjectOffsets(MachineFunction &Fn); - void replaceFrameIndices(MachineFunction &Fn); - void insertPrologEpilogCode(MachineFunction &Fn); - }; -} - - -/// createPowerPCPEI - This function returns a pass that inserts -/// prolog and epilog code, and eliminates abstract frame references. -/// -FunctionPass *llvm::createPowerPCPEI() { return new PPCPEI(); } - - -/// calculateCallerSavedRegisters - Scan the function for modified caller saved -/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for -/// the function's frame information and eliminates call frame pseudo -/// instructions. -/// -void PPCPEI::calculateCallerSavedRegisters(MachineFunction &Fn) { - const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); - const TargetFrameInfo &FrameInfo = *Fn.getTarget().getFrameInfo(); - - // Get the callee saved register list... - const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); - - // Get the function call frame set-up and tear-down instruction opcode - int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); - int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); - - // Early exit for targets which have no callee saved registers and no call - // frame setup/destroy pseudo instructions. - if ((CSRegs == 0 || CSRegs[0] == 0) && - FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) - return; - - // This bitset contains an entry for each physical register for the target... - std::vector ModifiedRegs(RegInfo->getNumRegs()); - unsigned MaxCallFrameSize = 0; - bool HasCalls = false; - - for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) - for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) - if (I->getOpcode() == FrameSetupOpcode || - I->getOpcode() == FrameDestroyOpcode) { - assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" - " instructions should have a single immediate argument!"); - unsigned Size = I->getOperand(0).getImmedValue(); - if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; - HasCalls = true; - RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); - } else { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - MachineOperand &MO = I->getOperand(i); - if (MO.isRegister() && MO.isDef()) { - assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Register allocation must be performed!"); - ModifiedRegs[MO.getReg()] = true; // Register is modified - } - } - ++I; - } - - MachineFrameInfo *FFI = Fn.getFrameInfo(); - FFI->setHasCalls(HasCalls); - FFI->setMaxCallFrameSize(MaxCallFrameSize); - - // Now figure out which *callee saved* registers are modified by the current - // function, thus needing to be saved and restored in the prolog/epilog. - // - for (unsigned i = 0; CSRegs[i]; ++i) { - unsigned Reg = CSRegs[i]; - if (ModifiedRegs[Reg]) { - RegsToSave.push_back(Reg); // If modified register... - } else { - for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); - *AliasSet; ++AliasSet) { // Check alias registers too... - if (ModifiedRegs[*AliasSet]) { - RegsToSave.push_back(Reg); - break; - } - } - } - } - - // FIXME: should we sort the regs to save so that we always get the regs in - // the correct order? - - // Now that we know which registers need to be saved and restored, allocate - // stack slots for them. - int Offset = 0; - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - unsigned RegSize = RegInfo->getRegClass(RegsToSave[i])->getSize(); - int FrameIdx; - - if (RegsToSave[i] == PPC32::LR) { - FrameIdx = FFI->CreateFixedObject(RegSize, 8); // LR lives at +8 - } else { - Offset -= RegSize; - FrameIdx = FFI->CreateFixedObject(RegSize, Offset); - } - StackSlots.push_back(FrameIdx); - } -} - - -/// saveCallerSavedRegisters - Insert spill code for any caller saved registers -/// that are modified in the function. -/// -void PPCPEI::saveCallerSavedRegisters(MachineFunction &Fn) { - // Early exit if no caller saved registers are modified! - if (RegsToSave.empty()) - return; - - const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); - - // Now that we have a stack slot for each register to be saved, insert spill - // code into the entry block... - MachineBasicBlock *MBB = Fn.begin(); - MachineBasicBlock::iterator I = MBB->begin(); - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); - // Insert the spill to the stack frame... - RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], RC); - } - - // Add code to restore the callee-save registers in each exiting block. - const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); - for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) { - // If last instruction is a return instruction, add an epilogue - if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { - MBB = FI; - I = MBB->end(); --I; - - for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i], RC); - --I; // Insert in reverse order - } - } - } -} - - -/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the -/// abstract stack objects... -/// -void PPCPEI::calculateFrameObjectOffsets(MachineFunction &Fn) { - const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); - - bool StackGrowsDown = - TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; - - // Loop over all of the stack objects, assigning sequential addresses... - MachineFrameInfo *FFI = Fn.getFrameInfo(); - - unsigned StackAlignment = TFI.getStackAlignment(); - - // Start at the beginning of the local area. - // The Offset is the distance from the stack top in the direction - // of stack growth -- so it's always positive. - int Offset = TFI.getOffsetOfLocalArea(); - if (StackGrowsDown) - Offset = -Offset; - assert(Offset >= 0 - && "Local area offset should be in direction of stack growth"); - - // If there are fixed sized objects that are preallocated in the local area, - // non-fixed objects can't be allocated right at the start of local area. - // We currently don't support filling in holes in between fixed sized objects, - // so we adjust 'Offset' to point to the end of last fixed sized - // preallocated object. - for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { - int FixedOff; - if (StackGrowsDown) { - // The maximum distance from the stack pointer is at lower address of - // the object -- which is given by offset. For down growing stack - // the offset is negative, so we negate the offset to get the distance. - FixedOff = -FFI->getObjectOffset(i); - } else { - // The maximum distance from the start pointer is at the upper - // address of the object. - FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); - } - if (FixedOff > Offset) Offset = FixedOff; - } - - for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { - // If stack grows down, we need to add size of find the lowest - // address of the object. - if (StackGrowsDown) - Offset += FFI->getObjectSize(i); - - unsigned Align = FFI->getObjectAlignment(i); - assert(Align <= StackAlignment && "Cannot align stack object to higher " - "alignment boundary than the stack itself!"); - Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... - - if (StackGrowsDown) { - FFI->setObjectOffset(i, -Offset); // Set the computed offset - } else { - FFI->setObjectOffset(i, Offset); - Offset += FFI->getObjectSize(i); - } - } - - // Set the final value of the stack pointer... - FFI->setStackSize(Offset); -} - - -/// insertPrologEpilogCode - Scan the function for modified caller saved -/// registers, insert spill code for these caller saved registers, then add -/// prolog and epilog code to the function. -/// -void PPCPEI::insertPrologEpilogCode(MachineFunction &Fn) { - // Add prologue to the function... - Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); - - // Add epilogue to restore the callee-save registers in each exiting block - const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); - for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { - // If last instruction is a return instruction, add an epilogue - if (!I->empty() && TII.isReturn(I->back().getOpcode())) - Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); - } -} - - -/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical -/// register references and actual offsets. -/// -void PPCPEI::replaceFrameIndices(MachineFunction &Fn) { - if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? - - const TargetMachine &TM = Fn.getTarget(); - assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); - const MRegisterInfo &MRI = *TM.getRegisterInfo(); - - for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) - for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (I->getOperand(i).isFrameIndex()) { - // If this instruction has a FrameIndex operand, we need to use that - // target machine register info object to eliminate it. - MRI.eliminateFrameIndex(Fn, I); - break; - } -} +//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass is responsible for finalizing the functions frame layout, saving +// callee saved registers, and for emitting prolog & epilog code for the +// function. +// +// This pass must be run after register allocation. After this pass is +// executed, it is illegal to construct MO_FrameIndex operands. +// +//===----------------------------------------------------------------------===// +// +// FIXME: The contents of this file should be merged with the target generic +// CodeGen/PrologEpilogInserter.cpp +// +//===----------------------------------------------------------------------===// + +#include "PowerPC.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "Support/Debug.h" +using namespace llvm; + +namespace { + struct PPCPEI : public MachineFunctionPass { + const char *getPassName() const { + return "PowerPC Frame Finalization & Prolog/Epilog Insertion"; + } + + /// runOnMachineFunction - Insert prolog/epilog code and replace abstract + /// frame indexes with appropriate references. + /// + bool runOnMachineFunction(MachineFunction &Fn) { + RegsToSave.clear(); + StackSlots.clear(); + + // Scan the function for modified caller saved registers and insert spill + // code for any caller saved registers that are modified. Also calculate + // the MaxCallFrameSize and HasCalls variables for the function's frame + // information and eliminates call frame pseudo instructions. + calculateCallerSavedRegisters(Fn); + + // Calculate actual frame offsets for all of the abstract stack objects... + calculateFrameObjectOffsets(Fn); + + // Add prolog and epilog code to the function. + insertPrologEpilogCode(Fn); + + // Add register spills and fills before prolog and after epilog so that in + // the event of a very large fixed size alloca, we don't have to do + // anything weird. + saveCallerSavedRegisters(Fn); + + // Replace all MO_FrameIndex operands with physical register references + // and actual offsets. + // + replaceFrameIndices(Fn); + return true; + } + + private: + std::vector RegsToSave; + std::vector StackSlots; + + void calculateCallerSavedRegisters(MachineFunction &Fn); + void saveCallerSavedRegisters(MachineFunction &Fn); + void calculateFrameObjectOffsets(MachineFunction &Fn); + void replaceFrameIndices(MachineFunction &Fn); + void insertPrologEpilogCode(MachineFunction &Fn); + }; +} + + +/// createPowerPCPEI - This function returns a pass that inserts +/// prolog and epilog code, and eliminates abstract frame references. +/// +FunctionPass *llvm::createPowerPCPEI() { return new PPCPEI(); } + + +/// calculateCallerSavedRegisters - Scan the function for modified caller saved +/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for +/// the function's frame information and eliminates call frame pseudo +/// instructions. +/// +void PPCPEI::calculateCallerSavedRegisters(MachineFunction &Fn) { + const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + const TargetFrameInfo &FrameInfo = *Fn.getTarget().getFrameInfo(); + + // Get the callee saved register list... + const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); + + // Get the function call frame set-up and tear-down instruction opcode + int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); + int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); + + // Early exit for targets which have no callee saved registers and no call + // frame setup/destroy pseudo instructions. + if ((CSRegs == 0 || CSRegs[0] == 0) && + FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) + return; + + // This bitset contains an entry for each physical register for the target... + std::vector ModifiedRegs(RegInfo->getNumRegs()); + unsigned MaxCallFrameSize = 0; + bool HasCalls = false; + + for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) + for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) + if (I->getOpcode() == FrameSetupOpcode || + I->getOpcode() == FrameDestroyOpcode) { + assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" + " instructions should have a single immediate argument!"); + unsigned Size = I->getOperand(0).getImmedValue(); + if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; + HasCalls = true; + RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); + } else { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + MachineOperand &MO = I->getOperand(i); + if (MO.isRegister() && MO.isDef()) { + assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && + "Register allocation must be performed!"); + ModifiedRegs[MO.getReg()] = true; // Register is modified + } + } + ++I; + } + + MachineFrameInfo *FFI = Fn.getFrameInfo(); + FFI->setHasCalls(HasCalls); + FFI->setMaxCallFrameSize(MaxCallFrameSize); + + // Now figure out which *callee saved* registers are modified by the current + // function, thus needing to be saved and restored in the prolog/epilog. + // + for (unsigned i = 0; CSRegs[i]; ++i) { + unsigned Reg = CSRegs[i]; + if (ModifiedRegs[Reg]) { + RegsToSave.push_back(Reg); // If modified register... + } else { + for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); + *AliasSet; ++AliasSet) { // Check alias registers too... + if (ModifiedRegs[*AliasSet]) { + RegsToSave.push_back(Reg); + break; + } + } + } + } + + // FIXME: should we sort the regs to save so that we always get the regs in + // the correct order? + + // Now that we know which registers need to be saved and restored, allocate + // stack slots for them. + int Offset = 0; + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + unsigned RegSize = RegInfo->getRegClass(RegsToSave[i])->getSize(); + int FrameIdx; + + if (RegsToSave[i] == PPC32::LR) { + FrameIdx = FFI->CreateFixedObject(RegSize, 8); // LR lives at +8 + } else { + Offset -= RegSize; + FrameIdx = FFI->CreateFixedObject(RegSize, Offset); + } + StackSlots.push_back(FrameIdx); + } +} + + +/// saveCallerSavedRegisters - Insert spill code for any caller saved registers +/// that are modified in the function. +/// +void PPCPEI::saveCallerSavedRegisters(MachineFunction &Fn) { + // Early exit if no caller saved registers are modified! + if (RegsToSave.empty()) + return; + + const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + + // Now that we have a stack slot for each register to be saved, insert spill + // code into the entry block... + MachineBasicBlock *MBB = Fn.begin(); + MachineBasicBlock::iterator I = MBB->begin(); + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); + // Insert the spill to the stack frame... + RegInfo->storeRegToStackSlot(*MBB, I, RegsToSave[i], StackSlots[i], RC); + } + + // Add code to restore the callee-save registers in each exiting block. + const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); + for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) { + // If last instruction is a return instruction, add an epilogue + if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { + MBB = FI; + I = MBB->end(); --I; + + for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { + const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i], RC); + --I; // Insert in reverse order + } + } + } +} + + +/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the +/// abstract stack objects... +/// +void PPCPEI::calculateFrameObjectOffsets(MachineFunction &Fn) { + const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); + + bool StackGrowsDown = + TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; + + // Loop over all of the stack objects, assigning sequential addresses... + MachineFrameInfo *FFI = Fn.getFrameInfo(); + + unsigned StackAlignment = TFI.getStackAlignment(); + + // Start at the beginning of the local area. + // The Offset is the distance from the stack top in the direction + // of stack growth -- so it's always positive. + int Offset = TFI.getOffsetOfLocalArea(); + if (StackGrowsDown) + Offset = -Offset; + assert(Offset >= 0 + && "Local area offset should be in direction of stack growth"); + + // If there are fixed sized objects that are preallocated in the local area, + // non-fixed objects can't be allocated right at the start of local area. + // We currently don't support filling in holes in between fixed sized objects, + // so we adjust 'Offset' to point to the end of last fixed sized + // preallocated object. + for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { + int FixedOff; + if (StackGrowsDown) { + // The maximum distance from the stack pointer is at lower address of + // the object -- which is given by offset. For down growing stack + // the offset is negative, so we negate the offset to get the distance. + FixedOff = -FFI->getObjectOffset(i); + } else { + // The maximum distance from the start pointer is at the upper + // address of the object. + FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); + } + if (FixedOff > Offset) Offset = FixedOff; + } + + for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { + // If stack grows down, we need to add size of find the lowest + // address of the object. + if (StackGrowsDown) + Offset += FFI->getObjectSize(i); + + unsigned Align = FFI->getObjectAlignment(i); + assert(Align <= StackAlignment && "Cannot align stack object to higher " + "alignment boundary than the stack itself!"); + Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... + + if (StackGrowsDown) { + FFI->setObjectOffset(i, -Offset); // Set the computed offset + } else { + FFI->setObjectOffset(i, Offset); + Offset += FFI->getObjectSize(i); + } + } + + // Set the final value of the stack pointer... + FFI->setStackSize(Offset); +} + + +/// insertPrologEpilogCode - Scan the function for modified caller saved +/// registers, insert spill code for these caller saved registers, then add +/// prolog and epilog code to the function. +/// +void PPCPEI::insertPrologEpilogCode(MachineFunction &Fn) { + // Add prologue to the function... + Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); + + // Add epilogue to restore the callee-save registers in each exiting block + const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); + for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { + // If last instruction is a return instruction, add an epilogue + if (!I->empty() && TII.isReturn(I->back().getOpcode())) + Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); + } +} + + +/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical +/// register references and actual offsets. +/// +void PPCPEI::replaceFrameIndices(MachineFunction &Fn) { + if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? + + const TargetMachine &TM = Fn.getTarget(); + assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); + const MRegisterInfo &MRI = *TM.getRegisterInfo(); + + for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) + for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (I->getOperand(i).isFrameIndex()) { + // If this instruction has a FrameIndex operand, we need to use that + // target machine register info object to eliminate it. + MRI.eliminateFrameIndex(Fn, I); + break; + } +} From lattner at cs.uiuc.edu Fri Aug 6 02:56:27 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 02:56:27 -0500 Subject: [llvm-commits] CVS: llvm-www/RandomBoxes/007-Bugpoint.html Message-ID: <200408060756.CAA23503@apoc.cs.uiuc.edu> Changes in directory llvm-www/RandomBoxes: 007-Bugpoint.html updated: 1.4 -> 1.5 --- Log message: Fix broken link --- Diffs of the changes: (+1 -1) Index: llvm-www/RandomBoxes/007-Bugpoint.html diff -u llvm-www/RandomBoxes/007-Bugpoint.html:1.4 llvm-www/RandomBoxes/007-Bugpoint.html:1.5 --- llvm-www/RandomBoxes/007-Bugpoint.html:1.4 Tue Jun 1 23:12:17 2004 +++ llvm-www/RandomBoxes/007-Bugpoint.html Fri Aug 6 02:56:17 2004 @@ -1,3 +1,3 @@ -Bugpoint is an automated testcase reduction tool that is extremely useful for debugging problems in LLVM optimizers and code generators. It can usually reduce an optimizer crash down to the few instructions needed to reproduce the problem or a miscompilation down to the specific loop nest or basic block in the program that is being miscompiled. +Bugpoint is an automated testcase reduction tool that is extremely useful for debugging problems in LLVM optimizers and code generators. It can usually reduce an optimizer crash down to the few instructions needed to reproduce the problem or a miscompilation down to the specific loop nest or basic block in the program that is being miscompiled. From alkis at cs.uiuc.edu Fri Aug 6 06:04:39 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:04:39 -0500 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200408061104.GAA27529@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.18 -> 1.19 --- Log message: Add convinience methods for accessing Constants from the constant pool. --- Diffs of the changes: (+5 -0) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.18 llvm-java/include/llvm/Java/ClassFile.h:1.19 --- llvm-java/include/llvm/Java/ClassFile.h:1.18 Wed Aug 4 05:02:03 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Fri Aug 6 06:04:28 2004 @@ -31,6 +31,8 @@ class ExceptionsAttribute; class Constant; class ConstantClass; + class ConstantFieldRef; + class ConstantMethodRef; class ConstantNameAndType; class ConstantUtf8; class ClassFile; @@ -78,6 +80,9 @@ uint16_t getMajorVersion() const { return majorV_; } const ConstantPool& getConstantPool() const { return cPool_; } + ConstantMethodRef* getConstantMethodRef(unsigned index) const; + ConstantFieldRef* getConstantFieldRef(unsigned index) const; + Constant* getConstant(unsigned index) const { return cPool_[index]; } bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } bool isFinal() const { return accessFlags_ & ACC_FINAL; } From alkis at cs.uiuc.edu Fri Aug 6 06:04:39 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:04:39 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200408061104.GAA27530@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.21 -> 1.22 --- Log message: Add convinience methods for accessing Constants from the constant pool. --- Diffs of the changes: (+14 -0) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.21 llvm-java/lib/ClassFile/ClassFile.cpp:1.22 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.21 Wed Aug 4 05:02:03 2004 +++ llvm-java/lib/ClassFile/ClassFile.cpp Fri Aug 6 06:04:28 2004 @@ -244,6 +244,20 @@ (*i)->getName()->str() + (*i)->getDescriptor()->str(), *i)); } +ConstantMethodRef* ClassFile::getConstantMethodRef(unsigned index) const +{ + assert(dynamic_cast(getConstant(index)) && + "Constant is not a ConstantMethodRef!"); + return static_cast(getConstant(index)); +} + +ConstantFieldRef* ClassFile::getConstantFieldRef(unsigned index) const +{ + assert(dynamic_cast(getConstant(index)) && + "Constant is not a ConstantFieldRef!"); + return static_cast(getConstant(index)); +} + Method* ClassFile::getMethod(const std::string& nameAndDescr) const { Name2MethodMap::const_iterator it = n2mMap_.find(nameAndDescr); From alkis at cs.uiuc.edu Fri Aug 6 06:06:16 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:06:16 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061106.GAA27615@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.78 -> 1.79 --- Log message: Do not use ClassFile::getConstantPool(). Use the newly added getConstant*() member functions. --- Diffs of the changes: (+5 -10) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.78 llvm-java/lib/Compiler/Compiler.cpp:1.79 --- llvm-java/lib/Compiler/Compiler.cpp:1.78 Thu Aug 5 13:56:55 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 06:06:06 2004 @@ -342,7 +342,6 @@ init.resize(elements.size(), NULL); } init[index] = vfun; - DEBUG(std::cerr << index << " = " << methodDescr << '\n'); } } @@ -365,8 +364,7 @@ } GlobalVariable* getStaticField(unsigned index) { - ConstantFieldRef* fieldRef = - (ConstantFieldRef*)(cf_->getConstantPool()[index]); + ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); std::string globalName = @@ -380,8 +378,7 @@ } Value* getField(unsigned bcI, unsigned index, Value* ptr) { - ConstantFieldRef* fieldRef = - (ConstantFieldRef*)(cf_->getConstantPool()[index]); + ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); return getField(bcI, @@ -568,7 +565,7 @@ } void do_ldc(unsigned bcI, unsigned index) { - Constant* c = cf_->getConstantPool()[index]; + Constant* c = cf_->getConstant(index); assert(getConstant(c) && "Java constant not handled!"); opStack_.push(getConstant(c)); } @@ -926,8 +923,7 @@ } void do_invokevirtual(unsigned bcI, unsigned index) { - ConstantMethodRef* methodRef = - (ConstantMethodRef*)(cf_->getConstantPool()[index]); + ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); ConstantNameAndType* nameAndType = methodRef->getNameAndType(); const std::string className = methodRef->getClass()->getName()->str(); @@ -960,8 +956,7 @@ } void do_invokestatic(unsigned bcI, unsigned index) { - ConstantMethodRef* methodRef = - (ConstantMethodRef*)(cf_->getConstantPool()[index]); + ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); ConstantNameAndType* nameAndType = methodRef->getNameAndType(); std::string funcName = From alkis at cs.uiuc.edu Fri Aug 6 06:07:00 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:07:00 -0500 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200408061107.GAA27647@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.19 -> 1.20 --- Log message: Remove ClassFile::getConstantPool() member function. --- Diffs of the changes: (+0 -1) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.19 llvm-java/include/llvm/Java/ClassFile.h:1.20 --- llvm-java/include/llvm/Java/ClassFile.h:1.19 Fri Aug 6 06:04:28 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Fri Aug 6 06:06:49 2004 @@ -79,7 +79,6 @@ uint16_t getMinorVersion() const { return minorV_; } uint16_t getMajorVersion() const { return majorV_; } - const ConstantPool& getConstantPool() const { return cPool_; } ConstantMethodRef* getConstantMethodRef(unsigned index) const; ConstantFieldRef* getConstantFieldRef(unsigned index) const; Constant* getConstant(unsigned index) const { return cPool_[index]; } From alkis at cs.uiuc.edu Fri Aug 6 06:25:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:25:02 -0500 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200408061125.GAA29793@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.20 -> 1.21 --- Log message: Add convinience member function to easily get ConstantClass objects from the constant pool. --- Diffs of the changes: (+3 -2) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.20 llvm-java/include/llvm/Java/ClassFile.h:1.21 --- llvm-java/include/llvm/Java/ClassFile.h:1.20 Fri Aug 6 06:06:49 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Fri Aug 6 06:24:52 2004 @@ -79,9 +79,10 @@ uint16_t getMinorVersion() const { return minorV_; } uint16_t getMajorVersion() const { return majorV_; } - ConstantMethodRef* getConstantMethodRef(unsigned index) const; - ConstantFieldRef* getConstantFieldRef(unsigned index) const; Constant* getConstant(unsigned index) const { return cPool_[index]; } + ConstantClass* getConstantClass(unsigned index) const; + ConstantFieldRef* getConstantFieldRef(unsigned index) const; + ConstantMethodRef* getConstantMethodRef(unsigned index) const; bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } bool isFinal() const { return accessFlags_ & ACC_FINAL; } From alkis at cs.uiuc.edu Fri Aug 6 06:25:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:25:02 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200408061125.GAA29796@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.22 -> 1.23 --- Log message: Add convinience member function to easily get ConstantClass objects from the constant pool. --- Diffs of the changes: (+11 -4) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.22 llvm-java/lib/ClassFile/ClassFile.cpp:1.23 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.22 Fri Aug 6 06:04:28 2004 +++ llvm-java/lib/ClassFile/ClassFile.cpp Fri Aug 6 06:24:52 2004 @@ -244,11 +244,11 @@ (*i)->getName()->str() + (*i)->getDescriptor()->str(), *i)); } -ConstantMethodRef* ClassFile::getConstantMethodRef(unsigned index) const +ConstantClass* ClassFile::getConstantClass(unsigned index) const { - assert(dynamic_cast(getConstant(index)) && - "Constant is not a ConstantMethodRef!"); - return static_cast(getConstant(index)); + assert(dynamic_cast(getConstant(index)) && + "Constant is not a ConstantClass!"); + return static_cast(getConstant(index)); } ConstantFieldRef* ClassFile::getConstantFieldRef(unsigned index) const @@ -258,6 +258,13 @@ return static_cast(getConstant(index)); } +ConstantMethodRef* ClassFile::getConstantMethodRef(unsigned index) const +{ + assert(dynamic_cast(getConstant(index)) && + "Constant is not a ConstantMethodRef!"); + return static_cast(getConstant(index)); +} + Method* ClassFile::getMethod(const std::string& nameAndDescr) const { Name2MethodMap::const_iterator it = n2mMap_.find(nameAndDescr); From alkis at cs.uiuc.edu Fri Aug 6 06:25:50 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 06:25:50 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061125.GAA29884@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.79 -> 1.80 --- Log message: Implement the 'new' java bytecode. --- Diffs of the changes: (+14 -1) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.79 llvm-java/lib/Compiler/Compiler.cpp:1.80 --- llvm-java/lib/Compiler/Compiler.cpp:1.79 Fri Aug 6 06:06:06 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 06:25:39 2004 @@ -976,7 +976,20 @@ } void do_new(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); + ConstantClass* classRef = cf_->getConstantClass(index); + const std::string& className = classRef->getName()->str(); + ClassFile* cf = ClassFile::getClassFile(className); + const ClassInfo& ci = getClassInfo(className); + const VTableInfo& vi = getVTableInfo(className); + + Value* objRef = new MallocInst(ci.type, + ConstantUInt::get(Type::UIntTy, 0), + TMP, getBBAt(bcI)); + Value* vtable = getField(bcI, className, "", objRef); + vtable = new CastInst(vtable, PointerType::get(vi.vtable->getType()), + TMP, getBBAt(bcI)); + vtable = new StoreInst(vi.vtable, vtable, getBBAt(bcI)); + opStack_.push(objRef); } void do_newarray(unsigned bcI, JType type) { From alkis at cs.uiuc.edu Fri Aug 6 09:33:47 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 09:33:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Instructions.cpp Message-ID: <200408061433.JAA03674@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Instructions.cpp updated: 1.1 -> 1.2 --- Log message: Split assertion to two in order to give better assertion messages. --- Diffs of the changes: (+3 -3) Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.1 llvm/lib/VMCore/Instructions.cpp:1.2 --- llvm/lib/VMCore/Instructions.cpp:1.1 Thu Jul 29 07:33:25 2004 +++ llvm/lib/VMCore/Instructions.cpp Fri Aug 6 09:33:37 2004 @@ -416,9 +416,9 @@ } void StoreInst::init(Value *Val, Value *Ptr) { - assert(isa(Ptr->getType()) && - Val->getType() == cast(Ptr->getType())->getElementType() - && "Ptr must have pointer type."); + assert(isa(Ptr->getType()) && "Ptr must have pointer type!"); + assert(Val->getType() == cast(Ptr->getType())->getElementType() + && "Ptr must be a pointer to Val type!"); Operands.reserve(2); Operands.push_back(Use(Val, this)); From alkis at cs.uiuc.edu Fri Aug 6 09:45:18 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 09:45:18 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061445.JAA03764@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.80 -> 1.81 --- Log message: Fix problem with stores through pointers to superclasses. --- Diffs of the changes: (+7 -5) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.80 llvm-java/lib/Compiler/Compiler.cpp:1.81 --- llvm-java/lib/Compiler/Compiler.cpp:1.80 Fri Aug 6 06:25:39 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 09:45:07 2004 @@ -580,13 +580,15 @@ } void do_store(unsigned bcI, JType type, unsigned index) { - Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push( - new StoreInst(v1, getOrCreateLocal(index, getType(type)), - getBBAt(bcI))); + Value* val = opStack_.top(); opStack_.pop(); + const Type* valTy = val->getType(); + Value* ptr = getOrCreateLocal(index, getType(type)); + if (!valTy->isPrimitiveType() && + valTy != cast(ptr->getType())->getElementType()) + ptr = new CastInst(ptr, PointerType::get(valTy), TMP, getBBAt(bcI)); + opStack_.push(new StoreInst(val, ptr, getBBAt(bcI))); } - void do_astore(unsigned bcI, JType type) { assert(0 && "not implemented"); } From alkis at cs.uiuc.edu Fri Aug 6 10:13:16 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 10:13:16 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061513.KAA04093@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.81 -> 1.82 --- Log message: Fix bug where types of overriden functions mismatched. --- Diffs of the changes: (+11 -7) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.81 llvm-java/lib/Compiler/Compiler.cpp:1.82 --- llvm-java/lib/Compiler/Compiler.cpp:1.81 Fri Aug 6 09:45:07 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 10:13:05 2004 @@ -330,17 +330,21 @@ std::string methodDescr = method->getName()->str() + method->getDescriptor()->str(); - unsigned& index = vi.m2iMap[methodDescr]; - Function* vfun = module_->getOrInsertFunction - (className + '/' + methodDescr, - cast(getType(method->getDescriptor(), - getClassInfo(className).type))); + + std::string funcName = className + '/' + methodDescr; + const FunctionType* funcTy = cast( + getType(method->getDescriptor(), getClassInfo(className).type)); + + Function* vfun = module_->getOrInsertFunction(funcName, funcTy); toCompileFunctions_.insert(vfun); + + unsigned& index = vi.m2iMap[methodDescr]; if (!index) { index = elements.size(); - elements.push_back(vfun->getType()); - init.resize(elements.size(), NULL); + elements.resize(index + 1, NULL); + init.resize(index + 1, NULL); } + elements[index] = vfun->getType(); init[index] = vfun; } } From alkis at cs.uiuc.edu Fri Aug 6 10:16:25 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 10:16:25 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061516.KAA04213@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.82 -> 1.83 --- Log message: Do not give a name to a void return value. This causes an assert :-) --- Diffs of the changes: (+5 -2) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.82 llvm-java/lib/Compiler/Compiler.cpp:1.83 --- llvm-java/lib/Compiler/Compiler.cpp:1.82 Fri Aug 6 10:13:05 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 10:16:14 2004 @@ -923,9 +923,12 @@ p->getType() == paramTy ? p : new CastInst(p, paramTy, TMP, bb); } - Value* r = new CallInst(fun, params, TMP, bb); - if (funTy->getReturnType() != Type::VoidTy) + if (funTy->getReturnType() == Type::VoidTy) + new CallInst(fun, params, "", bb); + else { + Value* r = new CallInst(fun, params, TMP, bb); opStack_.push(r); + } } void do_invokevirtual(unsigned bcI, unsigned index) { From alkis at cs.uiuc.edu Fri Aug 6 10:19:13 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 6 Aug 2004 10:19:13 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408061519.KAA04265@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.83 -> 1.84 --- Log message: Implement constructor calls through the invokespecial bytecode. Calling the superclass' method (another use of invokespecial) is yet unimplemented. --- Diffs of the changes: (+22 -1) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.83 llvm-java/lib/Compiler/Compiler.cpp:1.84 --- llvm-java/lib/Compiler/Compiler.cpp:1.83 Fri Aug 6 10:16:14 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Aug 6 10:19:03 2004 @@ -961,7 +961,28 @@ } void do_invokespecial(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); + ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); + ConstantNameAndType* nameAndType = methodRef->getNameAndType(); + + const std::string& className = methodRef->getClass()->getName()->str(); + const std::string& methodName = nameAndType->getName()->str(); + const std::string& methodDescr = + methodName + nameAndType->getDescriptor()->str(); + std::string funcName = className + '/' + methodDescr; + + const ClassInfo& ci = getClassInfo(className); + // constructor calls are statically bound + if (methodName == "") { + FunctionType* funcType = + cast(getType(nameAndType->getDescriptor(), ci.type)); + Function* function = module_->getOrInsertFunction(funcName, funcType); + toCompileFunctions_.insert(function); + makeCall(function, getBBAt(bcI)); + } + // otherwise we call the superclass' implementation of the method + else { + assert(0 && "not implemented"); + } } void do_invokestatic(unsigned bcI, unsigned index) { From criswell at cs.uiuc.edu Fri Aug 6 11:21:58 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 11:21:58 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/llvm.spec Message-ID: <200408061621.LAA22222@zion.cs.uiuc.edu> Changes in directory llvm: llvm.spec updated: 1.1 -> 1.1.8.1 --- Log message: Updated version. --- Diffs of the changes: (+1 -1) Index: llvm/llvm.spec diff -u llvm/llvm.spec:1.1 llvm/llvm.spec:1.1.8.1 --- llvm/llvm.spec:1.1 Mon Feb 9 21:57:51 2004 +++ llvm/llvm.spec Fri Aug 6 11:21:48 2004 @@ -1,6 +1,6 @@ Summary: Static and JIT research compiler infrastructure Name: llvm -Version: 1.2 +Version: 1.3 Release: 0 License: U of Illinois/NCSA Open Source License Group: Development/Languages From criswell at cs.uiuc.edu Fri Aug 6 11:41:19 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 11:41:19 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/test/QMTest/expectations.darwin.qmr expectations.sunos.qmr Message-ID: <200408061641.LAA22317@zion.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.darwin.qmr updated: 1.5 -> 1.5.2.1 expectations.sunos.qmr updated: 1.12 -> 1.12.2.1 --- Log message: Updated expectations to match the current set of XPass's. --- Diffs of the changes: (+2 -2) Index: llvm/test/QMTest/expectations.darwin.qmr diff -u llvm/test/QMTest/expectations.darwin.qmr:1.5 llvm/test/QMTest/expectations.darwin.qmr:1.5.2.1 --- llvm/test/QMTest/expectations.darwin.qmr:1.5 Mon Aug 2 10:12:29 2004 +++ llvm/test/QMTest/expectations.darwin.qmr Fri Aug 6 11:41:09 2004 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U>Regression.Transforms.LevelRaise.2002-05-02-BadCastEliminationq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-! PredecessorProblemq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U1Regression.CFrontend.2002-03-12-StructInitializerqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhUPASSqWh}h U$Regression.BugPoint.misopt-basictestqXh (h o}qY(h}h}ubub.(hoqZ}q[(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemq\h (h o}q](h}h}ubub.(hoq^}q_(hhhhh}h U)Regression.Transforms.Reassociate.subtestq`h (h o}qa(h}h}! ubub.(hoqb}qc(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExp rqdh (h o}qe(h}h}ubub.(hoqf}qg(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveqhh (h o}qi(h}h}ubub.(hoqj}qk(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqlh (h o}qm(h}h}ubub.(hoqn}qo(hhhhh}h U>Regression.Transforms.InstCombine.2003-06-22-ConstantExprCrashqph (h o}qq(h}h}ubub.(hoqr}qs(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqth (h o}qu(h}h}ubub.(hoqv}qw(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqxh (h o}qy(h}h}ubub.(hoqz}q{(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestq|h (h o}q}(h}h}ubub.(hoq~}q(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.Transforms.LevelRaise.2002-05-02-BadCastEliminationq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-! PredecessorProblemq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U1Regression.CFrontend.2002-03-12-StructInitializerqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U)Regression.Transforms.Reassociate.subtestq_h (h o}q`(h}! h}ubub.(hoqa}qb(hhhhh}h U)Regression.Linker.2002-08-20-Constant Exprqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2q{h (h o}q|(h}h}ubub.(hoq}}q~(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqh (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h! UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemqc h (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U(hhhhh}h U Regression.Reoptimizer.ticm.ticmq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemq_! h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3Regression.Transforms.Pi NodeInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U Changes in directory llvm/test/Programs/External: Makefile updated: 1.7 -> 1.7.6.1 --- Log message: Make Povray and SPEC parallel. --- Diffs of the changes: (+2 -2) Index: llvm/test/Programs/External/Makefile diff -u llvm/test/Programs/External/Makefile:1.7 llvm/test/Programs/External/Makefile:1.7.6.1 --- llvm/test/Programs/External/Makefile:1.7 Thu Feb 26 23:59:09 2004 +++ llvm/test/Programs/External/Makefile Fri Aug 6 11:42:58 2004 @@ -8,10 +8,10 @@ # # Create the list of directories to compile # -DIRS := SPEC Povray +PARALLEL_DIRS := SPEC Povray ifndef USE_POVRAY -DIRS := $(filter-out Povray/, $(DIRS)) +PARALLEL_DIRS := $(filter-out Povray/, $(PARALLEL_DIRS)) endif include ${LEVEL}/test/Programs/Makefile.programs From reid at x10sys.com Fri Aug 6 11:58:58 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 6 Aug 2004 11:58:58 -0500 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvmc.pod Message-ID: <200408061658.LAA22448@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvmc.pod added (r1.1) --- Log message: First version of a manual page for the llvmc compiler driver. This tool is being documented before being written to foster discussion about what the tool should do. Eventually, we'll achieve a decision point at which time this document forms the requirements for the tool from which it will be coded. --- Diffs of the changes: (+383 -0) Index: llvm/docs/CommandGuide/llvmc.pod diff -c /dev/null llvm/docs/CommandGuide/llvmc.pod:1.1 *** /dev/null Fri Aug 6 11:58:58 2004 --- llvm/docs/CommandGuide/llvmc.pod Fri Aug 6 11:58:48 2004 *************** *** 0 **** --- 1,383 ---- + =pod + + =head1 NAME + + llvmc - The LLVM Compiler Driver + + =head1 SYNOPSIS + + B [I] [I...] + + =head1 DESCRIPTION + + The B command is a configurable driver for invoking other + LLVM (and non-LLVM) tools in order to compile, optimize and link software + for multiple languages. For those familiar with the GNU Compiler + Collection's B tool, it is very similar. This tool has the + following main goals or purposes: + + =over + + =item * A Single point of access to the LLVM tool set. + + =item * Hide the complexities of the LLVM tools through a single interface. + + =item * Make integration of existing non-LLVM tools simple. + + =item * Extend the capabilities of minimal front ends. + + =item * Make the interface for compiling consistent for all languages. + + =back + + The tool itself does nothing with a user's program. It merely invokes other + tools to get the compilation tasks done. + + =head2 Basic Operation + + B always takes the following basic actions: + + =over + + =item * Command line options and filenames are collected. + + This provides the basic instruction to B on what actions it should + take. This is the I the user is making of B. + + =item * Configuration files are read. + + Based on the options and the suffixes of the filenames presented, a set + of configuration files are read to configure the actions B + will take (more on this later). + + =item * Determine actions to take. + + The tool chain needed to complete the task is determined. This is the + primary work of B. It breaks the request specified by the + command line options into a set of basic actions to be done: + pre-processing, compilation, assembly, optimization, and linking. + For each applicable action, it selects the command to be run from + the specifications in the configuration files. + + =item * Execute actions. + + The actions determined previously are executed sequentially and then + B terminates. + + =back + + =head2 Configuration Files + + B is highly configurable both on the command line and in configuration + files. Configuration files specify the details of what commands to run + for a given action. Each front end compiler must provide its own + configuration file to tell B how to invoke that compiler. The LLVM + toolset does not need to be configured as B just "knows" how to + invoke those tools. + + Rest TBD. + + =head1 OPTIONS + + =head2 Control Options + + Control options tell B what to do at a high level. The + following control options are defined: + + =over + + =item B<-c> or B<--compile> + + This option specifies that the linking phase is not to be run. All + previous phases, if applicable will run. This is generally how a given + bytecode file is compiled and optimized for a source language module. + + =item B<-k> or B<--link> or default + + This option (or the lack of any control option) specifies that all stages + of compilation, optimization, and linking should be attempted. Source files + specified on the command line will be compiled and linked with objects and + libraries also specified. + + =item B<-S> or B<--assemble> + + This option specifies that compilation should end in the creation of + an LLVM assembly file that can be later converted to an LLVM object + file. + + =item B<-E> or B<--preprocess> + + This option specifies that no compilation or linking should be + performed. Only pre-processing, if applicabe to the language being + compiled, is performed. For languages that support it, this will + result in the output containing the raw input to the compiler. + + =back + + =head2 Optimization Options + + Optimization with B is based on goals and specified with + the following -O options. The specific details of which + optimizations run is controlled by the configuration files because + each source language will have different needs. + + =over + + =item B<-O1> or B<-O0> (default, fast compilation) + + Only those optimizations that will hasten the compilation (mostly by reducing + the output) are applied. In general these are extremely fast and simple + optimizations that reduce emitted code size. The goal here is not to make the + resulting program fast but to make the compilation fast. If not specified, + this is the default level of optimization. + + =item B<-O2> (basic optimization) + + This level of optimization specifies a balance between generating good code + that will execute reasonably quickly and not spending too much time optimizing + the code to get there. For example, this level of optimization may include + things like global common subexpression elimintation, aggressive dead code + elimination, and scalar replication. + + =item B<-O3> (aggressive optimization) + + This level of optimization aggressively optimizes each set of files compiled + together. However, no link-time inter-procedural optimization is performed. + This level implies all the optimizations of the B<-O1> and B<-O2> optimization + levels, and should also provide loop optimizatiosn and compile time + inter-procedural optimizations. Essentially, this level tries to do as much + as it can with the input it is given but doesn't do any link time IPO. + + =item B<-O4> (linktime optimization) + + In addition to the previous three levels of optimization, this level of + optimization aggressively optimizes each program at link time. It employs + basic analysis and basic link-time inter-procedural optimizations, + considering the program as a whole. + + =item B<-O5> (aggressive linktime optimization) + + This is the same as B<-O4> except it employs aggressive analyses and + aggressive inter-procedural optimization. + + =item B<-O6> (profile guided optimization - not implemented) + + This is the same as B<-O5> except that it employes profile-guided + reoptimization of the program after it has executed. Note that this implies + a single level of reoptimization based on runtime profile analysis. Once + the re-optimization has completed, the profiling instrumentation is + removed and final optimizations are employed. + + =item B<-O7> (lifelong optimization - not implemented) + + This is the same as B<-O5> and similar to B<-O6> except that reoptimization + is performed through the life of the program. That is, each run will update + the profile by which future reoptimizations are directed. + + =back + + =head2 Input Options + + =over + + =item B<-l> I + + This option instructs B to locate a library named I and search + it for unresolved symbols when linking the program. + + =item B<-L> F + + This option instructs B to add F to the list of places in which + the linker will + + =item B<-x> I + + This option instructs B to regard the following input files as + containing programs in the language I. Normally, input file languages + are identified by their suffix but this option will override that default + behavior. The B<-x> option stays in effect until the end of the options or + a new B<-x> option is encountered. + + =back + + =head2 Output Options + + =over + + =item B<-m>I + + This option selects the back end code generator to use. The I portion + of the option names the back end to use. + + =item B<--native> + + Normally, B produces bytecode files at most stages of compilation. + With this option, B will arrange for native object files to be + generated with the B<-c> option, native assembly files to be generated + with the B<-S> option, and native executables to be generated with the + B<--link> option. In the case of the B<-E> option, the output will not + differ as there is no I version of pre-processed output. + + =item B<-o> F + + Specify the output file name. The contents of the file depend on other + options. + + =back + + =head2 Configuration Options + + =over + + =item B<--show-config> I<[suffixes...]> + + When this option is given, the only action taken by B is to show its + final configuration state in the form of a configuration file. No compilation + tasks will be conducted when this option is given; processing will stop once + the configuration has been printed. The optional (comma separated) list of + suffixes controls what is printed. Without any suffixes, the configuration + for all languages is printed. With suffixes, only the languages pertaining + to those file suffixes will be printed. The configuration information is + printed after all command line options and configuration files have been + read and processed. This allows the user to verify that the correct + configuration data has been read by B. + + =item B<--config> :I

    :I=I + + This option instructs B to accept I as the value for configuration + item I in the section named I
    . This is a quick way to override + a configuration item on the command line without resorting to changing the + configuration files. + + =item B<--config-file> F + + This option tells B to read configuration data from the I + named F. Data from such directories will be read in the order + specified on the command line after all other standard config files have + been read. This allows users or groups of users to conveniently create + their own configuration directories in addition to the standard ones to which + they may not have write access. + + =item B<--config-only-from> F + + This option tells B to skip the normal processing of configuration + files and only configure from the contents of the F directory. Multiple + B<--config-only-from> options may be given in which case the directories are + read in the order given on the command line. + + =back + + =head2 Information Options + + =over + + =item B<-n> or B<--noop> + + This option tells B to do everything but actually execute the + resulting tools. In combination with the B<-v> option, this causes B + to merely print out what it would have done. + + =item B<-v> or B<--verbose> + + This option will cause B to print out (on standard output) each of the + actions it takes to accomplish the objective. The output will immediately + precede the invocation of other tools. + + =item B<--stats> + + Print all statistics gathered during the compilation to the standard error. + Note that this option is merely passed through to the sub-tools to do with + as they please. + + =item B<--time-passes> + + Record the amount of time needed for each optimization pass and print it + to standard error. Like B<--stats> this option is just passed through to + the sub-tools to do with as they please. + + =item B<--time-programs> + + Record the amount of time each program (compilation tool) takes and print + it to the standard error. + + =back + + =head2 Language Specific Options + + =over + + + =item B<-Tool,opt>=I + + Pass an arbitrary option to the optimizer. + + =item B<-Tool,link>=I + + Pass an arbitrary option to the linker. + + =item B<-Tool,asm>=I + + Pass an arbitrary optionsto the code generator. + + =back + + =head3 C/C++ Specific Options + + =over + + =item B<-I>F (C/C++ Only) + + This option is just passed through to a C or C++ front end compiler to tell it + where include files can be found. + + =back + + =head2 Advanced Options + + =over + + =item B<--emit-raw-code> + + No optimization is done whatsoever. The compilers invoked by B with + this option given will be instructed to produce raw, unoptimized code. This + option is useful only to front end language developers and therefore does not + participate in the list of B<-O> options. This is distinctly different from + the B<-O0> option (a synonym for B<-O1>) because those optimizations will + reduce code size to make compilation faster. With B<--emit-raw-code>, only + the full raw code produced by the compiler will be generated. + + =back + + =head2 Miscellaneous Options + + =over + + =item B<--help> + + Print a summary of command line options. + + =item B<-V> or B<--version> + + This option will cause B to print out its version number + and terminate. + + =back + + =head1 EXIT STATUS + + If B succeeds, it will exit with 0. Otherwise, if an error + occurs, it will exit with a non-zero value and no compilation actions + will be taken. If one of the compilation tools returns a non-zero + status, pending actions will be discarded and B will return the + same result code as the failing compilation tool. + + =head1 SEE ALSO + + L, L, L, L, + L, L + + =head1 AUTHORS + + Reid Spencer + + =cut From lattner at cs.uiuc.edu Fri Aug 6 12:44:59 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 12:44:59 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200408061744.MAA25101@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.11 -> 1.12 --- Log message: Increase fixed size buffers. "Noone would ever want a struct with more than 1024 elements in it". This is obviously a gross hack --- Diffs of the changes: (+8 -5) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.11 llvm-gcc/gcc/llvm-types.c:1.12 --- llvm-gcc/gcc/llvm-types.c:1.11 Sun Jul 18 16:18:03 2004 +++ llvm-gcc/gcc/llvm-types.c Fri Aug 6 12:44:47 2004 @@ -1204,9 +1204,9 @@ unsigned Idx, Size; unsigned fieldcount; PtrPtrTableEntry **HTEP, *HTE; - llvm_type *StructElements[256]; /* FIXME: Fixed size buffers are bad. */ - unsigned ElementOffsets[256]; - unsigned ElementAlignments[256]; + llvm_type *StructElements[256*4]; /* FIXME: Fixed size buffers are bad. */ + unsigned ElementOffsets[256*4]; + unsigned ElementAlignments[256*4]; /* Is it a forward declaration? */ if (TYPE_SIZE(type) == 0) { /* Yes, handle this. */ @@ -1288,7 +1288,7 @@ if (Field && TREE_CODE(Field) != FIELD_DECL) Field = GetNextFieldDecl(Field); for (fieldcount = 0; Field; fieldcount++,Field = GetNextFieldDecl(Field)) { - assert ((fieldcount<256) && "LLVM can only have 255 structure members!"); + assert ((fieldcount<256*4) && "LLVM can only have 1023 structure members!"); DecodeFieldDecl(Field, StructElements, ElementOffsets, ElementAlignments, &Idx, &Size); @@ -1363,8 +1363,11 @@ return (HTE->Dest = llvm_type_get_cannonical_struct(Result)); } case VOID_TYPE: return VoidTy; - case BOOLEAN_TYPE: return BoolTy; + case BOOLEAN_TYPE: + if (TYPE_PRECISION(type) == 1) + return BoolTy; + /* FALL THROUGH */ case ENUMERAL_TYPE: if (TYPE_SIZE(type) == 0) { /* Use of an enum that is only forward declared. */ From lattner at cs.uiuc.edu Fri Aug 6 12:46:45 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 12:46:45 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200408061746.MAA25238@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.12 -> 1.13 --- Log message: revert inadvertently checked in hunk --- Diffs of the changes: (+1 -4) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.12 llvm-gcc/gcc/llvm-types.c:1.13 --- llvm-gcc/gcc/llvm-types.c:1.12 Fri Aug 6 12:44:47 2004 +++ llvm-gcc/gcc/llvm-types.c Fri Aug 6 12:46:33 2004 @@ -1363,11 +1363,8 @@ return (HTE->Dest = llvm_type_get_cannonical_struct(Result)); } case VOID_TYPE: return VoidTy; + case BOOLEAN_TYPE: return BoolTy; - case BOOLEAN_TYPE: - if (TYPE_PRECISION(type) == 1) - return BoolTy; - /* FALL THROUGH */ case ENUMERAL_TYPE: if (TYPE_SIZE(type) == 0) { /* Use of an enum that is only forward declared. */ From lattner at cs.uiuc.edu Fri Aug 6 13:03:43 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 13:03:43 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200408061803.NAA25926@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.13 -> 1.14 --- Log message: If you are looking for elegance, look elsewhere. --- Diffs of the changes: (+1 -1) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.13 llvm-gcc/gcc/llvm-types.c:1.14 --- llvm-gcc/gcc/llvm-types.c:1.13 Fri Aug 6 12:46:33 2004 +++ llvm-gcc/gcc/llvm-types.c Fri Aug 6 13:03:30 2004 @@ -1257,7 +1257,7 @@ * before calling llvm_type_get_from_tree, so we just allocate "enough" * space. */ - Result = llvm_type_create_struct(500, + Result = llvm_type_create_struct(1024 /*FIXME THIS IS HORRIBLE!*/, (TREE_INT_CST_LOW(TYPE_SIZE(type))+7)/8); /* Add the new structure type to the hash table of created structure types. */ From lattner at cs.uiuc.edu Fri Aug 6 13:07:46 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 13:07:46 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200408061807.NAA26061@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.14 -> 1.15 --- Log message: Actually use uint's to index into structure elements instead of ubytes. --- Diffs of the changes: (+2 -2) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.14 llvm-gcc/gcc/llvm-types.c:1.15 --- llvm-gcc/gcc/llvm-types.c:1.14 Fri Aug 6 13:03:30 2004 +++ llvm-gcc/gcc/llvm-types.c Fri Aug 6 13:07:34 2004 @@ -1114,7 +1114,7 @@ TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field))); unsigned Align = TYPE_ALIGN(TREE_TYPE(Field)); assert(Offset == 0 && "Offset always thought to be zero in union!"); - SET_DECL_LLVM(Field, llvm_constant_new_integral(UByteTy, 0)); + SET_DECL_LLVM(Field, llvm_constant_new_integral(UIntTy, 0)); if (Align > MaxAlign) { MaxAlign = Align; @@ -1341,7 +1341,7 @@ #if DEBUG_STRUCT_LAYOUT fprintf(stderr, "%d, ", Idx); #endif - SET_DECL_LLVM(Field, llvm_constant_new_integral(UByteTy, Idx)); + SET_DECL_LLVM(Field, llvm_constant_new_integral(UIntTy, Idx)); /* If we just passed over a zero sized field, skip ahead to the next * field, so we don't assign all consequtive zero sized elements to the From lattner at cs.uiuc.edu Fri Aug 6 13:09:13 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Aug 2004 13:09:13 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c Message-ID: <200408061809.NAA29102@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-08-06-LargeStructTest.c added (r1.1) --- Log message: New testcase for critical 1.3 feature --- Diffs of the changes: (+17 -0) Index: llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c diff -c /dev/null llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c:1.1 *** /dev/null Fri Aug 6 13:09:13 2004 --- llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c Fri Aug 6 13:09:02 2004 *************** *** 0 **** --- 1,17 ---- + + #define A(X) int X; + #define B(X) A(X##0) A(X##1) A(X##2) A(X##3) A(X##4) A(X##5) A(X##6) A(X##7) \ + A(X##8) A(X##9) A(X##A) A(X##B) A(X##C) A(X##D) A(X##E) A(X##F) + #define C(X) B(X##0) B(X##1) B(X##2) B(X##3) B(X##4) B(X##5) B(X##6) B(X##7) \ + B(X##8) B(X##9) B(X##A) B(X##B) B(X##C) B(X##D) B(X##E) B(X##F) + + struct foo { + C(x); // 256 + C(y); // 256 + C(z); + }; + + + int test(struct foo *F) { + return F->xA1 + F->yFF + F->zC4; + } From brukman at cs.uiuc.edu Fri Aug 6 13:45:55 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri, 6 Aug 2004 13:45:55 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/External/SPEC/CINT2000/Makefile Message-ID: <200408061845.NAA23154@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000: Makefile updated: 1.13 -> 1.14 --- Log message: No, really, crafty loops on Sparc even compiled natively. Disabled. --- Diffs of the changes: (+8 -0) Index: llvm/test/Programs/External/SPEC/CINT2000/Makefile diff -u llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.13 llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.14 --- llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.13 Sun Mar 7 15:12:34 2004 +++ llvm/test/Programs/External/SPEC/CINT2000/Makefile Fri Aug 6 13:45:44 2004 @@ -13,4 +13,12 @@ 256.bzip2 \ 300.twolf +# Get the $(ARCH) setting +include $(LEVEL)/Makefile.config + +# Disable crafty until it stops infinite-looping on Sparc +ifeq ($(ARCH), Sparc) +PARALLEL_DIRS := $(filter-out 186.crafty, $(PARALLEL_DIRS)) +endif + include ${LEVEL}/test/Programs/Makefile.programs From brukman at cs.uiuc.edu Fri Aug 6 13:46:40 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri, 6 Aug 2004 13:46:40 -0500 Subject: [llvm-commits] CVS: llvm-www/testresults/index.html Message-ID: <200408061846.NAA23284@zion.cs.uiuc.edu> Changes in directory llvm-www/testresults: index.html updated: 1.10 -> 1.11 --- Log message: We are now testing LLC on MacOSX/PPC as well. --- Diffs of the changes: (+4 -2) Index: llvm-www/testresults/index.html diff -u llvm-www/testresults/index.html:1.10 llvm-www/testresults/index.html:1.11 --- llvm-www/testresults/index.html:1.10 Fri Jul 30 17:20:33 2004 +++ llvm-www/testresults/index.html Fri Aug 6 13:46:29 2004 @@ -29,7 +29,9 @@ 2.3GHz) -- release build
  • X86: FreeBSD 5.1 (may not be run every day)
  • -
  • PPC: Mac OS X 10.3 "Panther" on PowerPC G5 (dual 1.8Ghz CPU) (C Back-end Only)
  • +
  • PPC: Mac OS X +10.3 "Panther" on PowerPC G5 (dual 1.8Ghz CPU) (CBE and LLC +only)
  • Sparc V9: Solaris (Sun Fire V240, dual 1Ghz CPU)
  • @@ -41,7 +43,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/07/30 22:20:33 $ + Last modified: $Date: 2004/08/06 18:46:29 $ From gaeke at cs.uiuc.edu Fri Aug 6 14:11:56 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri, 6 Aug 2004 14:11:56 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp PhyRegAlloc.h Message-ID: <200408061911.OAA05092@seraph.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.158 -> 1.159 PhyRegAlloc.h updated: 1.68 -> 1.69 --- Log message: dumpSavedState has outlived its usefulness. --- Diffs of the changes: (+3 -47) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.158 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.159 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.158 Wed Aug 4 02:29:53 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Fri Aug 6 14:11:42 2004 @@ -1181,44 +1181,6 @@ } -/// Dump the saved state filled in by saveState() out to stderr. Only -/// used when debugging. -/// -void PhyRegAlloc::dumpSavedState () { - std::vector &state = FnAllocState[Fn]; - int ArgNum = 0; - for (Function::const_aiterator i=Fn->abegin (), e=Fn->aend (); i != e; ++i) { - const Argument *Arg = &*i; - std::cerr << "Argument: " << *Arg << "\n" - << "FnAllocState:\n"; - for (unsigned i = 0; i < state.size (); ++i) { - AllocInfo &S = state[i]; - if (S.Instruction == -1 && S.Operand == ArgNum) - std::cerr << " " << S << "\n"; - } - std::cerr << "----------\n"; - ++ArgNum; - } - int Insn = 0; - for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II) { - const Instruction *I = &*II; - MachineCodeForInstruction &Instrs = MachineCodeForInstruction::get (I); - std::cerr << "Instruction: " << *I - << "MachineCodeForInstruction:\n"; - for (unsigned i = 0, n = Instrs.size (); i != n; ++i) - std::cerr << " " << *Instrs[i]; - std::cerr << "FnAllocState:\n"; - for (unsigned i = 0; i < state.size (); ++i) { - AllocInfo &S = state[i]; - if (Insn == S.Instruction) - std::cerr << " " << S << "\n"; - } - std::cerr << "----------\n"; - ++Insn; - } -} - - bool PhyRegAlloc::doFinalization (Module &M) { if (SaveRegAllocState) finishSavingState (M); return false; @@ -1377,20 +1339,15 @@ colorIncomingArgs(); // Save register allocation state for this function in a Constant. - if (SaveRegAllocState) { + if (SaveRegAllocState) saveState(); - } // Now update the machine code with register names and add any additional // code inserted by the register allocator to the instruction stream. updateMachineCode(); - if (SaveRegAllocState) { - if (DEBUG_RA) // Check our work. - dumpSavedState (); - if (!SaveStateToModule) - finishSavingState (const_cast (*Fn->getParent ())); - } + if (SaveRegAllocState && !SaveStateToModule) + finishSavingState (const_cast (*Fn->getParent ())); if (DEBUG_RA) { std::cerr << "\n**** Machine Code After Register Allocation:\n\n"; Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.68 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.69 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.68 Wed Jun 2 21:45:09 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h Fri Aug 6 14:11:43 2004 @@ -128,7 +128,6 @@ void saveStateForValue (std::vector &state, const Value *V, int Insn, int Opnd); void saveState(); - void dumpSavedState(); void finishSavingState(Module &M); void setCallInterferences(const MachineInstr *MI, From criswell at cs.uiuc.edu Fri Aug 6 14:55:42 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 14:55:42 -0500 Subject: [llvm-commits] [release_13] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200408061955.OAA24317@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.11 -> 1.11.2.1 --- Log message: Merged in Chris's changes from August 6, 2004. This expands the number of structure elements beyond 256 to 1024. --- Diffs of the changes: (+7 -7) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.11 llvm-gcc/gcc/llvm-types.c:1.11.2.1 --- llvm-gcc/gcc/llvm-types.c:1.11 Sun Jul 18 16:18:03 2004 +++ llvm-gcc/gcc/llvm-types.c Fri Aug 6 14:55:32 2004 @@ -1114,7 +1114,7 @@ TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field))); unsigned Align = TYPE_ALIGN(TREE_TYPE(Field)); assert(Offset == 0 && "Offset always thought to be zero in union!"); - SET_DECL_LLVM(Field, llvm_constant_new_integral(UByteTy, 0)); + SET_DECL_LLVM(Field, llvm_constant_new_integral(UIntTy, 0)); if (Align > MaxAlign) { MaxAlign = Align; @@ -1204,9 +1204,9 @@ unsigned Idx, Size; unsigned fieldcount; PtrPtrTableEntry **HTEP, *HTE; - llvm_type *StructElements[256]; /* FIXME: Fixed size buffers are bad. */ - unsigned ElementOffsets[256]; - unsigned ElementAlignments[256]; + llvm_type *StructElements[256*4]; /* FIXME: Fixed size buffers are bad. */ + unsigned ElementOffsets[256*4]; + unsigned ElementAlignments[256*4]; /* Is it a forward declaration? */ if (TYPE_SIZE(type) == 0) { /* Yes, handle this. */ @@ -1257,7 +1257,7 @@ * before calling llvm_type_get_from_tree, so we just allocate "enough" * space. */ - Result = llvm_type_create_struct(500, + Result = llvm_type_create_struct(1024 /*FIXME THIS IS HORRIBLE!*/, (TREE_INT_CST_LOW(TYPE_SIZE(type))+7)/8); /* Add the new structure type to the hash table of created structure types. */ @@ -1288,7 +1288,7 @@ if (Field && TREE_CODE(Field) != FIELD_DECL) Field = GetNextFieldDecl(Field); for (fieldcount = 0; Field; fieldcount++,Field = GetNextFieldDecl(Field)) { - assert ((fieldcount<256) && "LLVM can only have 255 structure members!"); + assert ((fieldcount<256*4) && "LLVM can only have 1023 structure members!"); DecodeFieldDecl(Field, StructElements, ElementOffsets, ElementAlignments, &Idx, &Size); @@ -1341,7 +1341,7 @@ #if DEBUG_STRUCT_LAYOUT fprintf(stderr, "%d, ", Idx); #endif - SET_DECL_LLVM(Field, llvm_constant_new_integral(UByteTy, Idx)); + SET_DECL_LLVM(Field, llvm_constant_new_integral(UIntTy, Idx)); /* If we just passed over a zero sized field, skip ahead to the next * field, so we don't assign all consequtive zero sized elements to the From criswell at cs.uiuc.edu Fri Aug 6 14:57:15 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 14:57:15 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c Message-ID: <200408061957.OAA24493@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-08-06-LargeStructTest.c added (r1.1.2.1) --- Log message: Merge in test for structures with more than 256 members, courtesy of Chris. --- Diffs of the changes: (+17 -0) Index: llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c diff -c /dev/null llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c:1.1.2.1 *** /dev/null Fri Aug 6 14:57:15 2004 --- llvm/test/Regression/CFrontend/2004-08-06-LargeStructTest.c Fri Aug 6 14:57:05 2004 *************** *** 0 **** --- 1,17 ---- + + #define A(X) int X; + #define B(X) A(X##0) A(X##1) A(X##2) A(X##3) A(X##4) A(X##5) A(X##6) A(X##7) \ + A(X##8) A(X##9) A(X##A) A(X##B) A(X##C) A(X##D) A(X##E) A(X##F) + #define C(X) B(X##0) B(X##1) B(X##2) B(X##3) B(X##4) B(X##5) B(X##6) B(X##7) \ + B(X##8) B(X##9) B(X##A) B(X##B) B(X##C) B(X##D) B(X##E) B(X##F) + + struct foo { + C(x); // 256 + C(y); // 256 + C(z); + }; + + + int test(struct foo *F) { + return F->xA1 + F->yFF + F->zC4; + } From criswell at cs.uiuc.edu Fri Aug 6 16:04:09 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 16:04:09 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/utils/mkrel.sh Message-ID: <200408062104.QAA25642@zion.cs.uiuc.edu> Changes in directory llvm/utils: mkrel.sh added (r1.1.2.1) --- Log message: Created script to help automate part of the release process. --- Diffs of the changes: (+41 -0) Index: llvm/utils/mkrel.sh diff -c /dev/null llvm/utils/mkrel.sh:1.1.2.1 *** /dev/null Fri Aug 6 16:04:09 2004 --- llvm/utils/mkrel.sh Fri Aug 6 16:03:59 2004 *************** *** 0 **** --- 1,41 ---- + #!/bin/sh + + # + # Shell Script: mkrel + # + # Description: + # Make LLVM Release source tarballs by grabbing the source from the CVS + # repository. + # + # Usage: + # mkrel + # + + # + # Constants + # + cvsroot=":pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm" + + # + # Save the command line arguments into some variables. + # + version=$1 + tag=$2 + dir=$3 + + # + # Create the working directory and make it the current directory. + # + mkdir -p $dir + cd $dir + + # + # Extract the LLVM sources given the label. + # + cvs -d $cvsroot export -r $tag llvm llvm-gcc + + # + # Create source tarballs. + # + tar -cvf - llvm | gzip > llvm-${version}.tar.gz + tar -cvf - llvm-gcc | gzip > cfrontend-${version}.source.tar.gz From criswell at cs.uiuc.edu Fri Aug 6 16:12:55 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 16:12:55 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/docs/index.html Message-ID: <200408062112.QAA25842@zion.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.24 -> 1.24.2.1 --- Log message: Fixed the link to the Command Guide. The previous revision only worked if the browser is getting the file from a web server that autocompletes the URL. --- Diffs of the changes: (+3 -3) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.24 llvm/docs/index.html:1.24.2.1 --- llvm/docs/index.html:1.24 Mon Aug 2 16:37:11 2004 +++ llvm/docs/index.html Fri Aug 6 16:12:44 2004 @@ -51,8 +51,8 @@ Everything from unpacking and compilation of the distribution to execution of some tools. -
  • LLVM Command Guide - A reference manual for -the LLVM command line utilities ("man" pages for LLVM tools).
  • +
  • LLVM Command Guide - A reference +manual for the LLVM command line utilities ("man" pages for LLVM tools).
  • Frequently Asked Questions - A list of common questions and problems and their solutions.
  • @@ -195,6 +195,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/08/02 21:37:11 $ + Last modified: $Date: 2004/08/06 21:12:44 $ From criswell at cs.uiuc.edu Fri Aug 6 16:26:40 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri, 6 Aug 2004 16:26:40 -0500 Subject: [llvm-commits] [release_13] CVS: llvm/docs/GettingStarted.html Message-ID: <200408062126.QAA25958@zion.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.64 -> 1.64.2.1 --- Log message: Added note about new PowerPC code generator. Updated versions to 1.3. --- Diffs of the changes: (+8 -7) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.64 llvm/docs/GettingStarted.html:1.64.2.1 --- llvm/docs/GettingStarted.html:1.64 Tue Jul 20 15:25:18 2004 +++ llvm/docs/GettingStarted.html Fri Aug 6 16:26:30 2004 @@ -221,7 +221,7 @@
  • MacOS X on PowerPC
      -
    • No native code generation +
    • Experimental support for static native code generation
    • Approximately 1.25 GB of Free Disk Space
      • Source code: 45 MB
      • @@ -430,23 +430,23 @@

        The files are as follows:

        -
        llvm-1.2.tar.gz +
        llvm-1.3.tar.gz
        This is the source code to the LLVM suite.

        -

        cfrontend-1.2.sparc-sun-solaris2.8.tar.gz +
        cfrontend-1.3.sparc-sun-solaris2.8.tar.gz
        This is the binary release of the GCC front end for Solaris/Sparc.

        -

        cfrontend-1.2.i686-redhat-linux-gnu.tar.gz +
        cfrontend-1.3.i686-redhat-linux-gnu.tar.gz
        This is the binary release of the GCC front end for Linux/x86.

        -

        cfrontend-1.2.i386-unknown-freebsd5.1.tar.gz +
        cfrontend-1.3.i386-unknown-freebsd5.1.tar.gz
        This is the binary release of the GCC front end for FreeBSD/x86.

        -

        cfrontend-1.2.powerpc-apple-darwin7.0.0.tar.gz +
        cfrontend-1.3.powerpc-apple-darwin7.0.0.tar.gz
        This is the binary release of the GCC front end for MacOS X/PPC.
        @@ -480,6 +480,7 @@ label:

          +
        • Release 1.3: RELEASE_13
        • Release 1.2: RELEASE_12
        • Release 1.1: RELEASE_11
        • Release 1.0: RELEASE_1
        • @@ -1266,7 +1267,7 @@ Chris Lattner
          The LLVM Compiler Infrastructure
          - Last modified: $Date: 2004/07/20 20:25:18 $ + Last modified: $Date: 2004/08/06 21:26:30 $ From reid at x10sys.com Fri Aug 6 17:28:58 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 6 Aug 2004 17:28:58 -0500 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvmc.pod Message-ID: <200408062228.RAA26224@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvmc.pod updated: 1.1 -> 1.2 --- Log message: Various updates suggested by Misha and Chris. Moved material that is aimed more at the comiler writer than the llvmc user later in the document. --- Diffs of the changes: (+222 -73) Index: llvm/docs/CommandGuide/llvmc.pod diff -u llvm/docs/CommandGuide/llvmc.pod:1.1 llvm/docs/CommandGuide/llvmc.pod:1.2 --- llvm/docs/CommandGuide/llvmc.pod:1.1 Fri Aug 6 11:58:48 2004 +++ llvm/docs/CommandGuide/llvmc.pod Fri Aug 6 17:28:47 2004 @@ -33,6 +33,13 @@ The tool itself does nothing with a user's program. It merely invokes other tools to get the compilation tasks done. +The options supported by B generalize the compilation process and +provide a consistent and simple interface for multiple programming languages. +This makes it easier for developers to get their software compiled with LLVM. +Without B, developers would need to understand how to invoke the +front-end compiler, optimizer, assembler, and linker in order to compile their +programs. B's sole mission is to trivialize that process. + =head2 Basic Operation B always takes the following basic actions: @@ -41,41 +48,42 @@ =item * Command line options and filenames are collected. -This provides the basic instruction to B on what actions it should -take. This is the I the user is making of B. +The command line options provide the marching orders to B on what actions +it should perform. This is the I the user is making of B and it +is interpreted first. =item * Configuration files are read. -Based on the options and the suffixes of the filenames presented, a set -of configuration files are read to configure the actions B -will take (more on this later). +Based on the options and the suffixes of the filenames presented, a set of +configuration files are read to configure the actions B will take +(more on this later). =item * Determine actions to take. -The tool chain needed to complete the task is determined. This is the -primary work of B. It breaks the request specified by the -command line options into a set of basic actions to be done: -pre-processing, compilation, assembly, optimization, and linking. -For each applicable action, it selects the command to be run from -the specifications in the configuration files. +The tool chain needed to complete the task is determined. This is the primary +work of B. It breaks the request specified by the command line options +into a set of basic actions to be done: -=item * Execute actions. +=over -The actions determined previously are executed sequentially and then -B terminates. +=item * Pre-processing: gathering/filtering compiler input + +=item * Compilation: source language to bytecode conversion + +=item * Assembly: bytecode to native code conversion + +=item * Optimization: conversion of bytecode to something that runs faster + +=item * Linking: combining multiple bytecodes to produce executable program =back -=head2 Configuration Files +=item * Execute actions. -B is highly configurable both on the command line and in configuration -files. Configuration files specify the details of what commands to run -for a given action. Each front end compiler must provide its own -configuration file to tell B how to invoke that compiler. The LLVM -toolset does not need to be configured as B just "knows" how to -invoke those tools. +The actions determined previously are executed sequentially and then +B terminates. -Rest TBD. +=back =head1 OPTIONS @@ -160,7 +168,7 @@ This is the same as B<-O4> except it employs aggressive analyses and aggressive inter-procedural optimization. -=item B<-O6> (profile guided optimization - not implemented) +=item B<-O6> (profile guided optimization: not implemented) This is the same as B<-O5> except that it employes profile-guided reoptimization of the program after it has executed. Note that this implies @@ -168,7 +176,7 @@ the re-optimization has completed, the profiling instrumentation is removed and final optimizations are employed. -=item B<-O7> (lifelong optimization - not implemented) +=item B<-O7> (lifelong optimization: not implemented) This is the same as B<-O5> and similar to B<-O6> except that reoptimization is performed through the life of the program. That is, each run will update @@ -225,48 +233,6 @@ =back -=head2 Configuration Options - -=over - -=item B<--show-config> I<[suffixes...]> - -When this option is given, the only action taken by B is to show its -final configuration state in the form of a configuration file. No compilation -tasks will be conducted when this option is given; processing will stop once -the configuration has been printed. The optional (comma separated) list of -suffixes controls what is printed. Without any suffixes, the configuration -for all languages is printed. With suffixes, only the languages pertaining -to those file suffixes will be printed. The configuration information is -printed after all command line options and configuration files have been -read and processed. This allows the user to verify that the correct -configuration data has been read by B. - -=item B<--config> :I
          :I=I - -This option instructs B to accept I as the value for configuration -item I in the section named I
          . This is a quick way to override -a configuration item on the command line without resorting to changing the -configuration files. - -=item B<--config-file> F - -This option tells B to read configuration data from the I -named F. Data from such directories will be read in the order -specified on the command line after all other standard config files have -been read. This allows users or groups of users to conveniently create -their own configuration directories in addition to the standard ones to which -they may not have write access. - -=item B<--config-only-from> F - -This option tells B to skip the normal processing of configuration -files and only configure from the contents of the F directory. Multiple -B<--config-only-from> options may be given in which case the directories are -read in the order given on the command line. - -=back - =head2 Information Options =over @@ -325,17 +291,72 @@ =over -=item B<-I>F (C/C++ Only) +=item B<-I>F This option is just passed through to a C or C++ front end compiler to tell it where include files can be found. =back +=head2 Miscellaneous Options + +=over + +=item B<--help> + +Print a summary of command line options. + +=item B<-V> or B<--version> + +This option will cause B to print out its version number +and terminate. + +=back + =head2 Advanced Options +You better know what you're doing if you use these options. Improper use +of these options can produce drastically wrong results. + =over +=item B<--show-config> I<[suffixes...]> + +When this option is given, the only action taken by B is to show its +final configuration state in the form of a configuration file. No compilation +tasks will be conducted when this option is given; processing will stop once +the configuration has been printed. The optional (comma separated) list of +suffixes controls what is printed. Without any suffixes, the configuration +for all languages is printed. With suffixes, only the languages pertaining +to those file suffixes will be printed. The configuration information is +printed after all command line options and configuration files have been +read and processed. This allows the user to verify that the correct +configuration data has been read by B. + +=item B<--config> :I
          :I=I + +This option instructs B to accept I as the value for configuration +item I in the section named I
          . This is a quick way to override +a configuration item on the command line without resorting to changing the +configuration files. + +=item B<--config-file> F + +This option tells B to read configuration data from the I +named F. Data from such directories will be read in the order +specified on the command line after all other standard config files have +been read. This allows users or groups of users to conveniently create +their own configuration directories in addition to the standard ones to which +they may not have write access. + +=item B<--config-only-from> F + +This option tells B to skip the normal processing of configuration +files and only configure from the contents of the F directory. Multiple +B<--config-only-from> options may be given in which case the directories are +read in the order given on the command line. + + =item B<--emit-raw-code> No optimization is done whatsoever. The compilers invoked by B with @@ -348,18 +369,146 @@ =back -=head2 Miscellaneous Options +=head1 CONFIGURATION + +=head2 Warning + +Configuration information is relatively static for a given release of LLVM and +a front end compiler. However, the details may change from release to release. +Users are encouraged to simply use the various options of the B command +and ignore the configuration of the tool. These configuration files are for +compiler writers and LLVM developers. Those wishing to simply use B +don't need to understand this section but it may be instructive on what the tool +does. + +=head2 Introduction + +B is highly configurable both on the command line and in configuration +files. The options it understands are generic, consistent and simple by design. +Furthermore, the B options apply to the compilation of any LLVM enabled +programming language. To be enabled as a supported source language compiler, a +compiler writer must provide a configuration file that tells B how to +invoke the compiler and what its capabilities are. The purpose of the +configuration files then is to allow compiler writers to specify to B how +the compiler should be invoked. Users may but are not advised to alter the +compiler's B configuration. + +Because B just invokes other programs, it must deal with the +available command line options for those programs regardless of whether they +were written for LLVM or not. Furthermore, not all compilation front ends will +have the same capabilities. Some front ends will simply generate LLVM assembly +code, others will be able to generate fully optimized byte code. In general, +B doesn't make any assumptions about the capabilities or command line +options of a sub-tool. It simply uses the details found in the configuration +files and leaves it to the compiler writer to specify the configuration +correctly. + +Ths approach means that new compiler front ends can be up and working very +quickly. As a first cut, a front end can simply compile its source to raw +(unoptimized) bytecode or LLVM assembly and B can be configured to pick +up the slack (translate LLVm assembly to bytecode, optimize the bytecode, +generate native assembly, link, etc.). In fact, the front end need not use +any LLVM libraries, and it could be written in any language (instead of C++). +The configuration data will allow the full range of optimization, assembly, +and linking capabilities that LLVM provides to be added to these kinds of tools. +Enabling the rapid development of front-ends is one of the primary goals of +B. + +As a compiler front end matures, it may utilize the LLVM libraries and tools to +more efficiently produce optimized bytecode directly in a single compilation and +optimization program. In these cases, multiple tools would not be needed and +the configuration data for the compiler would change. + +Configuring B to the needs and capabilities of a source language compiler +is relatively straight forward. The compilation process is broken down into five +phases: =over -=item B<--help> +=item * Pre-processing (filter and combine source files) -Print a summary of command line options. +=item * Translation (translate source language to LLVM assembly or bytecode) -=item B<-V> or B<--version> +=item * Optimization (make bytecode execute quickly) -This option will cause B to print out its version number -and terminate. +=item * Assembly (converting bytecode to object code) + +=item * Linking (converting translated code to an executable) + +=back + +A compiler writer must provide a definition of what to do for each of these five +phases for each of the optimization levels. The specification consists simply of +prototypical command lines into which B can substitute command line +arguments and file names. Note that any given phase can be completely blank if +the source language's compiler combines multiple phases into a single program. +For example, quite often pre-processng, translation, and optimization are +combined into a single program. The specification for such a compiler would have +blank entries for pre-processing and translation but a full command line for +optimization. + +=head2 Configuration File Types + +There are two types of configuration files: the master configuration file +and the language specific configuration file. + +The master configuration file contains the general configuration of B +itself. This includes things like the mapping between file extensions and +source languages. This mapping is needed in order to quickly read only the +applicable language-specific configuration files (avoiding reading every config +file for every compilation task). + +Language specific configuration files tell B how to invoke the language's +compiler for a variety of different tasks and what other tools are needed to +I the compiler's missing features (e.g. optimization). + +Language specific configuration files are placed in directories and given +specific names to foster faster lookup. The name of a given configuration file +is the name of the source language. + +=head2 Default Directory Locations + +B will look for configuration files in two standard locations: the +LLVM installation directory (typically C) and the user's +home directory (typically C). In these directories a file named +C provides the master configuration for B. Language specific +files will have a language specific name (e.g. C++, Stacker, Scheme, FORTRAN). +When reading the configuration files, the master files are always read first in +the following order: + +=over + +=item 1 C in LLVM installation directory + +=item 2 C in the user's home directory. + +=back + +Then, based on the command line options and the suffixes of the file names +provided on B's command line, one or more language specific configuration +files are read. Only the language specific configuration files actually needed +to complete B's task are read. Other language specific files will be +ignored. + +Note that the user can affect this process in several ways using the various +B<--config-*> options and with the B<--x LANGUAGE> option. + +Although a user I override the master configuration file, this is not +advised. The capability is retained so that compiler writers can affect the +master configuration (such as adding new file suffixes) while developing a new +compiler front end since they might not have write access to the installed +master configuration. + +=head2 Syntax + +The syntax of the configuration files is yet to be determined. There are three +viable options: + +=over + +=item XML +=item Windows .ini +=item specific to B =back From reid at x10sys.com Fri Aug 6 17:56:59 2004 From: reid at x10sys.com (Reid Spencer) Date: Fri, 6 Aug 2004 17:56:59 -0500 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvmc.pod Message-ID: <200408062256.RAA26378@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvmc.pod updated: 1.2 -> 1.3 --- Log message: Correct spelling mistakes. Wrap lines at 80 columns. --- Diffs of the changes: (+25 -25) Index: llvm/docs/CommandGuide/llvmc.pod diff -u llvm/docs/CommandGuide/llvmc.pod:1.2 llvm/docs/CommandGuide/llvmc.pod:1.3 --- llvm/docs/CommandGuide/llvmc.pod:1.2 Fri Aug 6 17:28:47 2004 +++ llvm/docs/CommandGuide/llvmc.pod Fri Aug 6 17:56:49 2004 @@ -116,7 +116,7 @@ =item B<-E> or B<--preprocess> This option specifies that no compilation or linking should be -performed. Only pre-processing, if applicabe to the language being +performed. Only pre-processing, if applicable to the language being compiled, is performed. For languages that support it, this will result in the output containing the raw input to the compiler. @@ -133,7 +133,7 @@ =item B<-O1> or B<-O0> (default, fast compilation) -Only those optimizations that will hasten the compilation (mostly by reducing +Only those optimizations that will hasten the compilation (mostly by reducing the output) are applied. In general these are extremely fast and simple optimizations that reduce emitted code size. The goal here is not to make the resulting program fast but to make the compilation fast. If not specified, @@ -142,9 +142,9 @@ =item B<-O2> (basic optimization) This level of optimization specifies a balance between generating good code -that will execute reasonably quickly and not spending too much time optimizing +that will execute reasonably quickly and not spending too much time optimizing the code to get there. For example, this level of optimization may include -things like global common subexpression elimintation, aggressive dead code +things like global common subexpression elimination, aggressive dead code elimination, and scalar replication. =item B<-O3> (aggressive optimization) @@ -152,35 +152,35 @@ This level of optimization aggressively optimizes each set of files compiled together. However, no link-time inter-procedural optimization is performed. This level implies all the optimizations of the B<-O1> and B<-O2> optimization -levels, and should also provide loop optimizatiosn and compile time +levels, and should also provide loop optimizations and compile time inter-procedural optimizations. Essentially, this level tries to do as much as it can with the input it is given but doesn't do any link time IPO. -=item B<-O4> (linktime optimization) +=item B<-O4> (link time optimization) In addition to the previous three levels of optimization, this level of optimization aggressively optimizes each program at link time. It employs basic analysis and basic link-time inter-procedural optimizations, considering the program as a whole. -=item B<-O5> (aggressive linktime optimization) +=item B<-O5> (aggressive link time optimization) This is the same as B<-O4> except it employs aggressive analyses and aggressive inter-procedural optimization. =item B<-O6> (profile guided optimization: not implemented) -This is the same as B<-O5> except that it employes profile-guided -reoptimization of the program after it has executed. Note that this implies -a single level of reoptimization based on runtime profile analysis. Once +This is the same as B<-O5> except that it employs profile-guided +re-optimization of the program after it has executed. Note that this implies +a single level of re-optimization based on runtime profile analysis. Once the re-optimization has completed, the profiling instrumentation is removed and final optimizations are employed. =item B<-O7> (lifelong optimization: not implemented) -This is the same as B<-O5> and similar to B<-O6> except that reoptimization +This is the same as B<-O5> and similar to B<-O6> except that re-optimization is performed through the life of the program. That is, each run will update -the profile by which future reoptimizations are directed. +the profile by which future re-optimizations are directed. =back @@ -237,7 +237,7 @@ =over -=item B<-n> or B<--noop> +=item B<-n> or B<--no-op> This option tells B to do everything but actually execute the resulting tools. In combination with the B<-v> option, this causes B @@ -283,7 +283,7 @@ =item B<-Tool,asm>=I -Pass an arbitrary optionsto the code generator. +Pass an arbitrary option to the code generator. =back @@ -344,7 +344,7 @@ This option tells B to read configuration data from the I named F. Data from such directories will be read in the order -specified on the command line after all other standard config files have +specified on the command line after all other standard configuration files have been read. This allows users or groups of users to conveniently create their own configuration directories in addition to the standard ones to which they may not have write access. @@ -403,10 +403,10 @@ files and leaves it to the compiler writer to specify the configuration correctly. -Ths approach means that new compiler front ends can be up and working very +This approach means that new compiler front ends can be up and working very quickly. As a first cut, a front end can simply compile its source to raw (unoptimized) bytecode or LLVM assembly and B can be configured to pick -up the slack (translate LLVm assembly to bytecode, optimize the bytecode, +up the slack (translate LLVM assembly to bytecode, optimize the bytecode, generate native assembly, link, etc.). In fact, the front end need not use any LLVM libraries, and it could be written in any language (instead of C++). The configuration data will allow the full range of optimization, assembly, @@ -442,7 +442,7 @@ prototypical command lines into which B can substitute command line arguments and file names. Note that any given phase can be completely blank if the source language's compiler combines multiple phases into a single program. -For example, quite often pre-processng, translation, and optimization are +For example, quite often pre-processing, translation, and optimization are combined into a single program. The specification for such a compiler would have blank entries for pre-processing and translation but a full command line for optimization. @@ -455,8 +455,8 @@ The master configuration file contains the general configuration of B itself. This includes things like the mapping between file extensions and source languages. This mapping is needed in order to quickly read only the -applicable language-specific configuration files (avoiding reading every config -file for every compilation task). +applicable language-specific configuration files (avoiding reading every +configuration file for every compilation task). Language specific configuration files tell B how to invoke the language's compiler for a variety of different tasks and what other tools are needed to @@ -470,11 +470,11 @@ B will look for configuration files in two standard locations: the LLVM installation directory (typically C) and the user's -home directory (typically C). In these directories a file named -C provides the master configuration for B. Language specific -files will have a language specific name (e.g. C++, Stacker, Scheme, FORTRAN). -When reading the configuration files, the master files are always read first in -the following order: +home directory (typically C). In these directories a file +named C provides the master configuration for B. Language +specific files will have a language specific name (e.g. C++, Stacker, Scheme, +FORTRAN). When reading the configuration files, the master files are always +read first in the following order: =over From lattner at cs.uiuc.edu Sat Aug 7 02:08:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 02:08:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200408070708.CAA31067@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.25 -> 1.26 --- Log message: Death to tabs --- Diffs of the changes: (+14 -14) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.25 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.26 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.25 Fri Jun 11 01:37:11 2004 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Sat Aug 7 02:07:57 2004 @@ -105,23 +105,23 @@ for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) if (I->getOpcode() == FrameSetupOpcode || - I->getOpcode() == FrameDestroyOpcode) { - assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" - " instructions should have a single immediate argument!"); - unsigned Size = I->getOperand(0).getImmedValue(); - if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; - HasCalls = true; - RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); + I->getOpcode() == FrameDestroyOpcode) { + assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" + " instructions should have a single immediate argument!"); + unsigned Size = I->getOperand(0).getImmedValue(); + if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; + HasCalls = true; + RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); } else { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - MachineOperand &MO = I->getOperand(i); - if (MO.isRegister() && MO.isDef()) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + MachineOperand &MO = I->getOperand(i); + if (MO.isRegister() && MO.isDef()) { assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && "Register allocation must be performed!"); - ModifiedRegs[MO.getReg()] = true; // Register is modified + ModifiedRegs[MO.getReg()] = true; // Register is modified } } - ++I; + ++I; } MachineFrameInfo *FFI = Fn.getFrameInfo(); @@ -140,8 +140,8 @@ for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { // Check alias registers too... if (ModifiedRegs[*AliasSet]) { - RegsToSave.push_back(Reg); - break; + RegsToSave.push_back(Reg); + break; } } } From lattner at cs.uiuc.edu Sat Aug 7 02:18:53 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 02:18:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp Message-ID: <200408070718.CAA31286@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PrologEpilogInserter.cpp updated: 1.26 -> 1.27 --- Log message: Ok get rid of the REST of the tabs --- Diffs of the changes: (+11 -11) Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.26 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.27 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.26 Sat Aug 7 02:07:57 2004 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Sat Aug 7 02:18:41 2004 @@ -139,10 +139,10 @@ } else { for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { // Check alias registers too... - if (ModifiedRegs[*AliasSet]) { + if (ModifiedRegs[*AliasSet]) { RegsToSave.push_back(Reg); break; - } + } } } } @@ -178,9 +178,9 @@ I = MBB->end(); --I; for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { - const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); - RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i], RC); - --I; // Insert in reverse order + const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); + RegInfo->loadRegFromStackSlot(*MBB, I, RegsToSave[i],StackSlots[i], RC); + --I; // Insert in reverse order } } } @@ -291,10 +291,10 @@ for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (I->getOperand(i).isFrameIndex()) { - // If this instruction has a FrameIndex operand, we need to use that - // target machine register info object to eliminate it. - MRI.eliminateFrameIndex(Fn, I); - break; - } + if (I->getOperand(i).isFrameIndex()) { + // If this instruction has a FrameIndex operand, we need to use that + // target machine register info object to eliminate it. + MRI.eliminateFrameIndex(Fn, I); + break; + } } From reid at x10sys.com Sat Aug 7 10:19:41 2004 From: reid at x10sys.com (Reid Spencer) Date: Sat, 7 Aug 2004 10:19:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp Message-ID: <200408071519.KAA08324@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: MSSchedule.cpp updated: 1.3 -> 1.4 --- Log message: Get rid of a warning when compiling optimized. Uninitialized variable has been initialized. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.3 llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.4 --- llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.3 Fri Jul 30 18:36:10 2004 +++ llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp Sat Aug 7 10:19:31 2004 @@ -133,7 +133,7 @@ } bool MSSchedule::constructKernel(int II) { - MSchedGraphNode *branchNode; + MSchedGraphNode *branchNode = 0; int stageNum = (schedule.rbegin()->first)/ II; DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n"); From reid at x10sys.com Sat Aug 7 11:30:25 2004 From: reid at x10sys.com (Reid Spencer) Date: Sat, 7 Aug 2004 11:30:25 -0500 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvmc.pod Message-ID: <200408071630.LAA08555@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvmc.pod updated: 1.3 -> 1.4 --- Log message: Added information about the configuration file. This is a temporary home for this information as it belongs in a larger document on the subject of llvmc. --- Diffs of the changes: (+93 -4) Index: llvm/docs/CommandGuide/llvmc.pod diff -u llvm/docs/CommandGuide/llvmc.pod:1.3 llvm/docs/CommandGuide/llvmc.pod:1.4 --- llvm/docs/CommandGuide/llvmc.pod:1.3 Fri Aug 6 17:56:49 2004 +++ llvm/docs/CommandGuide/llvmc.pod Sat Aug 7 11:30:14 2004 @@ -272,16 +272,19 @@ =over +=item B<-T,pp>=I -=item B<-Tool,opt>=I +Pass an arbitrary option to the pre-processor. + +=item B<-T,opt>=I Pass an arbitrary option to the optimizer. -=item B<-Tool,link>=I +=item B<-T,link>=I Pass an arbitrary option to the linker. -=item B<-Tool,asm>=I +=item B<-T,asm>=I Pass an arbitrary option to the code generator. @@ -507,11 +510,97 @@ =over =item XML + =item Windows .ini + =item specific to B =back +=head2 Master Configuration Items + +=head3 Section: [lang=I] + +This section provides the master configuration data for a given language. The +language specific data will be found in a file named I. + +=over + +=item CI + +This adds the I specified to the list of recognized suffixes for +the I identified in the section. As many suffixes as are commonly used +for source files for the I should be specified. + +=back + +=begin html + +

          For example, the following might appear for C++: +

          
          +[lang=C++]
          +suffix=.cpp
          +suffix=.cxx
          +suffix=.C
          +

          + +=end html + +=head2 Language Specific Configuration Items + +=head3 Section: [general] + +=over + +=item C + +This item specifies whether the language has a pre-processing phase or not. This +controls whether the B<-E> option works for the language or not. + +=item C + +This item specifies the kind of output the language's compiler generates. The +choices are either bytecode (C) or LLVM assembly (C). + +=back + +=head3 Section: [-O0] + +=over + +=item CI + +This item specifies the I to use for pre-processing the input. + +=over + +Valid substitutions for this item are: + +=item %in% + +The input source file. + +=item %out% + +The output file. + +=item %options% + +Any pre-processing specific options (e.g. B<-I>). + +=back + +=item CI + +This item specifies the I to use for translating the source +language input into the output format given by the C item. + +=item CI + +This item specifies the I for optimizing the translator's output. + +=back + =head1 EXIT STATUS If B succeeds, it will exit with 0. Otherwise, if an error @@ -527,6 +616,6 @@ =head1 AUTHORS -Reid Spencer +Reid Spencer, L =cut From lattner at cs.uiuc.edu Sat Aug 7 20:28:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 20:28:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/LevelRaise.cpp Message-ID: <200408080128.UAA01967@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: LevelRaise.cpp updated: 1.100 -> 1.101 --- Log message: This DEBUG is buggy. comment it out because it's not worth fixing. This should go into 1.3 --- Diffs of the changes: (+2 -1) Index: llvm/lib/Transforms/LevelRaise.cpp diff -u llvm/lib/Transforms/LevelRaise.cpp:1.100 llvm/lib/Transforms/LevelRaise.cpp:1.101 --- llvm/lib/Transforms/LevelRaise.cpp:1.100 Thu Jul 29 07:17:33 2004 +++ llvm/lib/Transforms/LevelRaise.cpp Sat Aug 7 20:27:56 2004 @@ -302,7 +302,8 @@ // Make sure the source doesn't change type ConvertedTypes[Src] = Src->getType(); if (ValueConvertibleToType(CI, Src->getType(), ConvertedTypes, TD)) { - PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", *Src, *CI, *BB->getParent()); + //PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", *Src, *CI, + // *BB->getParent()); DEBUG(std::cerr << "\nCONVERTING EXPR TYPE:\n"); { // ValueMap must be destroyed before function verified! From lattner at cs.uiuc.edu Sat Aug 7 20:30:20 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 20:30:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp Message-ID: <200408080130.UAA02342@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.96 -> 1.97 --- Log message: Two fixes: 1. Fix a REALLY nasty cyclic replacement issue that Anshu discovered, causing nondeterminstic crashes and memory corruption. 2. For performance, don't go inserting constantexpr casts of GV pointers. This should definitely go into 1.3 --- Diffs of the changes: (+2 -3) Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.96 llvm/lib/Transforms/ExprTypeConvert.cpp:1.97 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.96 Thu Jul 29 07:17:34 2004 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Sat Aug 7 20:30:07 2004 @@ -151,7 +151,7 @@ // If it's a constant... all constants can be converted to a different // type. // - if (Constant *CPV = dyn_cast(V)) + if (isa(V) && !isa(V)) return true; CTMap[V] = Ty; @@ -984,10 +984,9 @@ unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0; Value *OtherOp = I->getOperand(OtherIdx); + Res->setOperand(!OtherIdx, NewVal); Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC, TD); - Res->setOperand(OtherIdx, NewOther); - Res->setOperand(!OtherIdx, NewVal); break; } case Instruction::Shl: From lattner at cs.uiuc.edu Sat Aug 7 22:27:52 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 22:27:52 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/CallGraph.h Message-ID: <200408080327.WAA10356@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: CallGraph.h updated: 1.37 -> 1.38 --- Log message: Add standard print/dump methods to CallGraph classes. --- Diffs of the changes: (+8 -0) Index: llvm/include/llvm/Analysis/CallGraph.h diff -u llvm/include/llvm/Analysis/CallGraph.h:1.37 llvm/include/llvm/Analysis/CallGraph.h:1.38 --- llvm/include/llvm/Analysis/CallGraph.h:1.37 Sun May 2 11:06:40 2004 +++ llvm/include/llvm/Analysis/CallGraph.h Sat Aug 7 22:27:39 2004 @@ -166,6 +166,10 @@ /// void print(std::ostream &o, const Module *M) const; + /// dump - Print out this call graph. + /// + void dump() const; + // stub - dummy function, just ignore it static void stub(); private: @@ -217,6 +221,10 @@ // CallGraphNode *operator[](unsigned i) const { return CalledFunctions[i];} + /// dump - Print out this call graph node. + /// + void dump() const; + void print(std::ostream &OS) const; //===--------------------------------------------------------------------- // Methods to keep a call graph up to date with a function that has been From lattner at cs.uiuc.edu Sat Aug 7 22:28:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 22:28:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraph.cpp Message-ID: <200408080328.WAA10362@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraph.cpp updated: 1.39 -> 1.40 --- Log message: Add standard print/dump methods to CallGraph classes. --- Diffs of the changes: (+22 -16) Index: llvm/lib/Analysis/IPA/CallGraph.cpp diff -u llvm/lib/Analysis/IPA/CallGraph.cpp:1.39 llvm/lib/Analysis/IPA/CallGraph.cpp:1.40 --- llvm/lib/Analysis/IPA/CallGraph.cpp:1.39 Thu Jul 29 12:14:17 2004 +++ llvm/lib/Analysis/IPA/CallGraph.cpp Sat Aug 7 22:27:49 2004 @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/Support/CallSite.h" #include "Support/STLExtras.h" +#include using namespace llvm; static RegisterAnalysis X("callgraph", "Call Graph Construction"); @@ -126,30 +127,35 @@ CallsExternalNode = 0; } -static void WriteToOutput(const CallGraphNode *CGN, std::ostream &o) { - if (CGN->getFunction()) - o << "Call graph node for function: '" - << CGN->getFunction()->getName() <<"'\n"; +void CallGraphNode::print(std::ostream &OS) const { + if (Function *F = getFunction()) + OS << "Call graph node for function: '" << F->getName() <<"'\n"; else - o << "Call graph node <>:\n"; + OS << "Call graph node <>:\n"; - for (unsigned i = 0; i < CGN->size(); ++i) - if ((*CGN)[i]->getFunction()) - o << " Calls function '" << (*CGN)[i]->getFunction()->getName() << "'\n"; + for (const_iterator I = begin(), E = end(); I != E; ++I) + if ((*I)->getFunction()) + OS << " Calls function '" << (*I)->getFunction()->getName() << "'\n"; else - o << " Calls external node\n"; - o << "\n"; + OS << " Calls external node\n"; + OS << "\n"; } -void CallGraph::print(std::ostream &o, const Module *M) const { - o << "CallGraph Root is: "; - if (getRoot()->getFunction()) - o << getRoot()->getFunction()->getName() << "\n"; +void CallGraphNode::dump() const { print(std::cerr); } + +void CallGraph::print(std::ostream &OS, const Module *M) const { + OS << "CallGraph Root is: "; + if (Function *F = getRoot()->getFunction()) + OS << F->getName() << "\n"; else - o << "<>\n"; + OS << "<>\n"; for (CallGraph::const_iterator I = begin(), E = end(); I != E; ++I) - WriteToOutput(I->second, o); + I->second->print(OS); +} + +void CallGraph::dump() const { + print(std::cerr, 0); } From lattner at cs.uiuc.edu Sat Aug 7 22:30:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 22:30:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp Message-ID: <200408080330.WAA10386@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Inliner.cpp updated: 1.20 -> 1.21 --- Log message: Fix another really nasty regression that Anshu pointed out. In cases where dangling constant users were removed from a function, causing it to be dead, we never removed the call graph edge from the external node to the function. In most cases, this didn't cause a problem (by luck). This should definitely go into 1.3 --- Diffs of the changes: (+24 -24) Index: llvm/lib/Transforms/IPO/Inliner.cpp diff -u llvm/lib/Transforms/IPO/Inliner.cpp:1.20 llvm/lib/Transforms/IPO/Inliner.cpp:1.21 --- llvm/lib/Transforms/IPO/Inliner.cpp:1.20 Thu Jul 29 12:28:42 2004 +++ llvm/lib/Transforms/IPO/Inliner.cpp Sat Aug 7 22:29:50 2004 @@ -54,8 +54,8 @@ E = CalleeNode->end(); I != E; ++I) CallerNode->addCalledFunction(*I); - // If we inlined the last possible call site to the function, - // delete the function body now. + // If we inlined the last possible call site to the function, delete the + // function body now. if (Callee->use_empty() && Callee->hasInternalLinkage() && !SCCFunctions.count(Callee)) { DEBUG(std::cerr << " -> Deleting dead function: " @@ -64,7 +64,7 @@ // Remove any call graph edges from the callee to its callees. while (CalleeNode->begin() != CalleeNode->end()) CalleeNode->removeCallEdgeTo(*(CalleeNode->end()-1)); - + // Removing the node for callee from the call graph and delete it. delete CG.removeFunctionFromModule(CalleeNode); ++NumDeleted; @@ -167,27 +167,27 @@ // from the program. Insert the dead ones in the FunctionsToRemove set. for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) { CallGraphNode *CGN = I->second; - Function *F = CGN ? CGN->getFunction() : 0; - - // If the only remaining users of the function are dead constants, - // remove them. - if (F) F->removeDeadConstantUsers(); - - if (F && (F->hasLinkOnceLinkage() || F->hasInternalLinkage()) && - F->use_empty()) { - - // Remove any call graph edges from the function to its callees. - while (CGN->begin() != CGN->end()) - CGN->removeCallEdgeTo(*(CGN->end()-1)); - - // If the function has external linkage (basically if it's a linkonce - // function) remove the edge from the external node to the callee - // node. - if (!F->hasInternalLinkage()) - CG.getExternalCallingNode()->removeCallEdgeTo(CGN); - - // Removing the node for callee from the call graph and delete it. - FunctionsToRemove.insert(CGN); + if (Function *F = CGN ? CGN->getFunction() : 0) { + // If the only remaining users of the function are dead constants, + // remove them. + bool HadDeadConstantUsers = !F->use_empty(); + F->removeDeadConstantUsers(); + + if ((F->hasLinkOnceLinkage() || F->hasInternalLinkage()) && + F->use_empty()) { + // Remove any call graph edges from the function to its callees. + while (CGN->begin() != CGN->end()) + CGN->removeCallEdgeTo(*(CGN->end()-1)); + + // If the function has external linkage (basically if it's a linkonce + // function) remove the edge from the external node to the callee + // node. + if (!F->hasInternalLinkage() || HadDeadConstantUsers) + CG.getExternalCallingNode()->removeCallEdgeTo(CGN); + + // Removing the node for callee from the call graph and delete it. + FunctionsToRemove.insert(CGN); + } } } From lattner at cs.uiuc.edu Sat Aug 7 22:33:20 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Aug 2004 22:33:20 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408080333.WAA10406@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.227 -> 1.228 --- Log message: This isn't a bug, it's a missing feature --- Diffs of the changes: (+2 -4) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.227 llvm/docs/ReleaseNotes.html:1.228 --- llvm/docs/ReleaseNotes.html:1.227 Thu Aug 5 16:53:13 2004 +++ llvm/docs/ReleaseNotes.html Sat Aug 7 22:33:07 2004 @@ -430,9 +430,7 @@ such, execution of a threaded program could cause these data structures to be corrupted. -
        • It is not possible to dlopen an LLVM bytecode file in the JIT.
        • - -
        • Linking in static archive files (.a files) is very slow (there is no symbol +
        • Linking in static archive files (.a files) is slow (there is no symbol table in the archive).
        • The gccld program does not link @@ -768,7 +766,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
          - Last modified: $Date: 2004/08/05 21:53:13 $ + Last modified: $Date: 2004/08/08 03:33:07 $ From alkis at cs.uiuc.edu Sun Aug 8 19:04:44 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 8 Aug 2004 19:04:44 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.nightly.report Message-ID: <200408090004.TAA29656@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.nightly.report updated: 1.26 -> 1.27 --- Log message: Write 'beta' with capital letters to be consistent. --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/TEST.nightly.report diff -u llvm/test/Programs/TEST.nightly.report:1.26 llvm/test/Programs/TEST.nightly.report:1.27 --- llvm/test/Programs/TEST.nightly.report:1.26 Fri Jul 23 08:34:17 2004 +++ llvm/test/Programs/TEST.nightly.report Sun Aug 8 19:04:33 2004 @@ -75,5 +75,5 @@ ["JIT-BETA" , 'TEST-RESULT-jit-ls-time: real\s*([.0-9m:]+)', \&FormatTime], ["GCC/CBE" , \&GCCCBERatio], ["GCC/LLC" , \&GCCLLCRatio], - ["GCC/LLC-Beta" , \&GCCLLC_BETARatio] + ["GCC/LLC-BETA" , \&GCCLLC_BETARatio] ); From reid at x10sys.com Sun Aug 8 20:24:42 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 8 Aug 2004 20:24:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp Message-ID: <200408090124.UAA29900@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCRegisterInfo.cpp updated: 1.24 -> 1.25 --- Log message: Fix stack size processing now that the return address isn't an implied push onto the top of the stack like x86, which uses the local area offset. This will allow the removal of PowerPCPEI.cpp soon. --- Diffs of the changes: (+4 -2) Index: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.24 llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.25 --- llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.24 Fri Aug 6 01:58:50 2004 +++ llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp Sun Aug 8 20:24:32 2004 @@ -210,9 +210,11 @@ // Do we need to allocate space on the stack? if (NumBytes == 0) return; - // Round the size to a multiple of the alignment + // Add the size of R1 to NumBytes size for the store of R1 to the bottom + // of the stack and round the size to a multiple of the alignment. unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - NumBytes = (NumBytes+Align-1)/Align*Align; + unsigned Size = getRegClass(PPC32::R1)->getSize(); + NumBytes = (NumBytes+Size+Align-1)/Align*Align; // Update frame info to pretend that this is part of the stack... MFI->setStackSize(NumBytes); From reid at x10sys.com Sun Aug 8 20:32:37 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 08 Aug 2004 18:32:37 -0700 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp In-Reply-To: <200408090124.UAA29900@zion.cs.uiuc.edu> References: <200408090124.UAA29900@zion.cs.uiuc.edu> Message-ID: <1092015157.25653.120.camel@bashful.x10sys.com> Whoops, forgot to give Nate credit for this commit. It certainly wasn't me who fixed it :) Reid. On Sun, 2004-08-08 at 18:24, Reid Spencer wrote: > Changes in directory llvm/lib/Target/PowerPC: > > PowerPCRegisterInfo.cpp updated: 1.24 -> 1.25 > --- > Log message: > > Fix stack size processing now that the return address isn't an implied > push onto the top of the stack like x86, which uses the local area > offset. This will allow the removal of PowerPCPEI.cpp soon. > > > --- > Diffs of the changes: (+4 -2) > > Index: llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp > diff -u llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.24 llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.25 > --- llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp:1.24 Fri Aug 6 01:58:50 2004 > +++ llvm/lib/Target/PowerPC/PowerPCRegisterInfo.cpp Sun Aug 8 20:24:32 2004 > @@ -210,9 +210,11 @@ > // Do we need to allocate space on the stack? > if (NumBytes == 0) return; > > - // Round the size to a multiple of the alignment > + // Add the size of R1 to NumBytes size for the store of R1 to the bottom > + // of the stack and round the size to a multiple of the alignment. > unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); > - NumBytes = (NumBytes+Align-1)/Align*Align; > + unsigned Size = getRegClass(PPC32::R1)->getSize(); > + NumBytes = (NumBytes+Size+Align-1)/Align*Align; > > // Update frame info to pretend that this is part of the stack... > MFI->setStackSize(NumBytes); > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20040808/f71f46ff/attachment.bin From reid at x10sys.com Sun Aug 8 22:08:40 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 8 Aug 2004 22:08:40 -0500 Subject: [llvm-commits] CVS: llvm/docs/CompilerDriver.html Message-ID: <200408090308.WAA30271@zion.cs.uiuc.edu> Changes in directory llvm/docs: CompilerDriver.html added (r1.1) --- Log message: This is the initial draft of the Compiler Driver documentation. It is not worthy of review at this point. There is much thought and content remaining to be written. --- Diffs of the changes: (+572 -0) Index: llvm/docs/CompilerDriver.html diff -c /dev/null llvm/docs/CompilerDriver.html:1.1 *** /dev/null Sun Aug 8 22:08:39 2004 --- llvm/docs/CompilerDriver.html Sun Aug 8 22:08:29 2004 *************** *** 0 **** --- 1,572 ---- + + + + + The LLVM Compiler Driver (llvmc) + + + + + + +
          The LLVM Compiler Driver (llvmc)
          +

          NOTE: This document is a work in progress!

          +
            +
          1. Abstract
          2. +
          3. Introduction +
              +
            1. Purpose
            2. +
            3. Operation
            4. +
            5. Phases
            6. +
            7. Actions
            8. +
            +
          4. +
          5. Details +
          6. Configuration +
          7. Glossary +
          +
          +

          Written by Reid Spencer +

          +
          + + + + +
          +

          This document describes the requirements, design, and configuration of the + LLVM compiler driver, llvmc. The compiler driver knows about LLVM's + tool set and can be configured to know about a variety of compilers for + source languages. It uses this knowledge to execute the tools necessary + to accomplish general compilation, optimization, and linking tasks. The main + purpose of llvmc is to provide a simple and consistent interface to + all compilation tasks. This reduces the burden on the end user who can just + learn to use llvmc instead of the entire LLVM tool set and all the + source language compilers compatible with LLVM.

          +
          + + + +
          +

          The llvmc tool is a configurable compiler + driver. As such, it isn't the compiler, optimizer, + or linker itself but it drives (invokes) other software that perform those + tasks. If you are familiar with the GNU Compiler Collection's gcc + tool, llvmc is very similar.

          +

          The following introductory sections will help you understand why this tool + is necessary and what it does.

          +
          + + + +
          +

          llvmc was invented to make compilation with LLVM based compilers + easier. To accomplish this, llvmc strives to:

          +
            +
          • Be the single point of access to most of the LLVM tool set.
          • +
          • Hide the complexities of the LLVM tools through a single interface.
          • +
          • Provide a consistent interface for compiling all languages.
          • +
          +

          Additionally, llvmc makes it easier to write a compiler for use + with LLVM, because it:

          +
            +
          • Makes integration of existing non-LLVM tools simple.
          • +
          • Extends the capabilities of minimal front ends by optimizing their + output.
          • +
          • Reduces the number of interfaces a compiler writer must know about + before a working compiler can be completed (essentially only the VMCore + interfaces need to be understood).
          • +
          • Supports source language translator invocation via both dynamically + loadable shared objects and invocation of an executable.
          • + +

            +
          + + + +
          +

          At a high level, llvmc operation is very simple. The basic action + taken by llvmc is to simply invoke some tool or set of tools to fill + the user's request for compilation. Every execution of llvmctakes the + following sequence of steps:
          +

          +
          Collect Command Line Options
          +
          The command line options provide the marching orders to llvmc + on what actions it should perform. This is the request the user is making + of llvmc and it is interpreted first. See the llvmc + manual page for details on the + options.
          +
          Read Configuration Files
          +
          Based on the options and the suffixes of the filenames presented, a set + of configuration files are read to configure the actions llvmc will + take. Configuration files are provided by either LLVM or the front end + compiler tools that B invokes. These files determine what actions + llvmc will take in response to the user's request. See the section + on configuration for more details.
          +
          Determine Phases To Execute
          +
          Based on the command line options and configuration files, + llvmc determines the compilation phases that + must be executed by the user's request. This is the primary work of + llvmc.
          +
          Determine Actions To Execute
          +
          Each phase to be executed can result in the + invocation of one or more actions. An action is + either a whole program or a function in a dynamically linked shared library. + In this step, llvmc determines the sequence of actions that must be + executed. Actions will always be executed in a deterministic order.
          +
          Execute Actions
          +
          The actions necessary to support the user's + original request are executed sequentially and deterministically. All + actions result in either the invocation of a whole program to perform the + action or the loading of a dynamically linkable shared library and invocation + of a standard interface function within that library.
          +
          Termination
          +
          If any action fails (returns a non-zero result code), llvmc + also fails and returns the result code from the failing action. If + everything succeeds, llvmc will return a zero result code.
          +

          +

          llvmc's operation must be simple, regular and predictable. + Developers need to be able to rely on it to take a consistent approach to + compilation. For example, the invocation:

          +
          +    llvmc -O2 x.c y.c z.c -o xyz
          +

          must produce exactly the same results as:

          +
          +    llvmc -O2 x.c
          +    llvmc -O2 y.c
          +    llvmc -O2 z.c
          +    llvmc -O2 x.o y.o z.o -o xyz
          +

          To accomplish this, llvmc uses a very simple goal oriented + procedure to do its work. The overall goal is to produce a functioning + executable. To accomplish this, llvmc always attempts to execute a + series of compilation phases in the same sequence. + However, the user's options to llvmc can cause the sequence of phases + to start in the middle or finish early.

          +
          + + +
          Phases
          +
          +

          llvmc breaks every compilation task into the following five + distinct phases:

          +
          Preprocessing
          Not all languages support preprocessing; + but for those that do, this phase can be invoked. This phase is for + languages that provide combining, filtering, or otherwise altering with the + source language input before the translator parses it. Although C and C++ + are the most common users of this phase, other languages may provide their + own preprocessor (whether its the C pre-processor or not).
          +
          +
          Translation
          The translation phase converts the source + language input into something that LLVM can interpret and use for + downstream phases. The translation is essentially from "non-LLVM form" to + "LLVM form".
          +
          +
          Optimization
          Once an LLVM Module has been obtained from + the translation phase, the program enters the optimization phase. This phase + attempts to optimize all of the input provided on the command line according + to the options provided.
          +
          +
          Linking
          The inputs are combined to form a complete + program.
          +
          +

          The following table shows the inputs, outputs, and command line options + applicabe to each phase.

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          PhaseInputsOutputsOptions
          Preprocessing
          • Source Language File
          • Source Language File
          +
          -E
          +
          Stops the compilation after preprocessing
          +
          Translation
            +
          • Source Language File
          • +
            +
          • LLVM Assembly
          • +
          • LLVM Bytecode
          • +
          • LLVM C++ IR
          • +
          +
          -c
          +
          Stops the compilation after translation so that optimization and + linking are not done.
          +
          -S
          +
          Stops the compilation before object code is written so that only + assembly code remains.
          +
          Optimization
            +
          • LLVM Assembly
          • +
          • LLVM Bytecode
          • +
            +
          • LLVM Bytecode
          • +
          +
          -Ox +
          This group of options affects the amount of optimization + performed.
          +
          Linking
            +
          • LLVM Bytecode
          • +
          • Native Object Code
          • +
          • LLVM Library
          • +
          • Native Library
          • +
            +
          • LLVM Bytecode Executable
          • +
          • Native Executable
          • +
          +
          -L
          Specifies a path for library search.
          +
          -l
          Specifies a library to link in.
          +
          +
          + + +
          Actions
          +
          +

          An action, with regard to llvmc is a basic operation that it takes + in order to fulfill the user's request. Each phase of compilation will invoke + zero or more actions in order to accomplish that phase.

          +

          Actions come in two forms:

            +
          1. Invokable Executables
          2. +
          3. Functions in a shared library
          4. +

        + + + + + +
        +
        + + + + +
        +

        This section of the document describes the configuration files used by + llvmc. Configuration information is relatively static for a + given release of LLVM and a front end compiler. However, the details may + change from release to release of either. Users are encouraged to simply use + the various options of the B command and ignore the configuration of + the tool. These configuration files are for compiler writers and LLVM + developers. Those wishing to simply use B don't need to understand + this section but it may be instructive on how the tool works.

        +
        + + +
        Overview
        +
        +

        llvmc is highly configurable both on the command line and in + configuration files. The options it understands are generic, consistent and + simple by design. Furthermore, the llvmc options apply to the + compilation of any LLVM enabled programming language. To be enabled as a + supported source language compiler, a compiler writer must provide a + configuration file that tells llvmc how to invoke the compiler + and what its capabilities are. The purpose of the configuration files then + is to allow compiler writers to specify to llvmc how the compiler + should be invoked. Users may but are not advised to alter the compiler's + llvmc configuration.

        + +

        Because llvmc just invokes other programs, it must deal with the + available command line options for those programs regardless of whether they + were written for LLVM or not. Furthermore, not all compilation front ends will + have the same capabilities. Some front ends will simply generate LLVM assembly + code, others will be able to generate fully optimized byte code. In general, + llvmc doesn't make any assumptions about the capabilities or command + line options of a sub-tool. It simply uses the details found in the configuration + files and leaves it to the compiler writer to specify the configuration + correctly.

        + +

        This approach means that new compiler front ends can be up and working very + quickly. As a first cut, a front end can simply compile its source to raw + (unoptimized) bytecode or LLVM assembly and llvmc can be configured + to pick up the slack (translate LLVM assembly to bytecode, optimize the + bytecode, generate native assembly, link, etc.). In fact, the front end need + not use any LLVM libraries, and it could be written in any language (instead of + C++). The configuration data will allow the full range of optimization, + assembly, and linking capabilities that LLVM provides to be added to these kinds + of tools. Enabling the rapid development of front-ends is one of the primary + goals of llvmc.

        + +

        As a compiler front end matures, it may utilize the LLVM libraries and tools + to more efficiently produce optimized bytecode directly in a single compilation + and optimization program. In these cases, multiple tools would not be needed + and the configuration data for the compiler would change.

        + +

        Configuring llvmc to the needs and capabilities of a source language + compiler is relatively straight forward. A compiler writer must provide a + definition of what to do for each of the five compilation phases for each of + the optimization levels. The specification consists simply of prototypical + command lines into which llvmc can substitute command line + arguments and file names. Note that any given phase can be completely blank if + the source language's compiler combines multiple phases into a single program. + For example, quite often pre-processing, translation, and optimization are + combined into a single program. The specification for such a compiler would have + blank entries for pre-processing and translation but a full command line for + optimization.

        +
        + + +
        Configuration Files
        +
        +

        Types of Files

        +

        There are two types of configuration files: the master configuration file + and the language specific configuration file. The master configuration file + contains the general configuration of llvmc itself and is supplied + with the tool. It contains information that is source language agnostic. + Language specific configuration files tell llvmc how to invoke the + language's compiler for a variety of different tasks and what other tools + are needed to backfill the compiler's missing features (e.g. + optimization).

        + +

        Directory Search

        +

        llvmc always looks for files of a specific name. It uses the + first file with the name its looking for by searching directories in the + following order:
        +

          +
        1. Any directory specified by the --config-dir option will be + checked first.
        2. +
        3. If the environment variable LLVM_CONFIG_DIR is set, and it contains + the name of a valid directory, that directory will be searched next.
        4. +
        5. If the user's home directory (typically /home/user contains + a sub-directory named .llvm and that directory contains a + sub-directory named etc then that directory will be tried + next.
        6. +
        7. If the LLVM installation directory (typically /usr/local/llvm + contains a sub-directory named etc then that directory will be + tried last.
        8. +
        9. If the configuration file sought still can't be found, llvmc + will print an error message and exit.
        10. +
        + The first file found in this search will be used. Other files with the same + name will be ignored even if they exist in one of the subsequent search + locations.

        + +

        File Names

        +

        In the directories searched, a file named master will be + recognized as the master configuration file for llvmc. Note that + users may override the master file with a copy in their home directory + but they are advised not to. This capability is only useful for compiler + implementers needing to alter the master configuration while developing + their compiler front end. When reading the configuration files, the master + files are always read first.

        +

        Language specific configuration files are given specific names to foster + faster lookup. The name of a given language specific configuration file is + the same as the suffix used to identify files containing source in that + language. For example, a configuration file for C++ source might be named + cpp, C, or cxx.

        + +

        What Gets Read

        +

        The master configuration file is always read. Which language specific + configuration files are read depends on the command line options and the + suffixes of the file names provided on llvmc's command line. Note + that the --x LANGUAGE option alters the language that llvmc + uses for the subsequent files on the command line. Only the language + specific configuration files actually needed to complete llvmc's + task are read. Other language specific files will be ignored.

        +
        + + +
        Syntax
        +
        +

        The syntax of the configuration files is yet to be determined. There are + two viable options remaining:
        +

          +
        • XML DTD Specific To llvmc
        • +
        • Windows .ini style file with numerous sections
        • +

        +
        + + +
        + Master Configuration Items +
        +
        +
        + 
        + =head3 Section: [lang=I]
        + 
        + This section provides the master configuration data for a given language. The
        + language specific data will be found in a file named I.
        + 
        + =over
        + 
        + =item CI
        + 
        + This adds the I specified to the list of recognized suffixes for
        + the I identified in the section. As many suffixes as are commonly used
        + for source files for the I should be specified. 
        + 
        + =back
        + 
        + =begin html
        + 
        + 

        For example, the following might appear for C++: +

        
        + [lang=C++]
        + suffix=.cpp
        + suffix=.cxx
        + suffix=.C
        + 

        + + =end html +
        +
        + + +
        + Language Specific Configuration Items +
        +
        +
        + =head3 Section: [general]
        + 
        + =over
        + 
        + =item C
        + 
        + This item specifies whether the language has a pre-processing phase or not. This
        + controls whether the B<-E> option works for the language or not.
        + 
        + =item C
        + 
        + This item specifies the kind of output the language's compiler generates. The
        + choices are either bytecode (C) or LLVM assembly (C).
        + 
        + =back
        + 
        + =head3 Section: [-O0]
        + 
        + =over
        + 
        + =item CI
        + 
        + This item specifies the I to use for pre-processing the input.
        + 
        + =over
        + 
        + Valid substitutions for this item are:
        + 
        + =item %in%
        + 
        + The input source file.
        + 
        + =item %out%
        + 
        + The output file.
        + 
        + =item %options%
        + 
        + Any pre-processing specific options (e.g. B<-I>).
        + 
        + =back
        + 
        + =item CI
        + 
        + This item specifies the I to use for translating the source
        + language input into the output format given by the C item.
        + 
        + =item CI
        + 
        + This item specifies the I for optimizing the translator's output.
        + 
        + =back
        + 
        +
        + + + + +
        +

        This document uses precise terms in reference to the various artifacts and + concepts related to compilation. The terms used throughout this document are + defined below.

        +
        +
        assembly
        +
        A compilation phase in which LLVM bytecode or + LLVM assembly code is assembled to a native code format (either target + specific aseembly language or the platform's native object file format). +
        + +
        compiler
        +
        Refers to any program that can be invoked by llvmc to accomplish + the work of one or more compilation phases.
        + +
        driver
        +
        Refers to llvmc itself.
        + +
        linking
        +
        A compilation phase in which LLVM bytecode files + and (optionally) native system libraries are combined to form a complete + executable program.
        + +
        optimization
        +
        A compilation phase in which LLVM bytecode is + optimized.
        + +
        phase
        +
        Refers to any one of the five compilation phases that that + llvmc supports. The five phases are: + preprocessing, + translation, + optimization, + assembly, + linking.
        + +
        source language
        +
        Any common programming language (e.g. C, C++, Java, Stacker, ML, + FORTRAN). These languages are distinguished from any of the lower level + languages (such as LLVM or native assembly), by the fact that a + translation phase + is required before LLVM can be applied.
        + +
        tool
        +
        Refers to any program in the LLVM tool set.
        + +
        translation
        +
        A compilation phase in which + source language code is translated into + either LLVM assembly language or LLVM bytecode.
        +
        +
        + +
        +
        Valid CSS!Valid HTML 4.01!Reid Spencer
        + The LLVM Compiler Infrastructure
        + Last modified: $Date: 2004/08/09 03:08:29 $ +
        + + + From reid at x10sys.com Sun Aug 8 22:10:49 2004 From: reid at x10sys.com (Reid Spencer) Date: Sun, 8 Aug 2004 22:10:49 -0500 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/llvmc.pod Message-ID: <200408090310.WAA30317@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llvmc.pod updated: 1.4 -> 1.5 --- Log message: Move information on Configuration files to the ../CompilerDriver.html file since it doesn't belong in the man page. --- Diffs of the changes: (+9 -235) Index: llvm/docs/CommandGuide/llvmc.pod diff -u llvm/docs/CommandGuide/llvmc.pod:1.4 llvm/docs/CommandGuide/llvmc.pod:1.5 --- llvm/docs/CommandGuide/llvmc.pod:1.4 Sat Aug 7 11:30:14 2004 +++ llvm/docs/CommandGuide/llvmc.pod Sun Aug 8 22:10:39 2004 @@ -55,8 +55,10 @@ =item * Configuration files are read. Based on the options and the suffixes of the filenames presented, a set of -configuration files are read to configure the actions B will take -(more on this later). +configuration files are read to configure the actions B will take. +Configuration files are provided by either LLVM or the front end compiler tools +that B invokes. Users generally don't need to be concerned with the +contents of the configuration files. =item * Determine actions to take. @@ -66,15 +68,15 @@ =over -=item * Pre-processing: gathering/filtering compiler input +=item * Pre-processing: gathering/filtering compiler input (optional). -=item * Compilation: source language to bytecode conversion +=item * Translation: source language to bytecode conversion. -=item * Assembly: bytecode to native code conversion +=item * Assembly: bytecode to native code conversion. -=item * Optimization: conversion of bytecode to something that runs faster +=item * Optimization: conversion of bytecode to something that runs faster. -=item * Linking: combining multiple bytecodes to produce executable program +=item * Linking: combining multiple bytecodes to produce executable program. =back @@ -372,234 +374,6 @@ =back -=head1 CONFIGURATION - -=head2 Warning - -Configuration information is relatively static for a given release of LLVM and -a front end compiler. However, the details may change from release to release. -Users are encouraged to simply use the various options of the B command -and ignore the configuration of the tool. These configuration files are for -compiler writers and LLVM developers. Those wishing to simply use B -don't need to understand this section but it may be instructive on what the tool -does. - -=head2 Introduction - -B is highly configurable both on the command line and in configuration -files. The options it understands are generic, consistent and simple by design. -Furthermore, the B options apply to the compilation of any LLVM enabled -programming language. To be enabled as a supported source language compiler, a -compiler writer must provide a configuration file that tells B how to -invoke the compiler and what its capabilities are. The purpose of the -configuration files then is to allow compiler writers to specify to B how -the compiler should be invoked. Users may but are not advised to alter the -compiler's B configuration. - -Because B just invokes other programs, it must deal with the -available command line options for those programs regardless of whether they -were written for LLVM or not. Furthermore, not all compilation front ends will -have the same capabilities. Some front ends will simply generate LLVM assembly -code, others will be able to generate fully optimized byte code. In general, -B doesn't make any assumptions about the capabilities or command line -options of a sub-tool. It simply uses the details found in the configuration -files and leaves it to the compiler writer to specify the configuration -correctly. - -This approach means that new compiler front ends can be up and working very -quickly. As a first cut, a front end can simply compile its source to raw -(unoptimized) bytecode or LLVM assembly and B can be configured to pick -up the slack (translate LLVM assembly to bytecode, optimize the bytecode, -generate native assembly, link, etc.). In fact, the front end need not use -any LLVM libraries, and it could be written in any language (instead of C++). -The configuration data will allow the full range of optimization, assembly, -and linking capabilities that LLVM provides to be added to these kinds of tools. -Enabling the rapid development of front-ends is one of the primary goals of -B. - -As a compiler front end matures, it may utilize the LLVM libraries and tools to -more efficiently produce optimized bytecode directly in a single compilation and -optimization program. In these cases, multiple tools would not be needed and -the configuration data for the compiler would change. - -Configuring B to the needs and capabilities of a source language compiler -is relatively straight forward. The compilation process is broken down into five -phases: - -=over - -=item * Pre-processing (filter and combine source files) - -=item * Translation (translate source language to LLVM assembly or bytecode) - -=item * Optimization (make bytecode execute quickly) - -=item * Assembly (converting bytecode to object code) - -=item * Linking (converting translated code to an executable) - -=back - -A compiler writer must provide a definition of what to do for each of these five -phases for each of the optimization levels. The specification consists simply of -prototypical command lines into which B can substitute command line -arguments and file names. Note that any given phase can be completely blank if -the source language's compiler combines multiple phases into a single program. -For example, quite often pre-processing, translation, and optimization are -combined into a single program. The specification for such a compiler would have -blank entries for pre-processing and translation but a full command line for -optimization. - -=head2 Configuration File Types - -There are two types of configuration files: the master configuration file -and the language specific configuration file. - -The master configuration file contains the general configuration of B -itself. This includes things like the mapping between file extensions and -source languages. This mapping is needed in order to quickly read only the -applicable language-specific configuration files (avoiding reading every -configuration file for every compilation task). - -Language specific configuration files tell B how to invoke the language's -compiler for a variety of different tasks and what other tools are needed to -I the compiler's missing features (e.g. optimization). - -Language specific configuration files are placed in directories and given -specific names to foster faster lookup. The name of a given configuration file -is the name of the source language. - -=head2 Default Directory Locations - -B will look for configuration files in two standard locations: the -LLVM installation directory (typically C) and the user's -home directory (typically C). In these directories a file -named C provides the master configuration for B. Language -specific files will have a language specific name (e.g. C++, Stacker, Scheme, -FORTRAN). When reading the configuration files, the master files are always -read first in the following order: - -=over - -=item 1 C in LLVM installation directory - -=item 2 C in the user's home directory. - -=back - -Then, based on the command line options and the suffixes of the file names -provided on B's command line, one or more language specific configuration -files are read. Only the language specific configuration files actually needed -to complete B's task are read. Other language specific files will be -ignored. - -Note that the user can affect this process in several ways using the various -B<--config-*> options and with the B<--x LANGUAGE> option. - -Although a user I override the master configuration file, this is not -advised. The capability is retained so that compiler writers can affect the -master configuration (such as adding new file suffixes) while developing a new -compiler front end since they might not have write access to the installed -master configuration. - -=head2 Syntax - -The syntax of the configuration files is yet to be determined. There are three -viable options: - -=over - -=item XML - -=item Windows .ini - -=item specific to B - -=back - -=head2 Master Configuration Items - -=head3 Section: [lang=I] - -This section provides the master configuration data for a given language. The -language specific data will be found in a file named I. - -=over - -=item CI - -This adds the I specified to the list of recognized suffixes for -the I identified in the section. As many suffixes as are commonly used -for source files for the I should be specified. - -=back - -=begin html - -

        For example, the following might appear for C++: -

        
        -[lang=C++]
        -suffix=.cpp
        -suffix=.cxx
        -suffix=.C
        -

        - -=end html - -=head2 Language Specific Configuration Items - -=head3 Section: [general] - -=over - -=item C - -This item specifies whether the language has a pre-processing phase or not. This -controls whether the B<-E> option works for the language or not. - -=item C - -This item specifies the kind of output the language's compiler generates. The -choices are either bytecode (C) or LLVM assembly (C). - -=back - -=head3 Section: [-O0] - -=over - -=item CI - -This item specifies the I to use for pre-processing the input. - -=over - -Valid substitutions for this item are: - -=item %in% - -The input source file. - -=item %out% - -The output file. - -=item %options% - -Any pre-processing specific options (e.g. B<-I>). - -=back - -=item CI - -This item specifies the I to use for translating the source -language input into the output format given by the C item. - -=item CI - -This item specifies the I for optimizing the translator's output. - -=back =head1 EXIT STATUS
    • Function(const FunctionType - *Ty, bool isInternal, const std::string &N = "", Module* Parent = 0) + *Ty, LinkageTypes Linkage, const std::string &N = "", Module* Parent = 0)

      Constructor used when you need to create new Functions to add the the program. The constructor must specify the type of the function to - create and whether or not it should start out with internal or external - linkage. The FunctionType argument + create and what type of linkage the function should have. The FunctionType argument specifies the formal arguments and return value for the function. The same FunctionType value can be used to create multiple functions. The Parent argument specifies the Module @@ -2044,7 +2044,7 @@ Dinakar Dhurjati and Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/07/18 21:44:13 $ + Last modified: $Date: 2004/08/04 05:10:48 $ From gaeke at cs.uiuc.edu Wed Aug 4 00:28:14 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 00:28:14 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/lib/TraceToFunction/TraceToFunction.cpp Message-ID: <200408040528.AAA00914@seraph.cs.uiuc.edu> Changes in directory reopt/lib/TraceToFunction: TraceToFunction.cpp updated: 1.82 -> 1.83 --- Log message: Split findAlternateEntryPoints() out from buildFLIMap(). Make it smarter -- fixing the Olden/tsp and Stanford/Puzzle infinite loop bug. In addTraceLiveInsToSet(), and in many other places, only allow Arguments and Instructions as trace live-in/out variables. Add an assertion to insert() to check this. Get rid of the (disabled) code that calls hasUseDominatedByEdge(). There is a place for this check, but it is _not_ here. Don't dump the DominatorSet every time in debug mode. It gets boring, let me tell you. --- Diffs of the changes: (+35 -27) Index: reopt/lib/TraceToFunction/TraceToFunction.cpp diff -u reopt/lib/TraceToFunction/TraceToFunction.cpp:1.82 reopt/lib/TraceToFunction/TraceToFunction.cpp:1.83 --- reopt/lib/TraceToFunction/TraceToFunction.cpp:1.82 Thu Jul 29 23:04:44 2004 +++ reopt/lib/TraceToFunction/TraceToFunction.cpp Wed Aug 4 00:28:02 2004 @@ -78,6 +78,7 @@ void buildFLIMap (Trace &T, FLIMapTy &FLIMap); // Main methods of TraceFunctionBuilder transformation + void findAlternateEntryPoints (Trace &T, std::vector &b); TypeVector createFunctionArgTypeVector (const LiveVariableVector &LiveIns, const LiveVariableVector &LiveOuts); void giveNamesToFunctionArgs (const LiveVariableVector &LiveIns, @@ -201,6 +202,8 @@ } static void insert (LiveVariableSet &Set, LiveVariableVector &Vector, Value *V){ + assert ((isa (V) || isa (V)) + && "Weird: live variable not defined by instr"); Set.insert (V); if (std::find (Vector.begin (), Vector.end (), V) == Vector.end ()) Vector.push_back (V); @@ -225,8 +228,7 @@ if (std::find (StartingFrom, T.end (), InB) != T.end ()) { Value *V = PN->getIncomingValue (i); // neglect incoming phi values from off-trace - if (!(isa (V) || isa (V) - || isa(V))) { + if (isa (V) || isa (V)) { DEBUG (std::cerr << "TLV: considering Phi source which is on-trace: " << InB->getName () << " with value " << V->getName () << "\n"); if (!DefinedInTraceBeforeUse (V, T, StartingFrom, true)) insert (S, LVV, V); @@ -239,8 +241,7 @@ } for (unsigned i = 0; i < Inst->getNumOperands (); ++i) { Value *V = Inst->getOperand (i); // V is used in the trace by Inst. - if (!(isa (V) || isa (V) - || isa(V))) + if (isa (V) || isa (V)) if (!DefinedInTraceBeforeUse (V, T, StartingFrom, true)) insert (S, LVV, V); } @@ -599,14 +600,6 @@ DEBUG (std::cerr << "buildFLIMap: identified FLI block " << i->getName() << " on edge <" << edge.first->getName () << ", " << edge.second->getName () << ">\n"); - if (T.contains (edge.second) && edge.second != T.getEntryBasicBlock ()) { - DEBUG (std::cerr << "buildFLIMap: " << edge.second->getName() - << " is a back-edge target that's internal to the trace\n"); - if (std::find (AlternateEntryPointsV.begin (), - AlternateEntryPointsV.end (), edge.second) - == AlternateEntryPointsV.end ()) - AlternateEntryPointsV.push_back (edge.second); - } // 1. remove the block from the trace if it is in there BasicBlock *bb = i; Trace::iterator TI = std::find (T.begin (), T.end (), bb); @@ -620,6 +613,24 @@ } } +// Fill in b with all the (possible) alternate entry points into T. +void TraceFunctionBuilder::findAlternateEntryPoints (Trace &T, + std::vector &b) { + for (Trace::iterator TI = T.begin (), TE = T.end(); TI != TE; ++TI) { + BasicBlock *Blk = *TI; + if (Blk == T.getEntryBasicBlock ()) + continue; + for (Value::use_iterator ui = Blk->use_begin (), ue = Blk->use_end (); + ui != ue; ++ui) { + assert (isa (*ui) + && "can't deal with non-Instruction Users of BasicBlocks"); + if (!T.contains (cast (*ui)->getParent ())) + if (std::find (b.begin (), b.end (), Blk) == b.end ()) + b.push_back (Blk); + } + } +} + BasicBlock *TraceFunctionBuilder::getFLIEdgeSource (BasicBlock *BB) const { FLIMapTy::const_iterator i = FLIMap.find (BB); if (i == FLIMap.end ()) return 0; @@ -784,17 +795,17 @@ // Add the getelementptr/store instruction pairs here that // correspond to each live-out variable. for (LiveVariableVector::iterator SI = So.begin (), SE = So.end (); - SI != SE; ++SI) - if (dominates (T, cast ((*SI))->getParent (), -#if 0 // WARNING: hasUseDominatedByEdge isn't working right yet! - BI->getParent ()) - && hasUseDominatedByEdge (cast (*SI), srcB, - successor)) -#else - BI->getParent ())) -#endif - FB->getInstList ().push_back - (new StoreInst (O2CMap[*SI], TF->LiveOutToArgMap[*SI])); + SI != SE; ++SI) { + Value *V = *SI; + bool storeIt = true; + if (Instruction *Inst = dyn_cast (V)) + storeIt = dominates (T, Inst->getParent (), BI->getParent ()); + else // it's an Argument, so it must dominate the store. + assert (isa (V) && "not instruction, not argument??"); + if (storeIt) + FB->getInstList ().push_back (new StoreInst (O2CMap[V], + TF->LiveOutToArgMap[V])); + } // Make FB contain a return instruction that returns the // number of the taken exit-branch. Add it to the end of FB: ReturnInst *RI = new ReturnInst (ConstantUInt::get (Type::UIntTy, @@ -864,11 +875,7 @@ bool TraceFunctionBuilder::runOnFunction (Function &F) { if (T.getFunction () != &F) { return false; } - DS = &getAnalysis(); - DEBUG (std::cerr << "Dominator set information:\n"; - DS->print (std::cerr); - std::cerr << "End dominator set information.\n"); // Create a TraceFunction object to hold the trace function along with // its auxiliary data structures. @@ -883,6 +890,7 @@ // Get some information about the trace's relationship to its parent // function. + findAlternateEntryPoints (T, AlternateEntryPointsV); buildTraceLiveInSet (LiveInSet, TF->LiveInVector, T); buildTraceLiveOutSet (LiveOutSet, TF->LiveOutVector, T); TypeVector P = createFunctionArgTypeVector (TF->LiveInVector, From gaeke at cs.uiuc.edu Wed Aug 4 00:28:15 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 00:28:15 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/test/run-tests Message-ID: <200408040528.AAA00929@seraph.cs.uiuc.edu> Changes in directory reopt/test: run-tests updated: 1.16 -> 1.17 --- Log message: Add my hacked version of mst to the list, as well as all the other spec2000 benchmarks that currently work on sparc (llc+jit). --- Diffs of the changes: (+7 -0) Index: reopt/test/run-tests diff -u reopt/test/run-tests:1.16 reopt/test/run-tests:1.17 --- reopt/test/run-tests:1.16 Tue Jul 27 13:47:23 2004 +++ reopt/test/run-tests Wed Aug 4 00:28:05 2004 @@ -73,11 +73,18 @@ power) SUBDIR=MultiSource/Benchmarks/Olden/power ;; tsp) SUBDIR=MultiSource/Benchmarks/Olden/tsp ;; + hackedmst) SUBDIR=SingleSource/Reoptimizer/Mst ;; + mcf) SUBDIR=External/SPEC/CINT2000/181.mcf; spectest=1 ;; art) SUBDIR=External/SPEC/CFP2000/179.art; spectest=1;; equake) SUBDIR=External/SPEC/CFP2000/183.equake; spectest=1 ;; gzip) SUBDIR=External/SPEC/CINT2000/164.gzip; spectest=1 ;; bzip2) SUBDIR=External/SPEC/CINT2000/256.bzip2; spectest=1 ;; + crafty) SUBDIR=External/SPEC/CINT2000/186.crafty; spectest=1 ;; + parser) SUBDIR=External/SPEC/CINT2000/197.parser; spectest=1 ;; + vortex) SUBDIR=External/SPEC/CINT2000/255.vortex; spectest=1 ;; + twolf) SUBDIR=External/SPEC/CINT2000/300.twolf; spectest=1 ;; + ammp) SUBDIR=External/SPEC/CFP2000/188.ammp; spectest=1 ;; *) ucname=`echo $benchmk | perl -pe '$_ = ucfirst lc $_;'` SUBDIR=$EXTRATESTSUBDIR/$ucname From gaeke at cs.uiuc.edu Wed Aug 4 00:28:14 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 00:28:14 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/test/Summarize.pl Message-ID: <200408040528.AAA00915@seraph.cs.uiuc.edu> Changes in directory reopt/test: Summarize.pl updated: 1.1 -> 1.2 --- Log message: Deal correctly with partial reports. Print "1 trace" instead of "1 traces". --- Diffs of the changes: (+19 -3) Index: reopt/test/Summarize.pl diff -u reopt/test/Summarize.pl:1.1 reopt/test/Summarize.pl:1.2 --- reopt/test/Summarize.pl:1.1 Wed Jul 21 16:02:57 2004 +++ reopt/test/Summarize.pl Wed Aug 4 00:28:03 2004 @@ -14,6 +14,14 @@ $test $traces $fail $extra . +sub pluralize { + my ($traces) = @_; + if ($traces > 1) { $traces = "$traces traces"; } + elsif ($traces == 1) { $traces = "$traces trace"; } + else { $traces = "no traces"; } + return $traces; +} + while (<>) { if (/Running Reoptimizer version of (\S+)/) { $test = $1; @@ -29,13 +37,21 @@ } elsif (/Finished running Reoptimizer tests for (\S+)/) { die "Wrong test?" unless $test eq $1; - if ($traces) { $traces = "$traces traces"; } - else { $traces = "no traces"; } + $traces = pluralize ($traces); write; + $test = ''; } - elsif (/(Segmentation Fault|Bus Error|Assertion failed|Terminated|Killed)/i) { + elsif (/(Segmentation Fault|Bus Error|Assertion failed|Terminated|Killed)/i) + { $extra = "$1"; } } +if ($test) { + $traces = pluralize ($traces); + $fail = ''; + $extra = ''; + write; +} + exit(0); From gaeke at cs.uiuc.edu Wed Aug 4 00:28:14 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 00:28:14 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/test/TTFTestHarness.pl Message-ID: <200408040528.AAA00923@seraph.cs.uiuc.edu> Changes in directory reopt/test: TTFTestHarness.pl updated: 1.1 -> 1.2 --- Log message: Look for ttftest in user's /home/vadve/gaeke/llvm_seraph/tools/Debug:/home/vadve/shared/localtools/sparc/bin:/home/vadve/gaeke/bin:/usr/dcs/software/supported/bin:/home/vadve/gaeke/programs/sun4u/bin:/usr/dcs/software/unsupported/bin:/usr/dcs/software/evaluation/bin:/usr/dcs/software/licensed/bin:/usr/local/bin:/usr/dcs/applications/purify/bin:/usr/dcs/applications/matlabr12/bin:/usr/dcs/applications/matlab5/bin:/usr/dcs/software/old/bin:/usr/dcs/applications/StarOffice/bin:/usr/bin:/sbin:/usr/sbin:/usr/ccs/bin:/usr/ccs/lib:/opt/SUNWspro/bin:/usr/dt/bin:/usr/openwin/bin:/usr/ucb:/etc:/usr/etc, in addition to the usual place. --- Diffs of the changes: (+9 -1) Index: reopt/test/TTFTestHarness.pl diff -u reopt/test/TTFTestHarness.pl:1.1 reopt/test/TTFTestHarness.pl:1.2 --- reopt/test/TTFTestHarness.pl:1.1 Fri Jul 9 01:14:32 2004 +++ reopt/test/TTFTestHarness.pl Wed Aug 4 00:28:04 2004 @@ -1,6 +1,14 @@ #!/usr/bin/perl -$TTFTEST = "../Debug/ttftest"; +print "looking for ttftest\n"; +if ( -x "../Debug/ttftest" ) { $TTFTEST = "../Debug/ttftest"; } +else { + print "looking in path dirs\n"; + foreach my $dir ( split ( /:/, $ENV{'PATH'} ) ) { + print "looking in $dir\n"; + if ( -x "$dir/ttftest" ) { $TTFTEST = "$dir/ttftest"; last; } + } +} die "can't find ttftest" unless -x $TTFTEST; sub assembleBytecode { From lattner at cs.uiuc.edu Wed Aug 4 01:06:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 01:06:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040606.BAA11765@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.75 -> 1.76 --- Log message: Concisify some code Do not call FindGlobalNamed when we know we will ignore the result (because we are not going to link a static symbol anyway). This speeds up gccld -disable-opt on 252.eon from 8.63s to 8.39s. --- Diffs of the changes: (+16 -24) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.75 llvm/lib/VMCore/Linker.cpp:1.76 --- llvm/lib/VMCore/Linker.cpp:1.75 Thu Jul 29 12:20:21 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 01:05:47 2004 @@ -382,32 +382,24 @@ // It doesn't exist exactly, scan through all of the type planes in the symbol // table, checking each of them for a type-compatible version. // - for (SymbolTable::plane_iterator PI = ST->plane_begin(), PE = ST->plane_end(); + for (SymbolTable::plane_iterator PI = ST->plane_begin(), PE = ST->plane_end(); PI != PE; ++PI) { - SymbolTable::ValueMap &VM = PI->second; - // Does this type plane contain an entry with the specified name? + SymbolTable::ValueMap &VM = PI->second; SymbolTable::value_iterator VI = VM.find(Name); - if (VI != VM.end()) { - // - // Ensure that this type if placed correctly into the symbol table. - // - assert(VI->second->getType() == PI->first && "Type conflict!"); - - // - // Save a reference to the new type. Resolving the type can modify the - // symbol table, invalidating the TI variable. - // - Value *ValPtr = VI->second; - - // - // Determine whether we can fold the two types together, resolving them. - // If so, we can use this value. - // - if (!RecursiveResolveTypes(Ty, PI->first, ST, "")) - return cast(ValPtr); - } + + if (VI != VM.end()) { + // Ensure that this type if placed correctly into the symbol table. + GlobalValue *ValPtr = cast(VI->second); + assert(ValPtr->getType() == PI->first && "Type conflict!"); + + // Determine whether we can fold the two types together, resolving them. + // If so, we can use this value. + if (!ValPtr->hasInternalLinkage() && + !RecursiveResolveTypes(Ty, PI->first, ST, "")) + return ValPtr; } + } return 0; // Otherwise, nothing could be found. } @@ -428,7 +420,7 @@ for (Module::const_giterator I = Src->gbegin(), E = Src->gend(); I != E; ++I){ const GlobalVariable *SGV = I; GlobalVariable *DGV = 0; - if (SGV->hasName()) { + if (SGV->hasName() && !SGV->hasInternalLinkage()) { // A same named thing is a global variable, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. @@ -613,7 +605,7 @@ for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction Function *DF = 0; - if (SF->hasName()) + if (SF->hasName() && !SF->hasInternalLinkage()) // The same named thing is a Function, because the only two things // that may be in a module level symbol table are Global Vars and // Functions, and they both have distinct, nonoverlapping, possible types. From lattner at cs.uiuc.edu Wed Aug 4 02:06:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 02:06:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040706.CAA12967@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.76 -> 1.77 --- Log message: Factor some code out, no substantial change. --- Diffs of the changes: (+26 -18) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.76 llvm/lib/VMCore/Linker.cpp:1.77 --- llvm/lib/VMCore/Linker.cpp:1.76 Wed Aug 4 01:05:47 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 02:05:54 2004 @@ -378,7 +378,7 @@ SymbolTable *ST) { // See if an exact match exists in the symbol table... if (Value *V = ST->lookup(Ty, Name)) return cast(V); - + // It doesn't exist exactly, scan through all of the type planes in the symbol // table, checking each of them for a type-compatible version. // @@ -403,6 +403,27 @@ return 0; // Otherwise, nothing could be found. } +/// ForceRenaming - The LLVM SymbolTable class autorenames globals that conflict +/// in the symbol table. This is good for all clients except for us. Go +/// through the trouble to force this back. +static void ForceRenaming(GlobalValue *GV, const std::string &Name) { + assert(GV->getName() != Name && "Can't force rename to self"); + SymbolTable &ST = GV->getParent()->getSymbolTable(); + + // If there is a conflict, rename the conflict. + Value *ConflictVal = ST.lookup(GV->getType(), Name); + assert(ConflictVal&&"Why do we have to force rename if there is no conflic?"); + GlobalValue *ConflictGV = cast(ConflictVal); + assert(ConflictGV->hasInternalLinkage() && + "Not conflicting with a static global, should link instead!"); + + ConflictGV->setName(""); // Eliminate the conflict + GV->setName(Name); // Force the name back + ConflictGV->setName(Name); // This will cause ConflictGV to get renamed + assert(GV->getName() == Name() && ConflictGV->getName() != Name && + "ForceRenaming didn't work"); +} + // LinkGlobals - Loop through the global variables in the src module and merge // them into the dest module. @@ -448,15 +469,8 @@ // If the LLVM runtime renamed the global, but it is an externally visible // symbol, DGV must be an existing global with internal linkage. Rename // it. - if (NewDGV->getName() != SGV->getName() && !NewDGV->hasInternalLinkage()){ - assert(DGV && DGV->getName() == SGV->getName() && - DGV->hasInternalLinkage()); - DGV->setName(""); - NewDGV->setName(SGV->getName()); // Force the name back - DGV->setName(SGV->getName()); // This will cause a renaming - assert(NewDGV->getName() == SGV->getName() && - DGV->getName() != SGV->getName()); - } + if (NewDGV->getName() != SGV->getName() && !NewDGV->hasInternalLinkage()) + ForceRenaming(NewDGV, SGV->getName()); // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, NewDGV)); @@ -622,14 +636,8 @@ // If the LLVM runtime renamed the function, but it is an externally // visible symbol, DF must be an existing function with internal linkage. // Rename it. - if (NewDF->getName() != SF->getName() && !NewDF->hasInternalLinkage()) { - assert(DF && DF->getName() == SF->getName() &&DF->hasInternalLinkage()); - DF->setName(""); - NewDF->setName(SF->getName()); // Force the name back - DF->setName(SF->getName()); // This will cause a renaming - assert(NewDF->getName() == SF->getName() && - DF->getName() != SF->getName()); - } + if (NewDF->getName() != SF->getName() && !NewDF->hasInternalLinkage()) + ForceRenaming(DF, SF->getName()); // ... and remember this mapping... ValueMap.insert(std::make_pair(SF, NewDF)); From lattner at cs.uiuc.edu Wed Aug 4 02:28:18 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 02:28:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040728.CAA13492@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.77 -> 1.78 --- Log message: I swear I compiled this, really I did. --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.77 llvm/lib/VMCore/Linker.cpp:1.78 --- llvm/lib/VMCore/Linker.cpp:1.77 Wed Aug 4 02:05:54 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 02:28:06 2004 @@ -420,7 +420,7 @@ ConflictGV->setName(""); // Eliminate the conflict GV->setName(Name); // Force the name back ConflictGV->setName(Name); // This will cause ConflictGV to get renamed - assert(GV->getName() == Name() && ConflictGV->getName() != Name && + assert(GV->getName() == Name && ConflictGV->getName() != Name && "ForceRenaming didn't work"); } From gaeke at cs.uiuc.edu Wed Aug 4 02:29:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp SparcV9BurgISel.h Makefile SparcV9InstrInfo.cpp SparcV9InstrSelection.cpp SparcV9InstrSelectionSupport.h Message-ID: <200408040729.CAA13620@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9BurgISel.cpp added (r1.1) SparcV9BurgISel.h added (r1.1) Makefile updated: 1.42 -> 1.43 SparcV9InstrInfo.cpp (r1.71) removed SparcV9InstrSelection.cpp (r1.145) removed SparcV9InstrSelectionSupport.h (r1.19) removed --- Log message: All the SparcV9 BURG instruction selector pieces have been collected into the new file SparcV9BurgISel.cpp, with exposed interfaces in SparcV9BurgISel.h. The InstrSelection directory is now dead. --- Diffs of the changes: (+4566 -1) Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp diff -c /dev/null llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.1 *** /dev/null Wed Aug 4 02:29:01 2004 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Wed Aug 4 02:28:51 2004 *************** *** 0 **** --- 1,4509 ---- + //===- SparcV9BurgISel.cpp - SparcV9 BURG-based Instruction Selector ------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // SparcV9 BURG-based instruction selector. It uses the SSA graph to + // construct a forest of BURG instruction trees (class InstrForest) and then + // uses the BURG-generated tree grammar (BURM) to find the optimal instruction + // sequences for the SparcV9. + // + //===----------------------------------------------------------------------===// + + #include "MachineInstrAnnot.h" + #include "SparcV9BurgISel.h" + #include "SparcV9InstrForest.h" + #include "SparcV9Internals.h" + #include "SparcV9TmpInstr.h" + #include "llvm/CodeGen/IntrinsicLowering.h" + #include "llvm/CodeGen/MachineConstantPool.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFunctionInfo.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/GlobalValue.h" + #include "llvm/Instructions.h" + #include "llvm/Intrinsics.h" + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Support/CFG.h" + #include "llvm/Target/TargetInstrInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Type.h" + #include "Config/alloca.h" + #include "Support/CommandLine.h" + #include "Support/LeakDetector.h" + #include "Support/MathExtras.h" + #include "Support/STLExtras.h" + #include "Support/hash_map" + #include + #include + #include + using namespace llvm; + + //==------------------------------------------------------------------------==// + // InstrForest (V9ISel BURG instruction trees) implementation + //==------------------------------------------------------------------------==// + + namespace llvm { + + class InstructionNode : public InstrTreeNode { + bool codeIsFoldedIntoParent; + + public: + InstructionNode(Instruction *_instr); + + Instruction *getInstruction() const { + assert(treeNodeType == NTInstructionNode); + return cast(val); + } + + void markFoldedIntoParent() { codeIsFoldedIntoParent = true; } + bool isFoldedIntoParent() { return codeIsFoldedIntoParent; } + + // Methods to support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const InstructionNode *N) { return true; } + static inline bool classof(const InstrTreeNode *N) { + return N->getNodeType() == InstrTreeNode::NTInstructionNode; + } + + protected: + virtual void dumpNode(int indent) const; + }; + + class VRegListNode : public InstrTreeNode { + public: + VRegListNode() : InstrTreeNode(NTVRegListNode, 0) { opLabel = VRegListOp; } + // Methods to support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const VRegListNode *N) { return true; } + static inline bool classof(const InstrTreeNode *N) { + return N->getNodeType() == InstrTreeNode::NTVRegListNode; + } + protected: + virtual void dumpNode(int indent) const; + }; + + class VRegNode : public InstrTreeNode { + public: + VRegNode(Value* _val) : InstrTreeNode(NTVRegNode, _val) { + opLabel = VRegNodeOp; + } + // Methods to support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const VRegNode *N) { return true; } + static inline bool classof(const InstrTreeNode *N) { + return N->getNodeType() == InstrTreeNode::NTVRegNode; + } + protected: + virtual void dumpNode(int indent) const; + }; + + class ConstantNode : public InstrTreeNode { + public: + ConstantNode(Constant *constVal) + : InstrTreeNode(NTConstNode, (Value*)constVal) { + opLabel = ConstantNodeOp; + } + Constant *getConstVal() const { return (Constant*) val;} + // Methods to support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ConstantNode *N) { return true; } + static inline bool classof(const InstrTreeNode *N) { + return N->getNodeType() == InstrTreeNode::NTConstNode; + } + protected: + virtual void dumpNode(int indent) const; + }; + + class LabelNode : public InstrTreeNode { + public: + LabelNode(BasicBlock* BB) : InstrTreeNode(NTLabelNode, (Value*)BB) { + opLabel = LabelNodeOp; + } + BasicBlock *getBasicBlock() const { return (BasicBlock*)val;} + // Methods to support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const LabelNode *N) { return true; } + static inline bool classof(const InstrTreeNode *N) { + return N->getNodeType() == InstrTreeNode::NTLabelNode; + } + protected: + virtual void dumpNode(int indent) const; + }; + + /// InstrForest - A forest of instruction trees for a single function. + /// The goal of InstrForest is to group instructions into a single + /// tree if one or more of them might be potentially combined into a + /// single complex instruction in the target machine. We group two + /// instructions O and I if: (1) Instruction O computes an operand used + /// by instruction I, and (2) O and I are part of the same basic block, + /// and (3) O has only a single use, viz., I. + /// + class InstrForest : private hash_map { + public: + // Use a vector for the root set to get a deterministic iterator + // for stable code generation. Even though we need to erase nodes + // during forest construction, a vector should still be efficient + // because the elements to erase are nearly always near the end. + typedef std::vector RootSet; + typedef RootSet:: iterator root_iterator; + typedef RootSet::const_iterator const_root_iterator; + + private: + RootSet treeRoots; + + public: + /*ctor*/ InstrForest (Function *F); + /*dtor*/ ~InstrForest (); + + /// getTreeNodeForInstr - Returns the tree node for an Instruction. + /// + inline InstructionNode *getTreeNodeForInstr(Instruction* instr) { + return (*this)[instr]; + } + + /// Iterators for the root nodes for all the trees. + /// + const_root_iterator roots_begin() const { return treeRoots.begin(); } + root_iterator roots_begin() { return treeRoots.begin(); } + const_root_iterator roots_end () const { return treeRoots.end(); } + root_iterator roots_end () { return treeRoots.end(); } + + void dump() const; + + private: + // Methods used to build the instruction forest. + void eraseRoot (InstructionNode* node); + void setLeftChild (InstrTreeNode* parent, InstrTreeNode* child); + void setRightChild(InstrTreeNode* parent, InstrTreeNode* child); + void setParent (InstrTreeNode* child, InstrTreeNode* parent); + void noteTreeNodeForInstr(Instruction* instr, InstructionNode* treeNode); + InstructionNode* buildTreeForInstruction(Instruction* instr); + }; + + void InstrTreeNode::dump(int dumpChildren, int indent) const { + dumpNode(indent); + + if (dumpChildren) { + if (LeftChild) + LeftChild->dump(dumpChildren, indent+1); + if (RightChild) + RightChild->dump(dumpChildren, indent+1); + } + } + + InstructionNode::InstructionNode(Instruction* I) + : InstrTreeNode(NTInstructionNode, I), codeIsFoldedIntoParent(false) { + opLabel = I->getOpcode(); + + // Distinguish special cases of some instructions such as Ret and Br + // + if (opLabel == Instruction::Ret && cast(I)->getReturnValue()) { + opLabel = RetValueOp; // ret(value) operation + } + else if (opLabel ==Instruction::Br && !cast(I)->isUnconditional()) + { + opLabel = BrCondOp; // br(cond) operation + } else if (opLabel >= Instruction::SetEQ && opLabel <= Instruction::SetGT) { + opLabel = SetCCOp; // common label for all SetCC ops + } else if (opLabel == Instruction::Alloca && I->getNumOperands() > 0) { + opLabel = AllocaN; // Alloca(ptr, N) operation + } else if (opLabel == Instruction::GetElementPtr && + cast(I)->hasIndices()) { + opLabel = opLabel + 100; // getElem with index vector + } else if (opLabel == Instruction::Xor && + BinaryOperator::isNot(I)) { + opLabel = (I->getType() == Type::BoolTy)? NotOp // boolean Not operator + : BNotOp; // bitwise Not operator + } else if (opLabel == Instruction::And || opLabel == Instruction::Or || + opLabel == Instruction::Xor) { + // Distinguish bitwise operators from logical operators! + if (I->getType() != Type::BoolTy) + opLabel = opLabel + 100; // bitwise operator + } else if (opLabel == Instruction::Cast) { + const Type *ITy = I->getType(); + switch(ITy->getTypeID()) + { + case Type::BoolTyID: opLabel = ToBoolTy; break; + case Type::UByteTyID: opLabel = ToUByteTy; break; + case Type::SByteTyID: opLabel = ToSByteTy; break; + case Type::UShortTyID: opLabel = ToUShortTy; break; + case Type::ShortTyID: opLabel = ToShortTy; break; + case Type::UIntTyID: opLabel = ToUIntTy; break; + case Type::IntTyID: opLabel = ToIntTy; break; + case Type::ULongTyID: opLabel = ToULongTy; break; + case Type::LongTyID: opLabel = ToLongTy; break; + case Type::FloatTyID: opLabel = ToFloatTy; break; + case Type::DoubleTyID: opLabel = ToDoubleTy; break; + case Type::ArrayTyID: opLabel = ToArrayTy; break; + case Type::PointerTyID: opLabel = ToPointerTy; break; + default: + // Just use `Cast' opcode otherwise. It's probably ignored. + break; + } + } + } + + void InstructionNode::dumpNode(int indent) const { + for (int i=0; i < indent; i++) + std::cerr << " "; + std::cerr << getInstruction()->getOpcodeName() + << " [label " << getOpLabel() << "]" << "\n"; + } + + void VRegListNode::dumpNode(int indent) const { + for (int i=0; i < indent; i++) + std::cerr << " "; + + std::cerr << "List" << "\n"; + } + + void VRegNode::dumpNode(int indent) const { + for (int i=0; i < indent; i++) + std::cerr << " "; + std::cerr << "VReg " << *getValue() << "\n"; + } + + void ConstantNode::dumpNode(int indent) const { + for (int i=0; i < indent; i++) + std::cerr << " "; + std::cerr << "Constant " << *getValue() << "\n"; + } + + void LabelNode::dumpNode(int indent) const { + for (int i=0; i < indent; i++) + std::cerr << " "; + + std::cerr << "Label " << *getValue() << "\n"; + } + + /// InstrForest ctor - Create a forest of instruction trees for a + /// single function. + /// + InstrForest::InstrForest(Function *F) { + for (Function::iterator BB = F->begin(), FE = F->end(); BB != FE; ++BB) { + for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + buildTreeForInstruction(I); + } + } + + InstrForest::~InstrForest() { + for_each(treeRoots.begin(), treeRoots.end(), deleter); + } + + void InstrForest::dump() const { + for (const_root_iterator I = roots_begin(); I != roots_end(); ++I) + (*I)->dump(/*dumpChildren*/ 1, /*indent*/ 0); + } + + inline void InstrForest::eraseRoot(InstructionNode* node) { + for (RootSet::reverse_iterator RI=treeRoots.rbegin(), RE=treeRoots.rend(); + RI != RE; ++RI) + if (*RI == node) + treeRoots.erase(RI.base()-1); + } + + inline void InstrForest::noteTreeNodeForInstr(Instruction *instr, + InstructionNode *treeNode) { + (*this)[instr] = treeNode; + treeRoots.push_back(treeNode); // mark node as root of a new tree + } + + inline void InstrForest::setLeftChild(InstrTreeNode *parent, + InstrTreeNode *child) { + parent->LeftChild = child; + child->Parent = parent; + if (InstructionNode* instrNode = dyn_cast(child)) + eraseRoot(instrNode); // no longer a tree root + } + + inline void InstrForest::setRightChild(InstrTreeNode *parent, + InstrTreeNode *child) { + parent->RightChild = child; + child->Parent = parent; + if (InstructionNode* instrNode = dyn_cast(child)) + eraseRoot(instrNode); // no longer a tree root + } + + InstructionNode* InstrForest::buildTreeForInstruction(Instruction *instr) { + InstructionNode *treeNode = getTreeNodeForInstr(instr); + if (treeNode) { + // treeNode has already been constructed for this instruction + assert(treeNode->getInstruction() == instr); + return treeNode; + } + + // Otherwise, create a new tree node for this instruction. + treeNode = new InstructionNode(instr); + noteTreeNodeForInstr(instr, treeNode); + + if (instr->getOpcode() == Instruction::Call) { + // Operands of call instruction + return treeNode; + } + + // If the instruction has more than 2 instruction operands, + // then we need to create artificial list nodes to hold them. + // (Note that we only count operands that get tree nodes, and not + // others such as branch labels for a branch or switch instruction.) + // To do this efficiently, we'll walk all operands, build treeNodes + // for all appropriate operands and save them in an array. We then + // insert children at the end, creating list nodes where needed. + // As a performance optimization, allocate a child array only + // if a fixed array is too small. + int numChildren = 0; + InstrTreeNode** childArray = new InstrTreeNode*[instr->getNumOperands()]; + + // Walk the operands of the instruction + for (Instruction::op_iterator O = instr->op_begin(); O!=instr->op_end(); + ++O) { + Value* operand = *O; + + // Check if the operand is a data value, not an branch label, type, + // method or module. If the operand is an address type (i.e., label + // or method) that is used in an non-branching operation, e.g., `add'. + // that should be considered a data value. + // Check latter condition here just to simplify the next IF. + bool includeAddressOperand = + (isa(operand) || isa(operand)) + && !instr->isTerminator(); + + if (includeAddressOperand || isa(operand) || + isa(operand) || isa(operand)) { + // This operand is a data value. + // An instruction that computes the incoming value is added as a + // child of the current instruction if: + // the value has only a single use + // AND both instructions are in the same basic block. + // AND the current instruction is not a PHI (because the incoming + // value is conceptually in a predecessor block, + // even though it may be in the same static block) + // (Note that if the value has only a single use (viz., `instr'), + // the def of the value can be safely moved just before instr + // and therefore it is safe to combine these two instructions.) + // In all other cases, the virtual register holding the value + // is used directly, i.e., made a child of the instruction node. + InstrTreeNode* opTreeNode; + if (isa(operand) && operand->hasOneUse() && + cast(operand)->getParent() == instr->getParent() && + instr->getOpcode() != Instruction::PHI && + instr->getOpcode() != Instruction::Call) { + // Recursively create a treeNode for it. + opTreeNode = buildTreeForInstruction((Instruction*)operand); + } else if (Constant *CPV = dyn_cast(operand)) { + if (isa(CPV)) + opTreeNode = new VRegNode(operand); + else + // Create a leaf node for a constant + opTreeNode = new ConstantNode(CPV); + } else { + // Create a leaf node for the virtual register + opTreeNode = new VRegNode(operand); + } + + childArray[numChildren++] = opTreeNode; + } + } + + // Add any selected operands as children in the tree. + // Certain instructions can have more than 2 in some instances (viz., + // a CALL or a memory access -- LOAD, STORE, and GetElemPtr -- to an + // array or struct). Make the operands of every such instruction into + // a right-leaning binary tree with the operand nodes at the leaves + // and VRegList nodes as internal nodes. + InstrTreeNode *parent = treeNode; + + if (numChildren > 2) { + unsigned instrOpcode = treeNode->getInstruction()->getOpcode(); + assert(instrOpcode == Instruction::PHI || + instrOpcode == Instruction::Call || + instrOpcode == Instruction::Load || + instrOpcode == Instruction::Store || + instrOpcode == Instruction::GetElementPtr); + } + + // Insert the first child as a direct child + if (numChildren >= 1) + setLeftChild(parent, childArray[0]); + + int n; + + // Create a list node for children 2 .. N-1, if any + for (n = numChildren-1; n >= 2; n--) { + // We have more than two children + InstrTreeNode *listNode = new VRegListNode(); + setRightChild(parent, listNode); + setLeftChild(listNode, childArray[numChildren - n]); + parent = listNode; + } + + // Now insert the last remaining child (if any). + if (numChildren >= 2) { + assert(n == 1); + setRightChild(parent, childArray[numChildren - 1]); + } + + delete [] childArray; + return treeNode; + } + //==------------------------------------------------------------------------==// + // V9ISel Command-line options and declarations + //==------------------------------------------------------------------------==// + + namespace { + /// Allow the user to select the amount of debugging information printed + /// out by V9ISel. + /// + enum SelectDebugLevel_t { + Select_NoDebugInfo, + Select_PrintMachineCode, + Select_DebugInstTrees, + Select_DebugBurgTrees, + }; + cl::opt + SelectDebugLevel("dselect", cl::Hidden, + cl::desc("enable instruction selection debug information"), + cl::values( + clEnumValN(Select_NoDebugInfo, "n", "disable debug output"), + clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"), + clEnumValN(Select_DebugInstTrees, "i", + "print debugging info for instruction selection"), + clEnumValN(Select_DebugBurgTrees, "b", "print burg trees"), + clEnumValEnd)); + + + /// V9ISel - This is the FunctionPass that drives the instruction selection + /// process on the SparcV9 target. + /// + class V9ISel : public FunctionPass { + TargetMachine &Target; + void InsertCodeForPhis(Function &F); + void InsertPhiElimInstructions(BasicBlock *BB, + const std::vector& CpVec); + void SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt); + void PostprocessMachineCodeForTree(InstructionNode* instrNode, + int ruleForNode, short* nts); + public: + V9ISel(TargetMachine &TM) : Target(TM) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + } + + bool runOnFunction(Function &F); + virtual const char *getPassName() const { + return "SparcV9 BURG Instruction Selector"; + } + }; + } + + + //==------------------------------------------------------------------------==// + // Various V9ISel helper functions + //==------------------------------------------------------------------------==// + + static const uint32_t MAXLO = (1 << 10) - 1; // set bits set by %lo(*) + static const uint32_t MAXSIMM = (1 << 12) - 1; // set bits in simm13 field of OR + + /// ConvertConstantToIntType - Function to get the value of an integral + /// constant in the form that must be put into the machine register. The + /// specified constant is interpreted as (i.e., converted if necessary to) the + /// specified destination type. The result is always returned as an uint64_t, + /// since the representation of int64_t and uint64_t are identical. The + /// argument can be any known const. isValidConstant is set to true if a valid + /// constant was found. + /// + uint64_t ConvertConstantToIntType(const TargetMachine &target, const Value *V, + const Type *destType, bool &isValidConstant) { + isValidConstant = false; + uint64_t C = 0; + + if (! destType->isIntegral() && ! isa(destType)) + return C; + + if (! isa(V) || isa(V)) + return C; + + // GlobalValue: no conversions needed: get value and return it + if (const GlobalValue* GV = dyn_cast(V)) { + isValidConstant = true; // may be overwritten by recursive call + return ConvertConstantToIntType(target, GV, destType, isValidConstant); + } + + // ConstantBool: no conversions needed: get value and return it + if (const ConstantBool *CB = dyn_cast(V)) { + isValidConstant = true; + return (uint64_t) CB->getValue(); + } + + // ConstantPointerNull: it's really just a big, shiny version of zero. + if (const ConstantPointerNull *CPN = dyn_cast(V)) { + isValidConstant = true; + return 0; + } + + // For other types of constants, some conversion may be needed. + // First, extract the constant operand according to its own type + if (const ConstantExpr *CE = dyn_cast(V)) + switch(CE->getOpcode()) { + case Instruction::Cast: // recursively get the value as cast + C = ConvertConstantToIntType(target, CE->getOperand(0), CE->getType(), + isValidConstant); + break; + default: // not simplifying other ConstantExprs + break; + } + else if (const ConstantInt *CI = dyn_cast(V)) { + isValidConstant = true; + C = CI->getRawValue(); + } else if (const ConstantFP *CFP = dyn_cast(V)) { + isValidConstant = true; + double fC = CFP->getValue(); + C = (destType->isSigned()? (uint64_t) (int64_t) fC + : (uint64_t) fC); + } + + // Now if a valid value was found, convert it to destType. + if (isValidConstant) { + unsigned opSize = target.getTargetData().getTypeSize(V->getType()); + unsigned destSize = target.getTargetData().getTypeSize(destType); + uint64_t maskHi = (destSize < 8)? (1U << 8*destSize) - 1 : ~0; + assert(opSize <= 8 && destSize <= 8 && ">8-byte int type unexpected"); + + if (destType->isSigned()) { + if (opSize > destSize) // operand is larger than dest: + C = C & maskHi; // mask high bits + + if (opSize > destSize || + (opSize == destSize && ! V->getType()->isSigned())) + if (C & (1U << (8*destSize - 1))) + C = C | ~maskHi; // sign-extend from destSize to 64 bits + } + else { + if (opSize > destSize || (V->getType()->isSigned() && destSize < 8)) { + // operand is larger than dest, + // OR both are equal but smaller than the full register size + // AND operand is signed, so it may have extra sign bits: + // mask high bits + C = C & maskHi; + } + } + } + + return C; + } + + /// CreateSETUWConst - Copy a 32-bit unsigned constant into the register + /// `dest', using SETHI, OR in the worst case. This function correctly emulates + /// the SETUW pseudo-op for SPARC v9 (if argument isSigned == false). The + /// isSigned=true case is used to implement SETSW without duplicating code. It + /// optimizes some common cases: + /// (1) Small value that fits in simm13 field of OR: don't need SETHI. + /// (2) isSigned = true and C is a small negative signed value, i.e., + /// high bits are 1, and the remaining bits fit in simm13(OR). + static inline void + CreateSETUWConst(const TargetMachine& target, uint32_t C, + Instruction* dest, std::vector& mvec, + bool isSigned = false) { + MachineInstr *miSETHI = NULL, *miOR = NULL; + + // In order to get efficient code, we should not generate the SETHI if + // all high bits are 1 (i.e., this is a small signed value that fits in + // the simm13 field of OR). So we check for and handle that case specially. + // NOTE: The value C = 0x80000000 is bad: sC < 0 *and* -sC < 0. + // In fact, sC == -sC, so we have to check for this explicitly. + int32_t sC = (int32_t) C; + bool smallNegValue =isSigned && sC < 0 && sC != -sC && -sC < (int32_t)MAXSIMM; + + // Set the high 22 bits in dest if non-zero and simm13 field of OR not enough + if (!smallNegValue && (C & ~MAXLO) && C > MAXSIMM) { + miSETHI = BuildMI(V9::SETHI, 2).addZImm(C).addRegDef(dest); + miSETHI->getOperand(0).markHi32(); + mvec.push_back(miSETHI); + } + + // Set the low 10 or 12 bits in dest. This is necessary if no SETHI + // was generated, or if the low 10 bits are non-zero. + if (miSETHI==NULL || C & MAXLO) { + if (miSETHI) { + // unsigned value with high-order bits set using SETHI + miOR = BuildMI(V9::ORi,3).addReg(dest).addZImm(C).addRegDef(dest); + miOR->getOperand(1).markLo32(); + } else { + // unsigned or small signed value that fits in simm13 field of OR + assert(smallNegValue || (C & ~MAXSIMM) == 0); + miOR = BuildMI(V9::ORi, 3).addMReg(target.getRegInfo()->getZeroRegNum()) + .addSImm(sC).addRegDef(dest); + } + mvec.push_back(miOR); + } + + assert((miSETHI || miOR) && "Oops, no code was generated!"); + } + + /// CreateSETSWConst - Set a 32-bit signed constant in the register `dest', + /// with sign-extension to 64 bits. This uses SETHI, OR, SRA in the worst case. + /// This function correctly emulates the SETSW pseudo-op for SPARC v9. It + /// optimizes the same cases as SETUWConst, plus: + /// (1) SRA is not needed for positive or small negative values. + /// + static inline void + CreateSETSWConst(const TargetMachine& target, int32_t C, + Instruction* dest, std::vector& mvec) { + // Set the low 32 bits of dest + CreateSETUWConst(target, (uint32_t) C, dest, mvec, /*isSigned*/true); + + // Sign-extend to the high 32 bits if needed. + // NOTE: The value C = 0x80000000 is bad: -C == C and so -C is < MAXSIMM + if (C < 0 && (C == -C || -C > (int32_t) MAXSIMM)) + mvec.push_back(BuildMI(V9::SRAi5,3).addReg(dest).addZImm(0).addRegDef(dest)); + } + + /// CreateSETXConst - Set a 64-bit signed or unsigned constant in the + /// register `dest'. Use SETUWConst for each 32 bit word, plus a + /// left-shift-by-32 in between. This function correctly emulates the SETX + /// pseudo-op for SPARC v9. It optimizes the same cases as SETUWConst for each + /// 32 bit word. + /// + static inline void + CreateSETXConst(const TargetMachine& target, uint64_t C, + Instruction* tmpReg, Instruction* dest, + std::vector& mvec) { + assert(C > (unsigned int) ~0 && "Use SETUW/SETSW for 32-bit values!"); + + MachineInstr* MI; + + // Code to set the upper 32 bits of the value in register `tmpReg' + CreateSETUWConst(target, (C >> 32), tmpReg, mvec); + + // Shift tmpReg left by 32 bits + mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32) + .addRegDef(tmpReg)); + + // Code to set the low 32 bits of the value in register `dest' + CreateSETUWConst(target, C, dest, mvec); + + // dest = OR(tmpReg, dest) + mvec.push_back(BuildMI(V9::ORr,3).addReg(dest).addReg(tmpReg).addRegDef(dest)); + } + + /// CreateSETUWLabel - Set a 32-bit constant (given by a symbolic label) in + /// the register `dest'. + /// + static inline void + CreateSETUWLabel(const TargetMachine& target, Value* val, + Instruction* dest, std::vector& mvec) { + MachineInstr* MI; + + // Set the high 22 bits in dest + MI = BuildMI(V9::SETHI, 2).addReg(val).addRegDef(dest); + MI->getOperand(0).markHi32(); + mvec.push_back(MI); + + // Set the low 10 bits in dest + MI = BuildMI(V9::ORr, 3).addReg(dest).addReg(val).addRegDef(dest); + MI->getOperand(1).markLo32(); + mvec.push_back(MI); + } + + /// CreateSETXLabel - Set a 64-bit constant (given by a symbolic label) in the + /// register `dest'. + /// + static inline void + CreateSETXLabel(const TargetMachine& target, Value* val, Instruction* tmpReg, + Instruction* dest, std::vector& mvec) { + assert(isa(val) && + "I only know about constant values and global addresses"); + + MachineInstr* MI; + + MI = BuildMI(V9::SETHI, 2).addPCDisp(val).addRegDef(tmpReg); + MI->getOperand(0).markHi64(); + mvec.push_back(MI); + + MI = BuildMI(V9::ORi, 3).addReg(tmpReg).addPCDisp(val).addRegDef(tmpReg); + MI->getOperand(1).markLo64(); + mvec.push_back(MI); + + mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32) + .addRegDef(tmpReg)); + MI = BuildMI(V9::SETHI, 2).addPCDisp(val).addRegDef(dest); + MI->getOperand(0).markHi32(); + mvec.push_back(MI); + + MI = BuildMI(V9::ORr, 3).addReg(dest).addReg(tmpReg).addRegDef(dest); + mvec.push_back(MI); + + MI = BuildMI(V9::ORi, 3).addReg(dest).addPCDisp(val).addRegDef(dest); + MI->getOperand(1).markLo32(); + mvec.push_back(MI); + } + + /// CreateUIntSetInstruction - Create code to Set an unsigned constant in the + /// register `dest'. Uses CreateSETUWConst, CreateSETSWConst or CreateSETXConst + /// as needed. CreateSETSWConst is an optimization for the case that the + /// unsigned value has all ones in the 33 high bits (so that sign-extension sets + /// them all). + /// + static inline void + CreateUIntSetInstruction(const TargetMachine& target, + uint64_t C, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + static const uint64_t lo32 = (uint32_t) ~0; + if (C <= lo32) // High 32 bits are 0. Set low 32 bits. + CreateSETUWConst(target, (uint32_t) C, dest, mvec); + else if ((C & ~lo32) == ~lo32 && (C & (1U << 31))) { + // All high 33 (not 32) bits are 1s: sign-extension will take care + // of high 32 bits, so use the sequence for signed int + CreateSETSWConst(target, (int32_t) C, dest, mvec); + } else if (C > lo32) { + // C does not fit in 32 bits + TmpInstruction* tmpReg = new TmpInstruction(mcfi, Type::IntTy); + CreateSETXConst(target, C, tmpReg, dest, mvec); + } + } + + /// CreateIntSetInstruction - Create code to Set a signed constant in the + /// register `dest'. Really the same as CreateUIntSetInstruction. + /// + static inline void + CreateIntSetInstruction(const TargetMachine& target, + int64_t C, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + CreateUIntSetInstruction(target, (uint64_t) C, dest, mvec, mcfi); + } + + /// MaxConstantsTableTy - Table mapping LLVM opcodes to the max. immediate + /// constant usable for that operation in the SparcV9 backend. Used by + /// ConstantMayNotFitInImmedField(). + /// + struct MaxConstantsTableTy { + // Entry == 0 ==> no immediate constant field exists at all. + // Entry > 0 ==> abs(immediate constant) <= Entry + std::vector tbl; + + int getMaxConstantForInstr (unsigned llvmOpCode); + MaxConstantsTableTy (); + unsigned size() const { return tbl.size (); } + int &operator[] (unsigned index) { return tbl[index]; } + }; + + int MaxConstantsTableTy::getMaxConstantForInstr(unsigned llvmOpCode) { + int modelOpCode = -1; + + if (llvmOpCode >= Instruction::BinaryOpsBegin && + llvmOpCode < Instruction::BinaryOpsEnd) + modelOpCode = V9::ADDi; + else + switch(llvmOpCode) { + case Instruction::Ret: modelOpCode = V9::JMPLCALLi; break; + + case Instruction::Malloc: + case Instruction::Alloca: + case Instruction::GetElementPtr: + case Instruction::PHI: + case Instruction::Cast: + case Instruction::Call: modelOpCode = V9::ADDi; break; + + case Instruction::Shl: + case Instruction::Shr: modelOpCode = V9::SLLXi6; break; + + default: break; + }; + + return (modelOpCode < 0)? 0: SparcV9MachineInstrDesc[modelOpCode].maxImmedConst; + } + + MaxConstantsTableTy::MaxConstantsTableTy () : tbl (Instruction::OtherOpsEnd) { + unsigned op; + assert(tbl.size() == Instruction::OtherOpsEnd && + "assignments below will be illegal!"); + for (op = Instruction::TermOpsBegin; op < Instruction::TermOpsEnd; ++op) + tbl[op] = getMaxConstantForInstr(op); + for (op = Instruction::BinaryOpsBegin; op < Instruction::BinaryOpsEnd; ++op) + tbl[op] = getMaxConstantForInstr(op); + for (op = Instruction::MemoryOpsBegin; op < Instruction::MemoryOpsEnd; ++op) + tbl[op] = getMaxConstantForInstr(op); + for (op = Instruction::OtherOpsBegin; op < Instruction::OtherOpsEnd; ++op) + tbl[op] = getMaxConstantForInstr(op); + } + + bool ConstantMayNotFitInImmedField(const Constant* CV, const Instruction* I) { + // The one and only MaxConstantsTable, used only by this function. + static MaxConstantsTableTy MaxConstantsTable; + + if (I->getOpcode() >= MaxConstantsTable.size()) // user-defined op (or bug!) + return true; + + if (isa(CV)) // can always use %g0 + return false; + + if (isa(I)) // Switch instructions will be lowered! + return false; + + if (const ConstantInt* CI = dyn_cast(CV)) + return labs((int64_t)CI->getRawValue()) > MaxConstantsTable[I->getOpcode()]; + + if (isa(CV)) + return 1 > MaxConstantsTable[I->getOpcode()]; + + return true; + } + + /// ChooseLoadInstruction - Return the appropriate load instruction opcode + /// based on the given LLVM value type. + /// + static inline MachineOpCode ChooseLoadInstruction(const Type *DestTy) { + switch (DestTy->getTypeID()) { + case Type::BoolTyID: + case Type::UByteTyID: return V9::LDUBr; + case Type::SByteTyID: return V9::LDSBr; + case Type::UShortTyID: return V9::LDUHr; + case Type::ShortTyID: return V9::LDSHr; + case Type::UIntTyID: return V9::LDUWr; + case Type::IntTyID: return V9::LDSWr; + case Type::PointerTyID: + case Type::ULongTyID: + case Type::LongTyID: return V9::LDXr; + case Type::FloatTyID: return V9::LDFr; + case Type::DoubleTyID: return V9::LDDFr; + default: assert(0 && "Invalid type for Load instruction"); + } + return 0; + } + + /// ChooseStoreInstruction - Return the appropriate store instruction opcode + /// based on the given LLVM value type. + /// + static inline MachineOpCode ChooseStoreInstruction(const Type *DestTy) { + switch (DestTy->getTypeID()) { + case Type::BoolTyID: + case Type::UByteTyID: + case Type::SByteTyID: return V9::STBr; + case Type::UShortTyID: + case Type::ShortTyID: return V9::STHr; + case Type::UIntTyID: + case Type::IntTyID: return V9::STWr; + case Type::PointerTyID: + case Type::ULongTyID: + case Type::LongTyID: return V9::STXr; + case Type::FloatTyID: return V9::STFr; + case Type::DoubleTyID: return V9::STDFr; + default: assert(0 && "Invalid type for Store instruction"); + } + return 0; + } + + static inline MachineOpCode ChooseAddInstructionByType(const Type* resultType) { + MachineOpCode opCode = V9::INVALID_OPCODE; + if (resultType->isIntegral() || isa(resultType) + || isa(resultType) || resultType == Type::LabelTy) { + opCode = V9::ADDr; + } else + switch(resultType->getTypeID()) { + case Type::FloatTyID: opCode = V9::FADDS; break; + case Type::DoubleTyID: opCode = V9::FADDD; break; + default: assert(0 && "Invalid type for ADD instruction"); break; + } + + return opCode; + } + + /// convertOpcodeFromRegToImm - Because the SparcV9 instruction selector likes + /// to re-write operands to instructions, making them change from a Value* + /// (virtual register) to a Constant* (making an immediate field), we need to + /// change the opcode from a register-based instruction to an immediate-based + /// instruction, hence this mapping. + /// + static unsigned convertOpcodeFromRegToImm(unsigned Opcode) { + switch (Opcode) { + /* arithmetic */ + case V9::ADDr: return V9::ADDi; + case V9::ADDccr: return V9::ADDcci; + case V9::ADDCr: return V9::ADDCi; + case V9::ADDCccr: return V9::ADDCcci; + case V9::SUBr: return V9::SUBi; + case V9::SUBccr: return V9::SUBcci; + case V9::SUBCr: return V9::SUBCi; + case V9::SUBCccr: return V9::SUBCcci; + case V9::MULXr: return V9::MULXi; + case V9::SDIVXr: return V9::SDIVXi; + case V9::UDIVXr: return V9::UDIVXi; + + /* logical */ + case V9::ANDr: return V9::ANDi; + case V9::ANDccr: return V9::ANDcci; + case V9::ANDNr: return V9::ANDNi; + case V9::ANDNccr: return V9::ANDNcci; + case V9::ORr: return V9::ORi; + case V9::ORccr: return V9::ORcci; + case V9::ORNr: return V9::ORNi; + case V9::ORNccr: return V9::ORNcci; + case V9::XORr: return V9::XORi; + case V9::XORccr: return V9::XORcci; + case V9::XNORr: return V9::XNORi; + case V9::XNORccr: return V9::XNORcci; + + /* shift */ + case V9::SLLr5: return V9::SLLi5; + case V9::SRLr5: return V9::SRLi5; + case V9::SRAr5: return V9::SRAi5; + case V9::SLLXr6: return V9::SLLXi6; + case V9::SRLXr6: return V9::SRLXi6; + case V9::SRAXr6: return V9::SRAXi6; + + /* Conditional move on int comparison with zero */ + case V9::MOVRZr: return V9::MOVRZi; + case V9::MOVRLEZr: return V9::MOVRLEZi; + case V9::MOVRLZr: return V9::MOVRLZi; + case V9::MOVRNZr: return V9::MOVRNZi; + case V9::MOVRGZr: return V9::MOVRGZi; + case V9::MOVRGEZr: return V9::MOVRGEZi; + + + /* Conditional move on int condition code */ + case V9::MOVAr: return V9::MOVAi; + case V9::MOVNr: return V9::MOVNi; + case V9::MOVNEr: return V9::MOVNEi; + case V9::MOVEr: return V9::MOVEi; + case V9::MOVGr: return V9::MOVGi; + case V9::MOVLEr: return V9::MOVLEi; + case V9::MOVGEr: return V9::MOVGEi; + case V9::MOVLr: return V9::MOVLi; + case V9::MOVGUr: return V9::MOVGUi; + case V9::MOVLEUr: return V9::MOVLEUi; + case V9::MOVCCr: return V9::MOVCCi; + case V9::MOVCSr: return V9::MOVCSi; + case V9::MOVPOSr: return V9::MOVPOSi; + case V9::MOVNEGr: return V9::MOVNEGi; + case V9::MOVVCr: return V9::MOVVCi; + case V9::MOVVSr: return V9::MOVVSi; + + /* Conditional move of int reg on fp condition code */ + case V9::MOVFAr: return V9::MOVFAi; + case V9::MOVFNr: return V9::MOVFNi; + case V9::MOVFUr: return V9::MOVFUi; + case V9::MOVFGr: return V9::MOVFGi; + case V9::MOVFUGr: return V9::MOVFUGi; + case V9::MOVFLr: return V9::MOVFLi; + case V9::MOVFULr: return V9::MOVFULi; + case V9::MOVFLGr: return V9::MOVFLGi; + case V9::MOVFNEr: return V9::MOVFNEi; + case V9::MOVFEr: return V9::MOVFEi; + case V9::MOVFUEr: return V9::MOVFUEi; + case V9::MOVFGEr: return V9::MOVFGEi; + case V9::MOVFUGEr: return V9::MOVFUGEi; + case V9::MOVFLEr: return V9::MOVFLEi; + case V9::MOVFULEr: return V9::MOVFULEi; + case V9::MOVFOr: return V9::MOVFOi; + + /* load */ + case V9::LDSBr: return V9::LDSBi; + case V9::LDSHr: return V9::LDSHi; + case V9::LDSWr: return V9::LDSWi; + case V9::LDUBr: return V9::LDUBi; + case V9::LDUHr: return V9::LDUHi; + case V9::LDUWr: return V9::LDUWi; + case V9::LDXr: return V9::LDXi; + case V9::LDFr: return V9::LDFi; + case V9::LDDFr: return V9::LDDFi; + case V9::LDQFr: return V9::LDQFi; + case V9::LDFSRr: return V9::LDFSRi; + case V9::LDXFSRr: return V9::LDXFSRi; + + /* store */ + case V9::STBr: return V9::STBi; + case V9::STHr: return V9::STHi; + case V9::STWr: return V9::STWi; + case V9::STXr: return V9::STXi; + case V9::STFr: return V9::STFi; + case V9::STDFr: return V9::STDFi; + case V9::STFSRr: return V9::STFSRi; + case V9::STXFSRr: return V9::STXFSRi; + + /* jump & return */ + case V9::JMPLCALLr: return V9::JMPLCALLi; + case V9::JMPLRETr: return V9::JMPLRETi; + + /* save and restore */ + case V9::SAVEr: return V9::SAVEi; + case V9::RESTOREr: return V9::RESTOREi; + + default: + // It's already in correct format + // Or, it's just not handled yet, but an assert() would break LLC + #if 0 + std::cerr << "Unhandled opcode in convertOpcodeFromRegToImm(): " << Opcode + << "\n"; + #endif + return Opcode; + } + } + + /// CreateCodeToLoadConst - Create an instruction sequence to put the + /// constant `val' into the virtual register `dest'. `val' may be a Constant or + /// a GlobalValue, viz., the constant address of a global variable or function. + /// The generated instructions are returned in `mvec'. Any temp. registers + /// (TmpInstruction) created are recorded in mcfi. Any stack space required is + /// allocated via MachineFunction. + /// + void CreateCodeToLoadConst(const TargetMachine& target, Function* F, + Value* val, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + assert(isa(val) && + "I only know about constant values and global addresses"); + + // Use a "set" instruction for known constants or symbolic constants (labels) + // that can go in an integer reg. + // We have to use a "load" instruction for all other constants, + // in particular, floating point constants. + const Type* valType = val->getType(); + + if (isa(val)) { + TmpInstruction* tmpReg = + new TmpInstruction(mcfi, PointerType::get(val->getType()), val); + CreateSETXLabel(target, val, tmpReg, dest, mvec); + return; + } + + bool isValid; + uint64_t C = ConvertConstantToIntType(target, val, dest->getType(), isValid); + if (isValid) { + if (dest->getType()->isSigned()) + CreateUIntSetInstruction(target, C, dest, mvec, mcfi); + else + CreateIntSetInstruction(target, (int64_t) C, dest, mvec, mcfi); + + } else { + // Make an instruction sequence to load the constant, viz: + // SETX , tmpReg, addrReg + // LOAD /*addr*/ addrReg, /*offset*/ 0, dest + // First, create a tmp register to be used by the SETX sequence. + TmpInstruction* tmpReg = + new TmpInstruction(mcfi, PointerType::get(val->getType())); + + // Create another TmpInstruction for the address register + TmpInstruction* addrReg = + new TmpInstruction(mcfi, PointerType::get(val->getType())); + + // Get the constant pool index for this constant + MachineConstantPool *CP = MachineFunction::get(F).getConstantPool(); + Constant *C = cast(val); + unsigned CPI = CP->getConstantPoolIndex(C); + + // Put the address of the constant into a register + MachineInstr* MI; + + MI = BuildMI(V9::SETHI, 2).addConstantPoolIndex(CPI).addRegDef(tmpReg); + MI->getOperand(0).markHi64(); + mvec.push_back(MI); + + MI = BuildMI(V9::ORi, 3).addReg(tmpReg).addConstantPoolIndex(CPI) + .addRegDef(tmpReg); + MI->getOperand(1).markLo64(); + mvec.push_back(MI); + + mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32) + .addRegDef(tmpReg)); + MI = BuildMI(V9::SETHI, 2).addConstantPoolIndex(CPI).addRegDef(addrReg); + MI->getOperand(0).markHi32(); + mvec.push_back(MI); + + MI = BuildMI(V9::ORr, 3).addReg(addrReg).addReg(tmpReg).addRegDef(addrReg); + mvec.push_back(MI); + + MI = BuildMI(V9::ORi, 3).addReg(addrReg).addConstantPoolIndex(CPI) + .addRegDef(addrReg); + MI->getOperand(1).markLo32(); + mvec.push_back(MI); + + // Now load the constant from out ConstantPool label + unsigned Opcode = ChooseLoadInstruction(val->getType()); + Opcode = convertOpcodeFromRegToImm(Opcode); + mvec.push_back(BuildMI(Opcode, 3) + .addReg(addrReg).addSImm((int64_t)0).addRegDef(dest)); + } + } + + /// CreateCodeToCopyFloatToInt - Similarly, create an instruction sequence + /// to copy an FP register `val' to an integer register `dest' by copying to + /// memory and back. The generated instructions are returned in `mvec'. Any + /// temp. virtual registers (TmpInstruction) created are recorded in mcfi. + /// Temporary stack space required is allocated via MachineFunction. + /// + void CreateCodeToCopyFloatToInt(const TargetMachine& target, Function* F, + Value* val, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + const Type* opTy = val->getType(); + const Type* destTy = dest->getType(); + assert(opTy->isFloatingPoint() && "Source type must be float/double"); + assert((destTy->isIntegral() || isa(destTy)) + && "Dest type must be integer, bool or pointer"); + + // FIXME: For now, we allocate permanent space because the stack frame + // manager does not allow locals to be allocated (e.g., for alloca) after + // a temp is allocated! + int offset = MachineFunction::get(F).getInfo()->allocateLocalVar(val); + + unsigned FPReg = target.getRegInfo()->getFramePointer(); + + // Store instruction stores `val' to [%fp+offset]. + // The store opCode is based only the source value being copied. + unsigned StoreOpcode = ChooseStoreInstruction(opTy); + StoreOpcode = convertOpcodeFromRegToImm(StoreOpcode); + mvec.push_back(BuildMI(StoreOpcode, 3) + .addReg(val).addMReg(FPReg).addSImm(offset)); + + // Load instruction loads [%fp+offset] to `dest'. + // The type of the load opCode is the integer type that matches the + // source type in size: + // On SparcV9: int for float, long for double. + // Note that we *must* use signed loads even for unsigned dest types, to + // ensure correct sign-extension for UByte, UShort or UInt: + const Type* loadTy = (opTy == Type::FloatTy)? Type::IntTy : Type::LongTy; + unsigned LoadOpcode = ChooseLoadInstruction(loadTy); + LoadOpcode = convertOpcodeFromRegToImm(LoadOpcode); + mvec.push_back(BuildMI(LoadOpcode, 3).addMReg(FPReg) + .addSImm(offset).addRegDef(dest)); + } + + /// CreateBitExtensionInstructions - Helper function for sign-extension and + /// zero-extension. For SPARC v9, we sign-extend the given operand using SLL; + /// SRA/SRL. + /// + inline void + CreateBitExtensionInstructions(bool signExtend, const TargetMachine& target, + Function* F, Value* srcVal, Value* destVal, + unsigned int numLowBits, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + MachineInstr* M; + + assert(numLowBits <= 32 && "Otherwise, nothing should be done here!"); + + if (numLowBits < 32) { + // SLL is needed since operand size is < 32 bits. + TmpInstruction *tmpI = new TmpInstruction(mcfi, destVal->getType(), + srcVal, destVal, "make32"); + mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(srcVal) + .addZImm(32-numLowBits).addRegDef(tmpI)); + srcVal = tmpI; + } + + mvec.push_back(BuildMI(signExtend? V9::SRAi5 : V9::SRLi5, 3) + .addReg(srcVal).addZImm(32-numLowBits).addRegDef(destVal)); + } + + /// CreateSignExtensionInstructions - Create instruction sequence to produce + /// a sign-extended register value from an arbitrary-sized integer value (sized + /// in bits, not bytes). The generated instructions are returned in `mvec'. Any + /// temp. registers (TmpInstruction) created are recorded in mcfi. Any stack + /// space required is allocated via MachineFunction. + /// + void CreateSignExtensionInstructions(const TargetMachine& target, + Function* F, Value* srcVal, Value* destVal, + unsigned int numLowBits, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + CreateBitExtensionInstructions(/*signExtend*/ true, target, F, srcVal, + destVal, numLowBits, mvec, mcfi); + } + + /// CreateZeroExtensionInstructions - Create instruction sequence to produce + /// a zero-extended register value from an arbitrary-sized integer value (sized + /// in bits, not bytes). For SPARC v9, we sign-extend the given operand using + /// SLL; SRL. The generated instructions are returned in `mvec'. Any temp. + /// registers (TmpInstruction) created are recorded in mcfi. Any stack space + /// required is allocated via MachineFunction. + /// + void CreateZeroExtensionInstructions(const TargetMachine& target, + Function* F, Value* srcVal, Value* destVal, + unsigned int numLowBits, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + CreateBitExtensionInstructions(/*signExtend*/ false, target, F, srcVal, + destVal, numLowBits, mvec, mcfi); + } + + /// CreateCodeToCopyIntToFloat - Create an instruction sequence to copy an + /// integer register `val' to a floating point register `dest' by copying to + /// memory and back. val must be an integral type. dest must be a Float or + /// Double. The generated instructions are returned in `mvec'. Any temp. + /// registers (TmpInstruction) created are recorded in mcfi. Any stack space + /// required is allocated via MachineFunction. + /// + void CreateCodeToCopyIntToFloat(const TargetMachine& target, + Function* F, Value* val, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + assert((val->getType()->isIntegral() || isa(val->getType())) + && "Source type must be integral (integer or bool) or pointer"); + assert(dest->getType()->isFloatingPoint() + && "Dest type must be float/double"); + + // Get a stack slot to use for the copy + int offset = MachineFunction::get(F).getInfo()->allocateLocalVar(val); + + // Get the size of the source value being copied. + size_t srcSize = target.getTargetData().getTypeSize(val->getType()); + + // Store instruction stores `val' to [%fp+offset]. + // The store and load opCodes are based on the size of the source value. + // If the value is smaller than 32 bits, we must sign- or zero-extend it + // to 32 bits since the load-float will load 32 bits. + // Note that the store instruction is the same for signed and unsigned ints. + const Type* storeType = (srcSize <= 4)? Type::IntTy : Type::LongTy; + Value* storeVal = val; + if (srcSize < target.getTargetData().getTypeSize(Type::FloatTy)) { + // sign- or zero-extend respectively + storeVal = new TmpInstruction(mcfi, storeType, val); + if (val->getType()->isSigned()) + CreateSignExtensionInstructions(target, F, val, storeVal, 8*srcSize, + mvec, mcfi); + else + CreateZeroExtensionInstructions(target, F, val, storeVal, 8*srcSize, + mvec, mcfi); + } + + unsigned FPReg = target.getRegInfo()->getFramePointer(); + unsigned StoreOpcode = ChooseStoreInstruction(storeType); + StoreOpcode = convertOpcodeFromRegToImm(StoreOpcode); + mvec.push_back(BuildMI(StoreOpcode, 3) + .addReg(storeVal).addMReg(FPReg).addSImm(offset)); + + // Load instruction loads [%fp+offset] to `dest'. + // The type of the load opCode is the floating point type that matches the + // stored type in size: + // On SparcV9: float for int or smaller, double for long. + const Type* loadType = (srcSize <= 4)? Type::FloatTy : Type::DoubleTy; + unsigned LoadOpcode = ChooseLoadInstruction(loadType); + LoadOpcode = convertOpcodeFromRegToImm(LoadOpcode); + mvec.push_back(BuildMI(LoadOpcode, 3) + .addMReg(FPReg).addSImm(offset).addRegDef(dest)); + } + + /// InsertCodeToLoadConstant - Generates code to load the constant + /// into a TmpInstruction (virtual reg) and returns the virtual register. + /// + static TmpInstruction* + InsertCodeToLoadConstant(Function *F, Value* opValue, Instruction* vmInstr, + std::vector& loadConstVec, + TargetMachine& target) { + // Create a tmp virtual register to hold the constant. + MachineCodeForInstruction &mcfi = MachineCodeForInstruction::get(vmInstr); + TmpInstruction* tmpReg = new TmpInstruction(mcfi, opValue); + + CreateCodeToLoadConst(target, F, opValue, tmpReg, loadConstVec, mcfi); + + // Record the mapping from the tmp VM instruction to machine instruction. + // Do this for all machine instructions that were not mapped to any + // other temp values created by + // tmpReg->addMachineInstruction(loadConstVec.back()); + return tmpReg; + } + + MachineOperand::MachineOperandType + ChooseRegOrImmed(int64_t intValue, bool isSigned, + MachineOpCode opCode, const TargetMachine& target, + bool canUseImmed, unsigned int& getMachineRegNum, + int64_t& getImmedValue) { + MachineOperand::MachineOperandType opType=MachineOperand::MO_VirtualRegister; + getMachineRegNum = 0; + getImmedValue = 0; + + if (canUseImmed && + target.getInstrInfo()->constantFitsInImmedField(opCode, intValue)) { + opType = isSigned? MachineOperand::MO_SignExtendedImmed + : MachineOperand::MO_UnextendedImmed; + getImmedValue = intValue; + } else if (intValue == 0 && + target.getRegInfo()->getZeroRegNum() != (unsigned)-1) { + opType = MachineOperand::MO_MachineRegister; + getMachineRegNum = target.getRegInfo()->getZeroRegNum(); + } + + return opType; + } + + MachineOperand::MachineOperandType + ChooseRegOrImmed(Value* val, + MachineOpCode opCode, const TargetMachine& target, + bool canUseImmed, unsigned int& getMachineRegNum, + int64_t& getImmedValue) { + getMachineRegNum = 0; + getImmedValue = 0; + + // To use reg or immed, constant needs to be integer, bool, or a NULL pointer. + // ConvertConstantToIntType() does the right conversions. + bool isValidConstant; + uint64_t valueToUse = + ConvertConstantToIntType(target, val, val->getType(), isValidConstant); + if (! isValidConstant) + return MachineOperand::MO_VirtualRegister; + + // Now check if the constant value fits in the IMMED field. + return ChooseRegOrImmed((int64_t) valueToUse, val->getType()->isSigned(), + opCode, target, canUseImmed, + getMachineRegNum, getImmedValue); + } + + /// CreateCopyInstructionsByType - Create instruction(s) to copy src to dest, + /// for arbitrary types. The generated instructions are returned in `mvec'. Any + /// temp. registers (TmpInstruction) created are recorded in mcfi. Any stack + /// space required is allocated via MachineFunction. + /// + void CreateCopyInstructionsByType(const TargetMachine& target, + Function *F, Value* src, Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + bool loadConstantToReg = false; + const Type* resultType = dest->getType(); + MachineOpCode opCode = ChooseAddInstructionByType(resultType); + assert (opCode != V9::INVALID_OPCODE + && "Unsupported result type in CreateCopyInstructionsByType()"); + + // If `src' is a constant that doesn't fit in the immed field or if it is + // a global variable (i.e., a constant address), generate a load + // instruction instead of an add. + if (isa(src)) + loadConstantToReg = true; + else if (isa(src)) { + unsigned int machineRegNum; + int64_t immedValue; + MachineOperand::MachineOperandType opType = + ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true, + machineRegNum, immedValue); + + if (opType == MachineOperand::MO_VirtualRegister) + loadConstantToReg = true; + } + + if (loadConstantToReg) { + // `src' is constant and cannot fit in immed field for the ADD. + // Insert instructions to "load" the constant into a register. + CreateCodeToLoadConst(target, F, src, dest, mvec, mcfi); + } else { + // Create a reg-to-reg copy instruction for the given type: + // -- For FP values, create a FMOVS or FMOVD instruction + // -- For non-FP values, create an add-with-0 instruction (opCode as above) + // Make `src' the second operand, in case it is a small constant! + MachineInstr* MI; + if (resultType->isFloatingPoint()) + MI = (BuildMI(resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD, 2) + .addReg(src).addRegDef(dest)); + else { + const Type* Ty =isa(resultType)? Type::ULongTy :resultType; + MI = (BuildMI(opCode, 3) + .addSImm((int64_t) 0).addReg(src).addRegDef(dest)); + } + mvec.push_back(MI); + } + } + + /// FixConstantOperandsForInstr - Make a machine instruction use its constant + /// operands more efficiently. If the constant is 0, then use the hardwired 0 + /// register, if any. Else, if the constant fits in the IMMEDIATE field, then + /// use that field. Otherwise, else create instructions to put the constant + /// into a register, either directly or by loading explicitly from the constant + /// pool. In the first 2 cases, the operand of `minstr' is modified in place. + /// Returns a vector of machine instructions generated for operands that fall + /// under case 3; these must be inserted before `minstr'. + /// + std::vector + FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr, + TargetMachine& target) { + std::vector MVec; + + MachineOpCode opCode = minstr->getOpcode(); + const TargetInstrInfo& instrInfo = *target.getInstrInfo(); + int resultPos = instrInfo.getResultPos(opCode); + int immedPos = instrInfo.getImmedConstantPos(opCode); + + Function *F = vmInstr->getParent()->getParent(); + + for (unsigned op=0; op < minstr->getNumOperands(); op++) { + const MachineOperand& mop = minstr->getOperand(op); + + // Skip the result position, preallocated machine registers, or operands + // that cannot be constants (CC regs or PC-relative displacements) + if (resultPos == (int)op || + mop.getType() == MachineOperand::MO_MachineRegister || + mop.getType() == MachineOperand::MO_CCRegister || + mop.getType() == MachineOperand::MO_PCRelativeDisp) + continue; + + bool constantThatMustBeLoaded = false; + unsigned int machineRegNum = 0; + int64_t immedValue = 0; + Value* opValue = NULL; + MachineOperand::MachineOperandType opType = + MachineOperand::MO_VirtualRegister; + + // Operand may be a virtual register or a compile-time constant + if (mop.getType() == MachineOperand::MO_VirtualRegister) { + assert(mop.getVRegValue() != NULL); + opValue = mop.getVRegValue(); + if (Constant *opConst = dyn_cast(opValue)) + if (!isa(opConst)) { + opType = ChooseRegOrImmed(opConst, opCode, target, + (immedPos == (int)op), machineRegNum, + immedValue); + if (opType == MachineOperand::MO_VirtualRegister) + constantThatMustBeLoaded = true; + } + } else { + // If the operand is from the constant pool, don't try to change it. + if (mop.getType() == MachineOperand::MO_ConstantPoolIndex) { + continue; + } + assert(mop.isImmediate()); + bool isSigned = mop.getType() == MachineOperand::MO_SignExtendedImmed; + + // Bit-selection flags indicate an instruction that is extracting + // bits from its operand so ignore this even if it is a big constant. + if (mop.isHiBits32() || mop.isLoBits32() || + mop.isHiBits64() || mop.isLoBits64()) + continue; + + opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned, + opCode, target, (immedPos == (int)op), + machineRegNum, immedValue); + + if (opType == MachineOperand::MO_SignExtendedImmed || + opType == MachineOperand::MO_UnextendedImmed) { + // The optype is an immediate value + // This means we need to change the opcode, e.g. ADDr -> ADDi + unsigned newOpcode = convertOpcodeFromRegToImm(opCode); + minstr->setOpcode(newOpcode); + } + + if (opType == mop.getType()) + continue; // no change: this is the most common case + + if (opType == MachineOperand::MO_VirtualRegister) { + constantThatMustBeLoaded = true; + opValue = isSigned + ? (Value*)ConstantSInt::get(Type::LongTy, immedValue) + : (Value*)ConstantUInt::get(Type::ULongTy,(uint64_t)immedValue); + } + } + + if (opType == MachineOperand::MO_MachineRegister) + minstr->SetMachineOperandReg(op, machineRegNum); + else if (opType == MachineOperand::MO_SignExtendedImmed || + opType == MachineOperand::MO_UnextendedImmed) { + minstr->SetMachineOperandConst(op, opType, immedValue); + // The optype is or has become an immediate + // This means we need to change the opcode, e.g. ADDr -> ADDi + unsigned newOpcode = convertOpcodeFromRegToImm(opCode); + minstr->setOpcode(newOpcode); + } else if (constantThatMustBeLoaded || + (opValue && isa(opValue))) + { // opValue is a constant that must be explicitly loaded into a reg + assert(opValue); + TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr, + MVec, target); + minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister, + tmpReg); + } + } + + // Also, check for implicit operands used by the machine instruction + // (no need to check those defined since they cannot be constants). + // These include: + // -- arguments to a Call + // -- return value of a Return + // Any such operand that is a constant value needs to be fixed also. + // The current instructions with implicit refs (viz., Call and Return) + // have no immediate fields, so the constant always needs to be loaded + // into a register. + bool isCall = instrInfo.isCall(opCode); + unsigned lastCallArgNum = 0; // unused if not a call + CallArgsDescriptor* argDesc = NULL; // unused if not a call + if (isCall) + argDesc = CallArgsDescriptor::get(minstr); + + for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i) + if (isa(minstr->getImplicitRef(i))) { + Value* oldVal = minstr->getImplicitRef(i); + TmpInstruction* tmpReg = + InsertCodeToLoadConstant(F, oldVal, vmInstr, MVec, target); + minstr->setImplicitRef(i, tmpReg); + + if (isCall) { + // find and replace the argument in the CallArgsDescriptor + unsigned i=lastCallArgNum; + while (argDesc->getArgInfo(i).getArgVal() != oldVal) + ++i; + assert(i < argDesc->getNumArgs() && + "Constant operands to a call *must* be in the arg list"); + lastCallArgNum = i; + argDesc->getArgInfo(i).replaceArgVal(tmpReg); + } + } + + return MVec; + } + + static inline void Add3OperandInstr(unsigned Opcode, InstructionNode* Node, + std::vector& mvec) { + mvec.push_back(BuildMI(Opcode, 3).addReg(Node->leftChild()->getValue()) + .addReg(Node->rightChild()->getValue()) + .addRegDef(Node->getValue())); + } + + /// IsZero - Check for a constant 0. + /// + static inline bool IsZero(Value* idx) { + return (idx == ConstantSInt::getNullValue(idx->getType())); + } + + /// FoldGetElemChain - Fold a chain of GetElementPtr instructions containing + /// only constant offsets into an equivalent (Pointer, IndexVector) pair. + /// Returns the pointer Value, and stores the resulting IndexVector in argument + /// chainIdxVec. This is a helper function for FoldConstantIndices that does the + /// actual folding. + // + static Value* + FoldGetElemChain(InstrTreeNode* ptrNode, std::vector& chainIdxVec, + bool lastInstHasLeadingNonZero) { + InstructionNode* gepNode = dyn_cast(ptrNode); + GetElementPtrInst* gepInst = + dyn_cast_or_null(gepNode ? gepNode->getInstruction() :0); + + // ptr value is not computed in this tree or ptr value does not come from GEP + // instruction + if (gepInst == NULL) + return NULL; + + // Return NULL if we don't fold any instructions in. + Value* ptrVal = NULL; + + // Now chase the chain of getElementInstr instructions, if any. + // Check for any non-constant indices and stop there. + // Also, stop if the first index of child is a non-zero array index + // and the last index of the current node is a non-array index: + // in that case, a non-array declared type is being accessed as an array + // which is not type-safe, but could be legal. + InstructionNode* ptrChild = gepNode; + while (ptrChild && (ptrChild->getOpLabel() == Instruction::GetElementPtr || + ptrChild->getOpLabel() == GetElemPtrIdx)) { + // Child is a GetElemPtr instruction + gepInst = cast(ptrChild->getValue()); + User::op_iterator OI, firstIdx = gepInst->idx_begin(); + User::op_iterator lastIdx = gepInst->idx_end(); + bool allConstantOffsets = true; + + // The first index of every GEP must be an array index. + assert((*firstIdx)->getType() == Type::LongTy && + "INTERNAL ERROR: Structure index for a pointer type!"); + + // If the last instruction had a leading non-zero index, check if the + // current one references a sequential (i.e., indexable) type. + // If not, the code is not type-safe and we would create an illegal GEP + // by folding them, so don't fold any more instructions. + if (lastInstHasLeadingNonZero) + if (! isa(gepInst->getType()->getElementType())) + break; // cannot fold in any preceding getElementPtr instrs. + + // Check that all offsets are constant for this instruction + for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI) + allConstantOffsets = isa(*OI); + + if (allConstantOffsets) { + // Get pointer value out of ptrChild. + ptrVal = gepInst->getPointerOperand(); + + // Insert its index vector at the start, skipping any leading [0] + // Remember the old size to check if anything was inserted. + unsigned oldSize = chainIdxVec.size(); + int firstIsZero = IsZero(*firstIdx); + chainIdxVec.insert(chainIdxVec.begin(), firstIdx + firstIsZero, lastIdx); + + // Remember if it has leading zero index: it will be discarded later. + if (oldSize < chainIdxVec.size()) + lastInstHasLeadingNonZero = !firstIsZero; + + // Mark the folded node so no code is generated for it. + ((InstructionNode*) ptrChild)->markFoldedIntoParent(); + + // Get the previous GEP instruction and continue trying to fold + ptrChild = dyn_cast(ptrChild->leftChild()); + } else // cannot fold this getElementPtr instr. or any preceding ones + break; + } + + // If the first getElementPtr instruction had a leading [0], add it back. + // Note that this instruction is the *last* one that was successfully + // folded *and* contributed any indices, in the loop above. + if (ptrVal && ! lastInstHasLeadingNonZero) + chainIdxVec.insert(chainIdxVec.begin(), ConstantSInt::get(Type::LongTy,0)); + + return ptrVal; + } + + /// GetGEPInstArgs - Helper function for GetMemInstArgs that handles the + /// final getElementPtr instruction used by (or same as) the memory operation. + /// Extracts the indices of the current instruction and tries to fold in + /// preceding ones if all indices of the current one are constant. + /// + static Value *GetGEPInstArgs(InstructionNode *gepNode, + std::vector &idxVec, + bool &allConstantIndices) { + allConstantIndices = true; + GetElementPtrInst* gepI = cast(gepNode->getInstruction()); + + // Default pointer is the one from the current instruction. + Value* ptrVal = gepI->getPointerOperand(); + InstrTreeNode* ptrChild = gepNode->leftChild(); + + // Extract the index vector of the GEP instruction. + // If all indices are constant and first index is zero, try to fold + // in preceding GEPs with all constant indices. + for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); + allConstantIndices && OI != OE; ++OI) + if (! isa(*OI)) + allConstantIndices = false; // note: this also terminates loop! + + // If we have only constant indices, fold chains of constant indices + // in this and any preceding GetElemPtr instructions. + bool foldedGEPs = false; + bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); + if (allConstantIndices) + if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) { + ptrVal = newPtr; + foldedGEPs = true; + } + + // Append the index vector of the current instruction. + // Skip the leading [0] index if preceding GEPs were folded into this. + idxVec.insert(idxVec.end(), + gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), + gepI->idx_end()); + + return ptrVal; + } + + /// GetMemInstArgs - Get the pointer value and the index vector for a memory + /// operation (GetElementPtr, Load, or Store). If all indices of the given + /// memory operation are constant, fold in constant indices in a chain of + /// preceding GetElementPtr instructions (if any), and return the pointer value + /// of the first instruction in the chain. All folded instructions are marked so + /// no code is generated for them. Returns the pointer Value to use, and + /// returns the resulting IndexVector in idxVec. Sets allConstantIndices + /// to true/false if all indices are/aren't const. + /// + static Value *GetMemInstArgs(InstructionNode *memInstrNode, + std::vector &idxVec, + bool& allConstantIndices) { + allConstantIndices = false; + Instruction* memInst = memInstrNode->getInstruction(); + assert(idxVec.size() == 0 && "Need empty vector to return indices"); + + // If there is a GetElemPtr instruction to fold in to this instr, + // it must be in the left child for Load and GetElemPtr, and in the + // right child for Store instructions. + InstrTreeNode* ptrChild = (memInst->getOpcode() == Instruction::Store + ? memInstrNode->rightChild() + : memInstrNode->leftChild()); + + // Default pointer is the one from the current instruction. + Value* ptrVal = ptrChild->getValue(); + + // Find the "last" GetElemPtr instruction: this one or the immediate child. + // There will be none if this is a load or a store from a scalar pointer. + InstructionNode* gepNode = NULL; + if (isa(memInst)) + gepNode = memInstrNode; + else if (isa(ptrChild) && isa(ptrVal)) { + // Child of load/store is a GEP and memInst is its only use. + // Use its indices and mark it as folded. + gepNode = cast(ptrChild); + gepNode->markFoldedIntoParent(); + } + + // If there are no indices, return the current pointer. + // Else extract the pointer from the GEP and fold the indices. + return gepNode ? GetGEPInstArgs(gepNode, idxVec, allConstantIndices) + : ptrVal; + } + + static inline MachineOpCode + ChooseBprInstruction(const InstructionNode* instrNode) { + MachineOpCode opCode; + + Instruction* setCCInstr = + ((InstructionNode*) instrNode->leftChild())->getInstruction(); + + switch(setCCInstr->getOpcode()) { + case Instruction::SetEQ: opCode = V9::BRZ; break; + case Instruction::SetNE: opCode = V9::BRNZ; break; + case Instruction::SetLE: opCode = V9::BRLEZ; break; + case Instruction::SetGE: opCode = V9::BRGEZ; break; + case Instruction::SetLT: opCode = V9::BRLZ; break; + case Instruction::SetGT: opCode = V9::BRGZ; break; + default: + assert(0 && "Unrecognized VM instruction!"); + opCode = V9::INVALID_OPCODE; + break; + } + + return opCode; + } + + static inline MachineOpCode + ChooseBpccInstruction(const InstructionNode* instrNode, + const BinaryOperator* setCCInstr) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned(); + + if (isSigned) { + switch(setCCInstr->getOpcode()) { + case Instruction::SetEQ: opCode = V9::BE; break; + case Instruction::SetNE: opCode = V9::BNE; break; + case Instruction::SetLE: opCode = V9::BLE; break; + case Instruction::SetGE: opCode = V9::BGE; break; + case Instruction::SetLT: opCode = V9::BL; break; + case Instruction::SetGT: opCode = V9::BG; break; + default: + assert(0 && "Unrecognized VM instruction!"); + break; + } + } else { + switch(setCCInstr->getOpcode()) { + case Instruction::SetEQ: opCode = V9::BE; break; + case Instruction::SetNE: opCode = V9::BNE; break; + case Instruction::SetLE: opCode = V9::BLEU; break; + case Instruction::SetGE: opCode = V9::BCC; break; + case Instruction::SetLT: opCode = V9::BCS; break; + case Instruction::SetGT: opCode = V9::BGU; break; + default: + assert(0 && "Unrecognized VM instruction!"); + break; + } + } + + return opCode; + } + + static inline MachineOpCode + ChooseBFpccInstruction(const InstructionNode* instrNode, + const BinaryOperator* setCCInstr) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + switch(setCCInstr->getOpcode()) { + case Instruction::SetEQ: opCode = V9::FBE; break; + case Instruction::SetNE: opCode = V9::FBNE; break; + case Instruction::SetLE: opCode = V9::FBLE; break; + case Instruction::SetGE: opCode = V9::FBGE; break; + case Instruction::SetLT: opCode = V9::FBL; break; + case Instruction::SetGT: opCode = V9::FBG; break; + default: + assert(0 && "Unrecognized VM instruction!"); + break; + } + + return opCode; + } + + // GetTmpForCC - Create a unique TmpInstruction for a boolean value, + // representing the CC register used by a branch on that value. + // For now, hack this using a little static cache of TmpInstructions. + // Eventually the entire BURG instruction selection should be put + // into a separate class that can hold such information. + // The static cache is not too bad because the memory for these + // TmpInstructions will be freed along with the rest of the Function anyway. + // + static TmpInstruction *GetTmpForCC (Value* boolVal, const Function *F, + const Type* ccType, + MachineCodeForInstruction& mcfi) { + typedef hash_map BoolTmpCache; + static BoolTmpCache boolToTmpCache; // Map boolVal -> TmpInstruction* + static const Function *lastFunction = 0;// Use to flush cache between funcs + + assert(boolVal->getType() == Type::BoolTy && "Weird but ok! Delete assert"); + + if (lastFunction != F) { + lastFunction = F; + boolToTmpCache.clear(); + } + + // Look for tmpI and create a new one otherwise. The new value is + // directly written to map using the ref returned by operator[]. + TmpInstruction*& tmpI = boolToTmpCache[boolVal]; + if (tmpI == NULL) + tmpI = new TmpInstruction(mcfi, ccType, boolVal); + + return tmpI; + } + + static inline MachineOpCode + ChooseBccInstruction(const InstructionNode* instrNode, const Type*& setCCType) { + InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild(); + assert(setCCNode->getOpLabel() == SetCCOp); + BinaryOperator* setCCInstr =cast(setCCNode->getInstruction()); + setCCType = setCCInstr->getOperand(0)->getType(); + + if (setCCType->isFloatingPoint()) + return ChooseBFpccInstruction(instrNode, setCCInstr); + else + return ChooseBpccInstruction(instrNode, setCCInstr); + } + + /// ChooseMovFpcciInstruction - WARNING: since this function has only one + /// caller, it always returns the opcode that expects an immediate and a + /// register. If this function is ever used in cases where an opcode that takes + /// two registers is required, then modify this function and use + /// convertOpcodeFromRegToImm() where required. It will be necessary to expand + /// convertOpcodeFromRegToImm() to handle the new cases of opcodes. + /// + static inline MachineOpCode + ChooseMovFpcciInstruction(const InstructionNode* instrNode) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + switch(instrNode->getInstruction()->getOpcode()) { + case Instruction::SetEQ: opCode = V9::MOVFEi; break; + case Instruction::SetNE: opCode = V9::MOVFNEi; break; + case Instruction::SetLE: opCode = V9::MOVFLEi; break; + case Instruction::SetGE: opCode = V9::MOVFGEi; break; + case Instruction::SetLT: opCode = V9::MOVFLi; break; + case Instruction::SetGT: opCode = V9::MOVFGi; break; + default: + assert(0 && "Unrecognized VM instruction!"); + break; + } + + return opCode; + } + + /// ChooseMovpcciForSetCC -- Choose a conditional-move instruction + /// based on the type of SetCC operation. + /// + /// WARNING: like the previous function, this function always returns + /// the opcode that expects an immediate and a register. See above. + /// + static MachineOpCode ChooseMovpcciForSetCC(const InstructionNode* instrNode) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + const Type* opType = instrNode->leftChild()->getValue()->getType(); + assert(opType->isIntegral() || isa(opType)); + bool noSign = opType->isUnsigned() || isa(opType); + + switch(instrNode->getInstruction()->getOpcode()) { + case Instruction::SetEQ: opCode = V9::MOVEi; break; + case Instruction::SetLE: opCode = noSign? V9::MOVLEUi : V9::MOVLEi; break; + case Instruction::SetGE: opCode = noSign? V9::MOVCCi : V9::MOVGEi; break; + case Instruction::SetLT: opCode = noSign? V9::MOVCSi : V9::MOVLi; break; + case Instruction::SetGT: opCode = noSign? V9::MOVGUi : V9::MOVGi; break; + case Instruction::SetNE: opCode = V9::MOVNEi; break; + default: assert(0 && "Unrecognized LLVM instr!"); break; + } + + return opCode; + } + + /// ChooseMovpregiForSetCC -- Choose a conditional-move-on-register-value + /// instruction based on the type of SetCC operation. These instructions + /// compare a register with 0 and perform the move is the comparison is true. + /// + /// WARNING: like the previous function, this function it always returns + /// the opcode that expects an immediate and a register. See above. + /// + static MachineOpCode ChooseMovpregiForSetCC(const InstructionNode* instrNode) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + switch(instrNode->getInstruction()->getOpcode()) { + case Instruction::SetEQ: opCode = V9::MOVRZi; break; + case Instruction::SetLE: opCode = V9::MOVRLEZi; break; + case Instruction::SetGE: opCode = V9::MOVRGEZi; break; + case Instruction::SetLT: opCode = V9::MOVRLZi; break; + case Instruction::SetGT: opCode = V9::MOVRGZi; break; + case Instruction::SetNE: opCode = V9::MOVRNZi; break; + default: assert(0 && "Unrecognized VM instr!"); break; + } + + return opCode; + } + + static inline MachineOpCode + ChooseConvertToFloatInstr(const TargetMachine& target, + OpLabel vopCode, const Type* opType) { + assert((vopCode == ToFloatTy || vopCode == ToDoubleTy) && + "Unrecognized convert-to-float opcode!"); + assert((opType->isIntegral() || opType->isFloatingPoint() || + isa(opType)) + && "Trying to convert a non-scalar type to FLOAT/DOUBLE?"); + + MachineOpCode opCode = V9::INVALID_OPCODE; + + unsigned opSize = target.getTargetData().getTypeSize(opType); + + if (opType == Type::FloatTy) + opCode = (vopCode == ToFloatTy? V9::NOP : V9::FSTOD); + else if (opType == Type::DoubleTy) + opCode = (vopCode == ToFloatTy? V9::FDTOS : V9::NOP); + else if (opSize <= 4) + opCode = (vopCode == ToFloatTy? V9::FITOS : V9::FITOD); + else { + assert(opSize == 8 && "Unrecognized type size > 4 and < 8!"); + opCode = (vopCode == ToFloatTy? V9::FXTOS : V9::FXTOD); + } + + return opCode; + } + + static inline MachineOpCode + ChooseConvertFPToIntInstr(const TargetMachine& target, + const Type* destType, const Type* opType) { + assert((opType == Type::FloatTy || opType == Type::DoubleTy) + && "This function should only be called for FLOAT or DOUBLE"); + assert((destType->isIntegral() || isa(destType)) + && "Trying to convert FLOAT/DOUBLE to a non-scalar type?"); + + MachineOpCode opCode = V9::INVALID_OPCODE; + + unsigned destSize = target.getTargetData().getTypeSize(destType); + + if (destType == Type::UIntTy) + assert(destType != Type::UIntTy && "Expand FP-to-uint beforehand."); + else if (destSize <= 4) + opCode = (opType == Type::FloatTy)? V9::FSTOI : V9::FDTOI; + else { + assert(destSize == 8 && "Unrecognized type size > 4 and < 8!"); + opCode = (opType == Type::FloatTy)? V9::FSTOX : V9::FDTOX; + } + + return opCode; + } + + static MachineInstr* + CreateConvertFPToIntInstr(const TargetMachine& target, Value* srcVal, + Value* destVal, const Type* destType) { + MachineOpCode opCode = ChooseConvertFPToIntInstr(target, destType, + srcVal->getType()); + assert(opCode != V9::INVALID_OPCODE && "Expected to need conversion!"); + return BuildMI(opCode, 2).addReg(srcVal).addRegDef(destVal); + } + + /// CreateCodeToConvertFloatToInt: Convert FP value to signed or unsigned + /// integer. The FP value must be converted to the dest type in an FP register, + /// and the result is then copied from FP to int register via memory. SPARC + /// does not have a float-to-uint conversion, only a float-to-int (fdtoi). + /// Since fdtoi converts to signed integers, any FP value V between MAXINT+1 and + /// MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly. + /// Therefore, for converting an FP value to uint32_t, we first need to convert + /// to uint64_t and then to uint32_t. + /// + static void + CreateCodeToConvertFloatToInt(const TargetMachine& target, + Value* opVal, Instruction* destI, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + Function* F = destI->getParent()->getParent(); + + // Create a temporary to represent the FP register into which the + // int value will placed after conversion. The type of this temporary + // depends on the type of FP register to use: single-prec for a 32-bit + // int or smaller; double-prec for a 64-bit int. + size_t destSize = target.getTargetData().getTypeSize(destI->getType()); + + const Type* castDestType = destI->getType(); // type for the cast instr result + const Type* castDestRegType; // type for cast instruction result reg + TmpInstruction* destForCast; // dest for cast instruction + Instruction* fpToIntCopyDest = destI; // dest for fp-reg-to-int-reg copy instr + + // For converting an FP value to uint32_t, we first need to convert to + // uint64_t and then to uint32_t, as explained above. + if (destI->getType() == Type::UIntTy) { + castDestType = Type::ULongTy; // use this instead of type of destI + castDestRegType = Type::DoubleTy; // uint64_t needs 64-bit FP register. + destForCast = new TmpInstruction(mcfi, castDestRegType, opVal); + fpToIntCopyDest = new TmpInstruction(mcfi, castDestType, destForCast); + } else { + castDestRegType = (destSize > 4)? Type::DoubleTy : Type::FloatTy; + destForCast = new TmpInstruction(mcfi, castDestRegType, opVal); + } + + // Create the fp-to-int conversion instruction (src and dest regs are FP regs) + mvec.push_back(CreateConvertFPToIntInstr(target, opVal, destForCast, + castDestType)); + + // Create the fpreg-to-intreg copy code + CreateCodeToCopyFloatToInt(target, F, destForCast, fpToIntCopyDest, mvec, + mcfi); + + // Create the uint64_t to uint32_t conversion, if needed + if (destI->getType() == Type::UIntTy) + CreateZeroExtensionInstructions(target, F, fpToIntCopyDest, destI, + /*numLowBits*/ 32, mvec, mcfi); + } + + static inline MachineOpCode + ChooseAddInstruction(const InstructionNode* instrNode) { + return ChooseAddInstructionByType(instrNode->getInstruction()->getType()); + } + + static inline MachineInstr* + CreateMovFloatInstruction(const InstructionNode* instrNode, + const Type* resultType) { + return BuildMI((resultType == Type::FloatTy) ? V9::FMOVS : V9::FMOVD, 2) + .addReg(instrNode->leftChild()->getValue()) + .addRegDef(instrNode->getValue()); + } + + static inline MachineInstr* + CreateAddConstInstruction(const InstructionNode* instrNode) { + MachineInstr* minstr = NULL; + + Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); + assert(isa(constOp)); + + // Cases worth optimizing are: + // (1) Add with 0 for float or double: use an FMOV of appropriate type, + // instead of an FADD (1 vs 3 cycles). There is no integer MOV. + if (ConstantFP *FPC = dyn_cast(constOp)) { + double dval = FPC->getValue(); + if (dval == 0.0) + minstr = CreateMovFloatInstruction(instrNode, + instrNode->getInstruction()->getType()); + } + + return minstr; + } + + static inline MachineOpCode ChooseSubInstructionByType(const Type* resultType) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + if (resultType->isInteger() || isa(resultType)) { + opCode = V9::SUBr; + } else { + switch(resultType->getTypeID()) { + case Type::FloatTyID: opCode = V9::FSUBS; break; + case Type::DoubleTyID: opCode = V9::FSUBD; break; + default: assert(0 && "Invalid type for SUB instruction"); break; + } + } + + return opCode; + } + + static inline MachineInstr* + CreateSubConstInstruction(const InstructionNode* instrNode) { + MachineInstr* minstr = NULL; + + Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); + assert(isa(constOp)); + + // Cases worth optimizing are: + // (1) Sub with 0 for float or double: use an FMOV of appropriate type, + // instead of an FSUB (1 vs 3 cycles). There is no integer MOV. + if (ConstantFP *FPC = dyn_cast(constOp)) { + double dval = FPC->getValue(); + if (dval == 0.0) + minstr = CreateMovFloatInstruction(instrNode, + instrNode->getInstruction()->getType()); + } + + return minstr; + } + + static inline MachineOpCode + ChooseFcmpInstruction(const InstructionNode* instrNode) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue(); + switch(operand->getType()->getTypeID()) { + case Type::FloatTyID: opCode = V9::FCMPS; break; + case Type::DoubleTyID: opCode = V9::FCMPD; break; + default: assert(0 && "Invalid type for FCMP instruction"); break; + } + + return opCode; + } + + /// BothFloatToDouble - Assumes that leftArg and rightArg of instrNode are both + /// cast instructions. Returns true if both are floats cast to double. + /// + static inline bool BothFloatToDouble(const InstructionNode* instrNode) { + InstrTreeNode* leftArg = instrNode->leftChild(); + InstrTreeNode* rightArg = instrNode->rightChild(); + InstrTreeNode* leftArgArg = leftArg->leftChild(); + InstrTreeNode* rightArgArg = rightArg->leftChild(); + assert(leftArg->getValue()->getType() == rightArg->getValue()->getType()); + return (leftArg->getValue()->getType() == Type::DoubleTy && + leftArgArg->getValue()->getType() == Type::FloatTy && + rightArgArg->getValue()->getType() == Type::FloatTy); + } + + static inline MachineOpCode ChooseMulInstructionByType(const Type* resultType) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + if (resultType->isInteger()) + opCode = V9::MULXr; + else + switch(resultType->getTypeID()) { + case Type::FloatTyID: opCode = V9::FMULS; break; + case Type::DoubleTyID: opCode = V9::FMULD; break; + default: assert(0 && "Invalid type for MUL instruction"); break; + } + + return opCode; + } + + static inline MachineInstr* + CreateIntNegInstruction(const TargetMachine& target, Value* vreg) { + return BuildMI(V9::SUBr, 3).addMReg(target.getRegInfo()->getZeroRegNum()) + .addReg(vreg).addRegDef(vreg); + } + + /// CreateShiftInstructions - Create instruction sequence for any shift + /// operation. SLL or SLLX on an operand smaller than the integer reg. size + /// (64bits) requires a second instruction for explicit sign-extension. Note + /// that we only have to worry about a sign-bit appearing in the most + /// significant bit of the operand after shifting (e.g., bit 32 of Int or bit 16 + /// of Short), so we do not have to worry about results that are as large as a + /// normal integer register. + /// + static inline void + CreateShiftInstructions(const TargetMachine& target, Function* F, + MachineOpCode shiftOpCode, Value* argVal1, + Value* optArgVal2, /* Use optArgVal2 if not NULL */ + unsigned optShiftNum, /* else use optShiftNum */ + Instruction* destVal, std::vector& mvec, + MachineCodeForInstruction& mcfi) { + assert((optArgVal2 != NULL || optShiftNum <= 64) && + "Large shift sizes unexpected, but can be handled below: " + "You need to check whether or not it fits in immed field below"); + + // If this is a logical left shift of a type smaller than the standard + // integer reg. size, we have to extend the sign-bit into upper bits + // of dest, so we need to put the result of the SLL into a temporary. + Value* shiftDest = destVal; + unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType()); + + if ((shiftOpCode == V9::SLLr5 || shiftOpCode == V9::SLLXr6) && opSize < 8) { + // put SLL result into a temporary + shiftDest = new TmpInstruction(mcfi, argVal1, optArgVal2, "sllTmp"); + } + + MachineInstr* M = (optArgVal2 != NULL) + ? BuildMI(shiftOpCode, 3).addReg(argVal1).addReg(optArgVal2) + .addReg(shiftDest, MachineOperand::Def) + : BuildMI(shiftOpCode, 3).addReg(argVal1).addZImm(optShiftNum) + .addReg(shiftDest, MachineOperand::Def); + mvec.push_back(M); + + if (shiftDest != destVal) { + // extend the sign-bit of the result into all upper bits of dest + assert(8*opSize <= 32 && "Unexpected type size > 4 and < IntRegSize?"); + CreateSignExtensionInstructions(target, F, shiftDest, destVal, 8*opSize, + mvec, mcfi); + } + } + + /// CreateMulConstInstruction - Does not create any instructions if we + /// cannot exploit constant to create a cheaper instruction. This returns the + /// approximate cost of the instructions generated, which is used to pick the + /// cheapest when both operands are constant. + /// + static unsigned + CreateMulConstInstruction(const TargetMachine &target, Function* F, + Value* lval, Value* rval, Instruction* destVal, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + // Use max. multiply cost, viz., cost of MULX + unsigned cost = target.getInstrInfo()->minLatency(V9::MULXr); + unsigned firstNewInstr = mvec.size(); + + Value* constOp = rval; + if (! isa(constOp)) + return cost; + + // Cases worth optimizing are: + // (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV) + // (2) Multiply by 2^x for integer types: replace with Shift + const Type* resultType = destVal->getType(); + + if (resultType->isInteger() || isa(resultType)) { + bool isValidConst; + int64_t C = (int64_t) ConvertConstantToIntType(target, constOp, + constOp->getType(), + isValidConst); + if (isValidConst) { + unsigned pow; + bool needNeg = false; + if (C < 0) { + needNeg = true; + C = -C; + } + + if (C == 0 || C == 1) { + cost = target.getInstrInfo()->minLatency(V9::ADDr); + unsigned Zero = target.getRegInfo()->getZeroRegNum(); + MachineInstr* M; + if (C == 0) + M =BuildMI(V9::ADDr,3).addMReg(Zero).addMReg(Zero).addRegDef(destVal); + else + M = BuildMI(V9::ADDr,3).addReg(lval).addMReg(Zero).addRegDef(destVal); + mvec.push_back(M); + } else if (isPowerOf2(C, pow)) { + unsigned opSize = target.getTargetData().getTypeSize(resultType); + MachineOpCode opCode = (opSize <= 32)? V9::SLLr5 : V9::SLLXr6; + CreateShiftInstructions(target, F, opCode, lval, NULL, pow, + destVal, mvec, mcfi); + } + + if (mvec.size() > 0 && needNeg) { + // insert after the instr to flip the sign + MachineInstr* M = CreateIntNegInstruction(target, destVal); + mvec.push_back(M); + } + } + } else { + if (ConstantFP *FPC = dyn_cast(constOp)) { + double dval = FPC->getValue(); + if (fabs(dval) == 1) { + MachineOpCode opCode = (dval < 0) + ? (resultType == Type::FloatTy? V9::FNEGS : V9::FNEGD) + : (resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD); + mvec.push_back(BuildMI(opCode,2).addReg(lval).addRegDef(destVal)); + } + } + } + + if (firstNewInstr < mvec.size()) { + cost = 0; + for (unsigned i=firstNewInstr; i < mvec.size(); ++i) + cost += target.getInstrInfo()->minLatency(mvec[i]->getOpcode()); + } + + return cost; + } + + /// CreateCheapestMulConstInstruction - Does not create any instructions + /// if we cannot exploit constant to create a cheaper instruction. + /// + static inline void + CreateCheapestMulConstInstruction(const TargetMachine &target, Function* F, + Value* lval, Value* rval, + Instruction* destVal, + std::vector& mvec, + MachineCodeForInstruction& mcfi) { + Value* constOp; + if (isa(lval) && isa(rval)) { + // both operands are constant: evaluate and "set" in dest + Constant* P = ConstantExpr::get(Instruction::Mul, + cast(lval), + cast(rval)); + CreateCodeToLoadConst (target, F, P, destVal, mvec, mcfi); + } + else if (isa(rval)) // rval is constant, but not lval + CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi); + else if (isa(lval)) // lval is constant, but not rval + CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi); + + // else neither is constant + return; + } + + /// CreateMulInstruction - Returns NULL if we cannot exploit constant + /// to create a cheaper instruction. + /// + static inline void + CreateMulInstruction(const TargetMachine &target, Function* F, + Value* lval, Value* rval, Instruction* destVal, + std::vector& mvec, + MachineCodeForInstruction& mcfi, + MachineOpCode forceMulOp = -1) { + unsigned L = mvec.size(); + CreateCheapestMulConstInstruction(target,F, lval, rval, destVal, mvec, mcfi); + if (mvec.size() == L) { + // no instructions were added so create MUL reg, reg, reg. + // Use FSMULD if both operands are actually floats cast to doubles. + // Otherwise, use the default opcode for the appropriate type. + MachineOpCode mulOp = ((forceMulOp != -1) + ? forceMulOp + : ChooseMulInstructionByType(destVal->getType())); + mvec.push_back(BuildMI(mulOp, 3).addReg(lval).addReg(rval) + .addRegDef(destVal)); + } + } + + /// ChooseDivInstruction - Generate a divide instruction for Div or Rem. + /// For Rem, this assumes that the operand type will be signed if the result + /// type is signed. This is correct because they must have the same sign. + /// + static inline MachineOpCode + ChooseDivInstruction(TargetMachine &target, const InstructionNode* instrNode) { + MachineOpCode opCode = V9::INVALID_OPCODE; + + const Type* resultType = instrNode->getInstruction()->getType(); + + if (resultType->isInteger()) + opCode = resultType->isSigned()? V9::SDIVXr : V9::UDIVXr; + else + switch(resultType->getTypeID()) { + case Type::FloatTyID: opCode = V9::FDIVS; break; + case Type::DoubleTyID: opCode = V9::FDIVD; break; + default: assert(0 && "Invalid type for DIV instruction"); break; + } + + return opCode; + } + + /// CreateDivConstInstruction - Return if we cannot exploit constant to create + /// a cheaper instruction. + /// + static void CreateDivConstInstruction(TargetMachine &target, + const InstructionNode* instrNode, + std::vector& mvec) { + Value* LHS = instrNode->leftChild()->getValue(); + Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue(); + if (!isa(constOp)) + return; + + Instruction* destVal = instrNode->getInstruction(); + unsigned ZeroReg = target.getRegInfo()->getZeroRegNum(); + + // Cases worth optimizing are: + // (1) Divide by 1 for any type: replace with copy (ADD or FMOV) + // (2) Divide by 2^x for integer types: replace with SR[L or A]{X} + const Type* resultType = instrNode->getInstruction()->getType(); + + if (resultType->isInteger()) { + unsigned pow; + bool isValidConst; + int64_t C = (int64_t) ConvertConstantToIntType(target, constOp, + constOp->getType(), + isValidConst); + if (isValidConst) { + bool needNeg = false; + if (C < 0) { + needNeg = true; + C = -C; + } + + if (C == 1) { + mvec.push_back(BuildMI(V9::ADDr, 3).addReg(LHS).addMReg(ZeroReg) + .addRegDef(destVal)); + } else if (isPowerOf2(C, pow)) { + unsigned opCode; + Value* shiftOperand; + unsigned opSize = target.getTargetData().getTypeSize(resultType); + + if (resultType->isSigned()) { + // For N / 2^k, if the operand N is negative, + // we need to add (2^k - 1) before right-shifting by k, i.e., + // + // (N / 2^k) = N >> k, if N >= 0; + // (N + 2^k - 1) >> k, if N < 0 + // + // If N is <= 32 bits, use: + // sra N, 31, t1 // t1 = ~0, if N < 0, 0 else + // srl t1, 32-k, t2 // t2 = 2^k - 1, if N < 0, 0 else + // add t2, N, t3 // t3 = N + 2^k -1, if N < 0, N else + // sra t3, k, result // result = N / 2^k + // + // If N is 64 bits, use: + // srax N, k-1, t1 // t1 = sign bit in high k positions + // srlx t1, 64-k, t2 // t2 = 2^k - 1, if N < 0, 0 else + // add t2, N, t3 // t3 = N + 2^k -1, if N < 0, N else + // sra t3, k, result // result = N / 2^k + TmpInstruction *sraTmp, *srlTmp, *addTmp; + MachineCodeForInstruction& mcfi + = MachineCodeForInstruction::get(destVal); + sraTmp = new TmpInstruction(mcfi, resultType, LHS, 0, "getSign"); + srlTmp = new TmpInstruction(mcfi, resultType, LHS, 0, "getPlus2km1"); + addTmp = new TmpInstruction(mcfi, resultType, LHS, srlTmp,"incIfNeg"); + + // Create the SRA or SRAX instruction to get the sign bit + mvec.push_back(BuildMI((opSize > 4)? V9::SRAXi6 : V9::SRAi5, 3) + .addReg(LHS) + .addSImm((resultType==Type::LongTy)? pow-1 : 31) + .addRegDef(sraTmp)); + + // Create the SRL or SRLX instruction to get the sign bit + mvec.push_back(BuildMI((opSize > 4)? V9::SRLXi6 : V9::SRLi5, 3) + .addReg(sraTmp) + .addSImm((resultType==Type::LongTy)? 64-pow : 32-pow) + .addRegDef(srlTmp)); + + // Create the ADD instruction to add 2^pow-1 for negative values + mvec.push_back(BuildMI(V9::ADDr, 3).addReg(LHS).addReg(srlTmp) + .addRegDef(addTmp)); + + // Get the shift operand and "right-shift" opcode to do the divide + shiftOperand = addTmp; + opCode = (opSize > 4)? V9::SRAXi6 : V9::SRAi5; + } else { + // Get the shift operand and "right-shift" opcode to do the divide + shiftOperand = LHS; + opCode = (opSize > 4)? V9::SRLXi6 : V9::SRLi5; + } + + // Now do the actual shift! + mvec.push_back(BuildMI(opCode, 3).addReg(shiftOperand).addZImm(pow) + .addRegDef(destVal)); + } + + if (needNeg && (C == 1 || isPowerOf2(C, pow))) { + // insert after the instr to flip the sign + mvec.push_back(CreateIntNegInstruction(target, destVal)); + } + } + } else { + if (ConstantFP *FPC = dyn_cast(constOp)) { + double dval = FPC->getValue(); + if (fabs(dval) == 1) { + unsigned opCode = + (dval < 0) ? (resultType == Type::FloatTy? V9::FNEGS : V9::FNEGD) + : (resultType == Type::FloatTy? V9::FMOVS : V9::FMOVD); + + mvec.push_back(BuildMI(opCode, 2).addReg(LHS).addRegDef(destVal)); + } + } + } + } + + static void CreateCodeForVariableSizeAlloca(const TargetMachine& target, + Instruction* result, unsigned tsize, + Value* numElementsVal, + std::vector& getMvec) + { + Value* totalSizeVal; + MachineInstr* M; + MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result); + Function *F = result->getParent()->getParent(); + + // Enforce the alignment constraints on the stack pointer at + // compile time if the total size is a known constant. + if (isa(numElementsVal)) { + bool isValid; + int64_t numElem = (int64_t) + ConvertConstantToIntType(target, numElementsVal, + numElementsVal->getType(), isValid); + assert(isValid && "Unexpectedly large array dimension in alloca!"); + int64_t total = numElem * tsize; + if (int extra= total % target.getFrameInfo()->getStackFrameSizeAlignment()) + total += target.getFrameInfo()->getStackFrameSizeAlignment() - extra; + totalSizeVal = ConstantSInt::get(Type::IntTy, total); + } else { + // The size is not a constant. Generate code to compute it and + // code to pad the size for stack alignment. + // Create a Value to hold the (constant) element size + Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize); + + // Create temporary values to hold the result of MUL, SLL, SRL + // To pad `size' to next smallest multiple of 16: + // size = (size + 15) & (-16 = 0xfffffffffffffff0) + TmpInstruction* tmpProd = new TmpInstruction(mcfi,numElementsVal, tsizeVal); + TmpInstruction* tmpAdd15= new TmpInstruction(mcfi,numElementsVal, tmpProd); + TmpInstruction* tmpAndf0= new TmpInstruction(mcfi,numElementsVal, tmpAdd15); + + // Instruction 1: mul numElements, typeSize -> tmpProd + // This will optimize the MUL as far as possible. + CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec, + mcfi, -1); + + // Instruction 2: andn tmpProd, 0x0f -> tmpAndn + getMvec.push_back(BuildMI(V9::ADDi, 3).addReg(tmpProd).addSImm(15) + .addReg(tmpAdd15, MachineOperand::Def)); + + // Instruction 3: add tmpAndn, 0x10 -> tmpAdd16 + getMvec.push_back(BuildMI(V9::ANDi, 3).addReg(tmpAdd15).addSImm(-16) + .addReg(tmpAndf0, MachineOperand::Def)); + + totalSizeVal = tmpAndf0; + } + + // Get the constant offset from SP for dynamically allocated storage + // and create a temporary Value to hold it. + MachineFunction& mcInfo = MachineFunction::get(F); + bool growUp; + ConstantSInt* dynamicAreaOffset = + ConstantSInt::get(Type::IntTy, + target.getFrameInfo()->getDynamicAreaOffset(mcInfo,growUp)); + assert(! growUp && "Has SPARC v9 stack frame convention changed?"); + + unsigned SPReg = target.getRegInfo()->getStackPointer(); + + // Instruction 2: sub %sp, totalSizeVal -> %sp + getMvec.push_back(BuildMI(V9::SUBr, 3).addMReg(SPReg).addReg(totalSizeVal) + .addMReg(SPReg,MachineOperand::Def)); + + // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result + getMvec.push_back(BuildMI(V9::ADDr,3).addMReg(SPReg).addReg(dynamicAreaOffset) + .addRegDef(result)); + } + + static void + CreateCodeForFixedSizeAlloca(const TargetMachine& target, + Instruction* result, unsigned tsize, + unsigned numElements, + std::vector& getMvec) { + assert(result && result->getParent() && + "Result value is not part of a function?"); + Function *F = result->getParent()->getParent(); + MachineFunction &mcInfo = MachineFunction::get(F); + + // If the alloca is of zero bytes (which is perfectly legal) we bump it up to + // one byte. This is unnecessary, but I really don't want to break any + // fragile logic in this code. FIXME. + if (tsize == 0) + tsize = 1; + + // Put the variable in the dynamically sized area of the frame if either: + // (a) The offset is too large to use as an immediate in load/stores + // (check LDX because all load/stores have the same-size immed. field). + // (b) The object is "large", so it could cause many other locals, + // spills, and temporaries to have large offsets. + // NOTE: We use LARGE = 8 * argSlotSize = 64 bytes. + // You've gotta love having only 13 bits for constant offset values :-|. + // + unsigned paddedSize; + int offsetFromFP = mcInfo.getInfo()->computeOffsetforLocalVar(result, + paddedSize, + tsize * numElements); + + if (((int)paddedSize) > 8 * target.getFrameInfo()->getSizeOfEachArgOnStack()|| + !target.getInstrInfo()->constantFitsInImmedField(V9::LDXi,offsetFromFP)) { + CreateCodeForVariableSizeAlloca(target, result, tsize, + ConstantSInt::get(Type::IntTy,numElements), + getMvec); + return; + } + + // else offset fits in immediate field so go ahead and allocate it. + offsetFromFP = mcInfo.getInfo()->allocateLocalVar(result, tsize *numElements); + + // Create a temporary Value to hold the constant offset. + // This is needed because it may not fit in the immediate field. + ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP); + + // Instruction 1: add %fp, offsetFromFP -> result + unsigned FPReg = target.getRegInfo()->getFramePointer(); + getMvec.push_back(BuildMI(V9::ADDr, 3).addMReg(FPReg).addReg(offsetVal) + .addRegDef(result)); + } + + /// SetOperandsForMemInstr - Choose addressing mode for the given load or store + /// instruction. Use [reg+reg] if it is an indexed reference, and the index + /// offset is not a constant or if it cannot fit in the offset field. Use + /// [reg+offset] in all other cases. This assumes that all array refs are + /// "lowered" to one of these forms: + /// %x = load (subarray*) ptr, constant ; single constant offset + /// %x = load (subarray*) ptr, offsetVal ; single non-constant offset + /// Generally, this should happen via strength reduction + LICM. Also, strength + /// reduction should take care of using the same register for the loop index + /// variable and an array index, when that is profitable. + /// + static void SetOperandsForMemInstr(unsigned Opcode, + std::vector& mvec, + InstructionNode* vmInstrNode, + const TargetMachine& target) { + Instruction* memInst = vmInstrNode->getInstruction(); + // Index vector, ptr value, and flag if all indices are const. + std::vector idxVec; + bool allConstantIndices; + Value* ptrVal = GetMemInstArgs(vmInstrNode, idxVec, allConstantIndices); + + // Now create the appropriate operands for the machine instruction. + // First, initialize so we default to storing the offset in a register. + int64_t smallConstOffset = 0; + Value* valueForRegOffset = NULL; + MachineOperand::MachineOperandType offsetOpType = + MachineOperand::MO_VirtualRegister; + + // Check if there is an index vector and if so, compute the + // right offset for structures and for arrays + if (!idxVec.empty()) { + const PointerType* ptrType = cast(ptrVal->getType()); + + // If all indices are constant, compute the combined offset directly. + if (allConstantIndices) { + // Compute the offset value using the index vector. Create a + // virtual reg. for it since it may not fit in the immed field. + uint64_t offset = target.getTargetData().getIndexedOffset(ptrType,idxVec); + valueForRegOffset = ConstantSInt::get(Type::LongTy, offset); + } else { + // There is at least one non-constant offset. Therefore, this must + // be an array ref, and must have been lowered to a single non-zero + // offset. (An extra leading zero offset, if any, can be ignored.) + // Generate code sequence to compute address from index. + bool firstIdxIsZero = IsZero(idxVec[0]); + assert(idxVec.size() == 1U + firstIdxIsZero + && "Array refs must be lowered before Instruction Selection"); + + Value* idxVal = idxVec[firstIdxIsZero]; + + std::vector mulVec; + Instruction* addr = + new TmpInstruction(MachineCodeForInstruction::get(memInst), + Type::ULongTy, memInst); + + // Get the array type indexed by idxVal, and compute its element size. + // The call to getTypeSize() will fail if size is not constant. + const Type* vecType = (firstIdxIsZero + ? GetElementPtrInst::getIndexedType(ptrType, + std::vector(1U, idxVec[0]), + /*AllowCompositeLeaf*/ true) + : ptrType); + const Type* eltType = cast(vecType)->getElementType(); + ConstantUInt* eltSizeVal = ConstantUInt::get(Type::ULongTy, + target.getTargetData().getTypeSize(eltType)); + + // CreateMulInstruction() folds constants intelligently enough. + CreateMulInstruction(target, memInst->getParent()->getParent(), + idxVal, /* lval, not likely to be const*/ + eltSizeVal, /* rval, likely to be constant */ + addr, /* result */ + mulVec, MachineCodeForInstruction::get(memInst), + -1); + + assert(mulVec.size() > 0 && "No multiply code created?"); + mvec.insert(mvec.end(), mulVec.begin(), mulVec.end()); + + valueForRegOffset = addr; + } + } else { + offsetOpType = MachineOperand::MO_SignExtendedImmed; + smallConstOffset = 0; + } + + // For STORE: + // Operand 0 is value, operand 1 is ptr, operand 2 is offset + // For LOAD or GET_ELEMENT_PTR, + // Operand 0 is ptr, operand 1 is offset, operand 2 is result. + unsigned offsetOpNum, ptrOpNum; + MachineInstr *MI; + if (memInst->getOpcode() == Instruction::Store) { + if (offsetOpType == MachineOperand::MO_VirtualRegister) { + MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue()) + .addReg(ptrVal).addReg(valueForRegOffset); + } else { + Opcode = convertOpcodeFromRegToImm(Opcode); + MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue()) + .addReg(ptrVal).addSImm(smallConstOffset); + } + } else { + if (offsetOpType == MachineOperand::MO_VirtualRegister) { + MI = BuildMI(Opcode, 3).addReg(ptrVal).addReg(valueForRegOffset) + .addRegDef(memInst); + } else { + Opcode = convertOpcodeFromRegToImm(Opcode); + MI = BuildMI(Opcode, 3).addReg(ptrVal).addSImm(smallConstOffset) + .addRegDef(memInst); + } + } + mvec.push_back(MI); + } + + /// ForwardOperand - Substitute operand `operandNum' of the instruction in + /// node `treeNode' in place of the use(s) of that instruction in node `parent'. + /// Check both explicit and implicit operands! Also make sure to skip over a + /// parent who: (1) is a list node in the Burg tree, or (2) itself had its + /// results forwarded to its parent. + /// + static void ForwardOperand (InstructionNode *treeNode, InstrTreeNode *parent, + int operandNum) { + assert(treeNode && parent && "Invalid invocation of ForwardOperand"); + + Instruction* unusedOp = treeNode->getInstruction(); + Value* fwdOp = unusedOp->getOperand(operandNum); + + // The parent itself may be a list node, so find the real parent instruction + while (parent->getNodeType() != InstrTreeNode::NTInstructionNode) { + parent = parent->parent(); + assert(parent && "ERROR: Non-instruction node has no parent in tree."); + } + InstructionNode* parentInstrNode = (InstructionNode*) parent; + + Instruction* userInstr = parentInstrNode->getInstruction(); + MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(userInstr); + + // The parent's mvec would be empty if it was itself forwarded. + // Recursively call ForwardOperand in that case... + // + if (mvec.size() == 0) { + assert(parent->parent() != NULL && + "Parent could not have been forwarded, yet has no instructions?"); + ForwardOperand(treeNode, parent->parent(), operandNum); + } else { + for (unsigned i=0, N=mvec.size(); i < N; i++) { + MachineInstr* minstr = mvec[i]; + for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i) { + const MachineOperand& mop = minstr->getOperand(i); + if (mop.getType() == MachineOperand::MO_VirtualRegister && + mop.getVRegValue() == unusedOp) { + minstr->SetMachineOperandVal(i, MachineOperand::MO_VirtualRegister, + fwdOp); + } + } + + for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); igetImplicitRef(i) == unusedOp) + minstr->setImplicitRef(i, fwdOp); + } + } + } + + /// AllUsesAreBranches - Returns true if all the uses of I are + /// Branch instructions, false otherwise. + /// + inline bool AllUsesAreBranches(const Instruction* I) { + for (Value::use_const_iterator UI=I->use_begin(), UE=I->use_end(); + UI != UE; ++UI) + if (! isa(*UI) // ignore tmp instructions here + && cast(*UI)->getOpcode() != Instruction::Br) + return false; + return true; + } + + /// CodeGenIntrinsic - Generate code for any intrinsic that needs a special + /// code sequence instead of a regular call. If not that kind of intrinsic, do + /// nothing. Returns true if code was generated, otherwise false. + /// + static bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr, + TargetMachine &target, + std::vector& mvec) { + switch (iid) { + default: + assert(0 && "Unknown intrinsic function call should have been lowered!"); + case Intrinsic::vastart: { + // Get the address of the first incoming vararg argument on the stack + bool ignore; + Function* func = cast(callInstr.getParent()->getParent()); + int numFixedArgs = func->getFunctionType()->getNumParams(); + int fpReg = target.getFrameInfo()->getIncomingArgBaseRegNum(); + int argSize = target.getFrameInfo()->getSizeOfEachArgOnStack(); + int firstVarArgOff = numFixedArgs * argSize + target.getFrameInfo()-> + getFirstIncomingArgOffset(MachineFunction::get(func), ignore); + mvec.push_back(BuildMI(V9::ADDi, 3).addMReg(fpReg).addSImm(firstVarArgOff). + addRegDef(&callInstr)); + return true; + } + + case Intrinsic::vaend: + return true; // no-op on SparcV9 + + case Intrinsic::vacopy: + // Simple copy of current va_list (arg1) to new va_list (result) + mvec.push_back(BuildMI(V9::ORr, 3). + addMReg(target.getRegInfo()->getZeroRegNum()). + addReg(callInstr.getOperand(1)). + addRegDef(&callInstr)); + return true; + } + } + + /// ThisIsAChainRule - returns true if the given BURG rule is a chain rule. + /// + extern bool ThisIsAChainRule(int eruleno) { + switch(eruleno) { + case 111: // stmt: reg + case 123: + case 124: + case 125: + case 126: + case 127: + case 128: + case 129: + case 130: + case 131: + case 132: + case 133: + case 155: + case 221: + case 222: + case 241: + case 242: + case 243: + case 244: + case 245: + case 321: + return true; break; + + default: + return false; break; + } + } + + /// GetInstructionsByRule - Choose machine instructions for the + /// SPARC V9 according to the patterns chosen by the BURG-generated parser. + /// This is where most of the work in the V9 instruction selector gets done. + /// + void GetInstructionsByRule(InstructionNode* subtreeRoot, int ruleForNode, + short* nts, TargetMachine &target, + std::vector& mvec) { + bool checkCast = false; // initialize here to use fall-through + bool maskUnsignedResult = false; + int nextRule; + int forwardOperandNum = -1; + unsigned allocaSize = 0; + MachineInstr* M, *M2; + unsigned L; + bool foldCase = false; + + mvec.clear(); + + // If the code for this instruction was folded into the parent (user), + // then do nothing! + if (subtreeRoot->isFoldedIntoParent()) + return; + + // Let's check for chain rules outside the switch so that we don't have + // to duplicate the list of chain rule production numbers here again + if (ThisIsAChainRule(ruleForNode)) { + // Chain rules have a single nonterminal on the RHS. + // Get the rule that matches the RHS non-terminal and use that instead. + assert(nts[0] && ! nts[1] + && "A chain rule should have only one RHS non-terminal!"); + nextRule = burm_rule(subtreeRoot->state, nts[0]); + nts = burm_nts[nextRule]; + GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec); + } else { + switch(ruleForNode) { + case 1: // stmt: Ret + case 2: // stmt: RetValue(reg) + { // NOTE: Prepass of register allocation is responsible + // for moving return value to appropriate register. + // Copy the return value to the required return register. + // Mark the return Value as an implicit ref of the RET instr.. + // Mark the return-address register as a hidden virtual reg. + // Finally put a NOP in the delay slot. + ReturnInst *returnInstr=cast(subtreeRoot->getInstruction()); + Value* retVal = returnInstr->getReturnValue(); + MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get(returnInstr); + + // Create a hidden virtual reg to represent the return address register + // used by the machine instruction but not represented in LLVM. + Instruction* returnAddrTmp = new TmpInstruction(mcfi, returnInstr); + + MachineInstr* retMI = + BuildMI(V9::JMPLRETi, 3).addReg(returnAddrTmp).addSImm(8) + .addMReg(target.getRegInfo()->getZeroRegNum(), MachineOperand::Def); + + // If there is a value to return, we need to: + // (a) Sign-extend the value if it is smaller than 8 bytes (reg size) + // (b) Insert a copy to copy the return value to the appropriate reg. + // -- For FP values, create a FMOVS or FMOVD instruction + // -- For non-FP values, create an add-with-0 instruction + if (retVal != NULL) { + const SparcV9RegInfo& regInfo = + (SparcV9RegInfo&) *target.getRegInfo(); + const Type* retType = retVal->getType(); + unsigned regClassID = regInfo.getRegClassIDOfType(retType); + unsigned retRegNum = (retType->isFloatingPoint() + ? (unsigned) SparcV9FloatRegClass::f0 + : (unsigned) SparcV9IntRegClass::i0); + retRegNum = regInfo.getUnifiedRegNum(regClassID, retRegNum); + + // Insert sign-extension instructions for small signed values. + Value* retValToUse = retVal; + if (retType->isIntegral() && retType->isSigned()) { + unsigned retSize = target.getTargetData().getTypeSize(retType); + if (retSize <= 4) { + // Create a temporary virtual reg. to hold the sign-extension. + retValToUse = new TmpInstruction(mcfi, retVal); + + // Sign-extend retVal and put the result in the temporary reg. + CreateSignExtensionInstructions + (target, returnInstr->getParent()->getParent(), + retVal, retValToUse, 8*retSize, mvec, mcfi); + } + } + + // (b) Now, insert a copy to to the appropriate register: + // -- For FP values, create a FMOVS or FMOVD instruction + // -- For non-FP values, create an add-with-0 instruction + // First, create a virtual register to represent the register and + // mark this vreg as being an implicit operand of the ret MI. + TmpInstruction* retVReg = + new TmpInstruction(mcfi, retValToUse, NULL, "argReg"); + + retMI->addImplicitRef(retVReg); + + if (retType->isFloatingPoint()) + M = (BuildMI(retType==Type::FloatTy? V9::FMOVS : V9::FMOVD, 2) + .addReg(retValToUse).addReg(retVReg, MachineOperand::Def)); + else + M = (BuildMI(ChooseAddInstructionByType(retType), 3) + .addReg(retValToUse).addSImm((int64_t) 0) + .addReg(retVReg, MachineOperand::Def)); + + // Mark the operand with the register it should be assigned + M->SetRegForOperand(M->getNumOperands()-1, retRegNum); + retMI->SetRegForImplicitRef(retMI->getNumImplicitRefs()-1, retRegNum); + + mvec.push_back(M); + } + + // Now insert the RET instruction and a NOP for the delay slot + mvec.push_back(retMI); + mvec.push_back(BuildMI(V9::NOP, 0)); + + break; + } + + case 3: // stmt: Store(reg,reg) + case 4: // stmt: Store(reg,ptrreg) + SetOperandsForMemInstr(ChooseStoreInstruction( + subtreeRoot->leftChild()->getValue()->getType()), + mvec, subtreeRoot, target); + break; + + case 5: // stmt: BrUncond + { + BranchInst *BI = cast(subtreeRoot->getInstruction()); + mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0))); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + break; + } + + case 206: // stmt: BrCond(setCCconst) + { // setCCconst => boolean was computed with `%b = setCC type reg1 const' + // If the constant is ZERO, we can use the branch-on-integer-register + // instructions and avoid the SUBcc instruction entirely. + // Otherwise this is just the same as case 5, so just fall through. + // + InstrTreeNode* constNode = subtreeRoot->leftChild()->rightChild(); + assert(constNode && + constNode->getNodeType() ==InstrTreeNode::NTConstNode); + Constant *constVal = cast(constNode->getValue()); + bool isValidConst; + + if ((constVal->getType()->isInteger() + || isa(constVal->getType())) + && ConvertConstantToIntType(target, + constVal, constVal->getType(), isValidConst) == 0 + && isValidConst) + { + // That constant is a zero after all... + // Use the left child of setCC as the first argument! + // Mark the setCC node so that no code is generated for it. + InstructionNode* setCCNode = (InstructionNode*) + subtreeRoot->leftChild(); + assert(setCCNode->getOpLabel() == SetCCOp); + setCCNode->markFoldedIntoParent(); + + BranchInst* brInst=cast(subtreeRoot->getInstruction()); + + M = BuildMI(ChooseBprInstruction(subtreeRoot), 2) + .addReg(setCCNode->leftChild()->getValue()) + .addPCDisp(brInst->getSuccessor(0)); + mvec.push_back(M); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + + // false branch + mvec.push_back(BuildMI(V9::BA, 1) + .addPCDisp(brInst->getSuccessor(1))); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + break; + } + // ELSE FALL THROUGH + } + + case 6: // stmt: BrCond(setCC) + { // bool => boolean was computed with SetCC. + // The branch to use depends on whether it is FP, signed, or unsigned. + // If it is an integer CC, we also need to find the unique + // TmpInstruction representing that CC. + // + BranchInst* brInst = cast(subtreeRoot->getInstruction()); + const Type* setCCType; + unsigned Opcode = ChooseBccInstruction(subtreeRoot, setCCType); + Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(), + brInst->getParent()->getParent(), + setCCType, + MachineCodeForInstruction::get(brInst)); + M = BuildMI(Opcode, 2).addCCReg(ccValue) + .addPCDisp(brInst->getSuccessor(0)); + mvec.push_back(M); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + + // false branch + mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(brInst->getSuccessor(1))); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + break; + } + + case 208: // stmt: BrCond(boolconst) + { + // boolconst => boolean is a constant; use BA to first or second label + Constant* constVal = + cast(subtreeRoot->leftChild()->getValue()); + unsigned dest = cast(constVal)->getValue()? 0 : 1; + + M = BuildMI(V9::BA, 1).addPCDisp( + cast(subtreeRoot->getInstruction())->getSuccessor(dest)); + mvec.push_back(M); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + break; + } + + case 8: // stmt: BrCond(boolreg) + { // boolreg => boolean is recorded in an integer register. + // Use branch-on-integer-register instruction. + // + BranchInst *BI = cast(subtreeRoot->getInstruction()); + M = BuildMI(V9::BRNZ, 2).addReg(subtreeRoot->leftChild()->getValue()) + .addPCDisp(BI->getSuccessor(0)); + mvec.push_back(M); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + + // false branch + mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(1))); + + // delay slot + mvec.push_back(BuildMI(V9::NOP, 0)); + break; + } + + case 9: // stmt: Switch(reg) + assert(0 && "*** SWITCH instruction is not implemented yet."); + break; + + case 10: // reg: VRegList(reg, reg) + assert(0 && "VRegList should never be the topmost non-chain rule"); + break; + + case 21: // bool: Not(bool,reg): Compute with a conditional-move-on-reg + { // First find the unary operand. It may be left or right, usually right. + Instruction* notI = subtreeRoot->getInstruction(); + Value* notArg = BinaryOperator::getNotArgument( + cast(subtreeRoot->getInstruction())); + unsigned ZeroReg = target.getRegInfo()->getZeroRegNum(); + + // Unconditionally set register to 0 + mvec.push_back(BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(notI)); + + // Now conditionally move 1 into the register. + // Mark the register as a use (as well as a def) because the old + // value will be retained if the condition is false. + mvec.push_back(BuildMI(V9::MOVRZi, 3).addReg(notArg).addZImm(1) + .addReg(notI, MachineOperand::UseAndDef)); + + break; + } + + case 421: // reg: BNot(reg,reg): Compute as reg = reg XOR-NOT 0 + { // First find the unary operand. It may be left or right, usually right. + Value* notArg = BinaryOperator::getNotArgument( + cast(subtreeRoot->getInstruction())); + unsigned ZeroReg = target.getRegInfo()->getZeroRegNum(); + mvec.push_back(BuildMI(V9::XNORr, 3).addReg(notArg).addMReg(ZeroReg) + .addRegDef(subtreeRoot->getValue())); + break; + } + + case 322: // reg: Not(tobool, reg): + // Fold CAST-TO-BOOL with NOT by inverting the sense of cast-to-bool + foldCase = true; + // Just fall through! + + case 22: // reg: ToBoolTy(reg): + { + Instruction* castI = subtreeRoot->getInstruction(); + Value* opVal = subtreeRoot->leftChild()->getValue(); + assert(opVal->getType()->isIntegral() || + isa(opVal->getType())); + + // Unconditionally set register to 0 + mvec.push_back(BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(castI)); + + // Now conditionally move 1 into the register. + // Mark the register as a use (as well as a def) because the old + // value will be retained if the condition is false. + MachineOpCode opCode = foldCase? V9::MOVRZi : V9::MOVRNZi; + mvec.push_back(BuildMI(opCode, 3).addReg(opVal).addZImm(1) + .addReg(castI, MachineOperand::UseAndDef)); + + break; + } + + case 23: // reg: ToUByteTy(reg) + case 24: // reg: ToSByteTy(reg) + case 25: // reg: ToUShortTy(reg) + case 26: // reg: ToShortTy(reg) + case 27: // reg: ToUIntTy(reg) + case 28: // reg: ToIntTy(reg) + case 29: // reg: ToULongTy(reg) + case 30: // reg: ToLongTy(reg) + { + //====================================================================== + // Rules for integer conversions: + // + //-------- + // From ISO 1998 C++ Standard, Sec. 4.7: + // + // 2. If the destination type is unsigned, the resulting value is + // the least unsigned integer congruent to the source integer + // (modulo 2n where n is the number of bits used to represent the + // unsigned type). [Note: In a two s complement representation, + // this conversion is conceptual and there is no change in the + // bit pattern (if there is no truncation). ] + // + // 3. If the destination type is signed, the value is unchanged if + // it can be represented in the destination type (and bitfield width); + // otherwise, the value is implementation-defined. + //-------- + // + // Since we assume 2s complement representations, this implies: + // + // -- If operand is smaller than destination, zero-extend or sign-extend + // according to the signedness of the *operand*: source decides: + // (1) If operand is signed, sign-extend it. + // If dest is unsigned, zero-ext the result! + // (2) If operand is unsigned, our current invariant is that + // it's high bits are correct, so zero-extension is not needed. + // + // -- If operand is same size as or larger than destination, + // zero-extend or sign-extend according to the signedness of + // the *destination*: destination decides: + // (1) If destination is signed, sign-extend (truncating if needed) + // This choice is implementation defined. We sign-extend the + // operand, which matches both Sun's cc and gcc3.2. + // (2) If destination is unsigned, zero-extend (truncating if needed) + //====================================================================== + + Instruction* destI = subtreeRoot->getInstruction(); + Function* currentFunc = destI->getParent()->getParent(); + MachineCodeForInstruction& mcfi=MachineCodeForInstruction::get(destI); + + Value* opVal = subtreeRoot->leftChild()->getValue(); + const Type* opType = opVal->getType(); + const Type* destType = destI->getType(); + unsigned opSize = target.getTargetData().getTypeSize(opType); + unsigned destSize = target.getTargetData().getTypeSize(destType); + + bool isIntegral = opType->isIntegral() || isa(opType); + + if (opType == Type::BoolTy || + opType == destType || + isIntegral && opSize == destSize && opSize == 8) { + // nothing to do in all these cases + forwardOperandNum = 0; // forward first operand to user + + } else if (opType->isFloatingPoint()) { + + CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, mcfi); + if (destI->getType()->isUnsigned() && destI->getType() !=Type::UIntTy) + maskUnsignedResult = true; // not handled by fp->int code + + } else if (isIntegral) { + + bool opSigned = opType->isSigned(); + bool destSigned = destType->isSigned(); + unsigned extSourceInBits = 8 * std::min(opSize, destSize); + + assert(! (opSize == destSize && opSigned == destSigned) && + "How can different int types have same size and signedness?"); + + bool signExtend = (opSize < destSize && opSigned || + opSize >= destSize && destSigned); + + bool signAndZeroExtend = (opSize < destSize && destSize < 8u && + opSigned && !destSigned); + assert(!signAndZeroExtend || signExtend); + + bool zeroExtendOnly = opSize >= destSize && !destSigned; + assert(!zeroExtendOnly || !signExtend); + + if (signExtend) { + Value* signExtDest = (signAndZeroExtend + ? new TmpInstruction(mcfi, destType, opVal) + : destI); + + CreateSignExtensionInstructions + (target, currentFunc,opVal,signExtDest,extSourceInBits,mvec,mcfi); + + if (signAndZeroExtend) + CreateZeroExtensionInstructions + (target, currentFunc, signExtDest, destI, 8*destSize, mvec, mcfi); + } + else if (zeroExtendOnly) { + CreateZeroExtensionInstructions + (target, currentFunc, opVal, destI, extSourceInBits, mvec, mcfi); + } + else + forwardOperandNum = 0; // forward first operand to user + + } else + assert(0 && "Unrecognized operand type for convert-to-integer"); + + break; + } + + case 31: // reg: ToFloatTy(reg): + case 32: // reg: ToDoubleTy(reg): + case 232: // reg: ToDoubleTy(Constant): + + // If this instruction has a parent (a user) in the tree + // and the user is translated as an FsMULd instruction, + // then the cast is unnecessary. So check that first. + // In the future, we'll want to do the same for the FdMULq instruction, + // so do the check here instead of only for ToFloatTy(reg). + // + if (subtreeRoot->parent() != NULL) { + const MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get( + cast(subtreeRoot->parent())->getInstruction()); + if (mcfi.size() == 0 || mcfi.front()->getOpcode() == V9::FSMULD) + forwardOperandNum = 0; // forward first operand to user + } + + if (forwardOperandNum != 0) { // we do need the cast + Value* leftVal = subtreeRoot->leftChild()->getValue(); + const Type* opType = leftVal->getType(); + MachineOpCode opCode=ChooseConvertToFloatInstr(target, + subtreeRoot->getOpLabel(), opType); + if (opCode == V9::NOP) { // no conversion needed + forwardOperandNum = 0; // forward first operand to user + } else { + // If the source operand is a non-FP type it must be + // first copied from int to float register via memory! + Instruction *dest = subtreeRoot->getInstruction(); + Value* srcForCast; + int n = 0; + if (! opType->isFloatingPoint()) { + // Create a temporary to represent the FP register + // into which the integer will be copied via memory. + // The type of this temporary will determine the FP + // register used: single-prec for a 32-bit int or smaller, + // double-prec for a 64-bit int. + // + uint64_t srcSize = + target.getTargetData().getTypeSize(leftVal->getType()); + Type* tmpTypeToUse = + (srcSize <= 4)? Type::FloatTy : Type::DoubleTy; + MachineCodeForInstruction &destMCFI = + MachineCodeForInstruction::get(dest); + srcForCast = new TmpInstruction(destMCFI, tmpTypeToUse, dest); + + CreateCodeToCopyIntToFloat(target, + dest->getParent()->getParent(), + leftVal, cast(srcForCast), + mvec, destMCFI); + } else + srcForCast = leftVal; + + M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest); + mvec.push_back(M); + } + } + break; + + case 19: // reg: ToArrayTy(reg): + case 20: // reg: ToPointerTy(reg): + forwardOperandNum = 0; // forward first operand to user + break; + + case 233: // reg: Add(reg, Constant) + maskUnsignedResult = true; + M = CreateAddConstInstruction(subtreeRoot); + if (M != NULL) { + mvec.push_back(M); + break; + } + // ELSE FALL THROUGH + + case 33: // reg: Add(reg, reg) + maskUnsignedResult = true; + Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec); + break; + + case 234: // reg: Sub(reg, Constant) + maskUnsignedResult = true; + M = CreateSubConstInstruction(subtreeRoot); + if (M != NULL) { + mvec.push_back(M); + break; + } + // ELSE FALL THROUGH + + case 34: // reg: Sub(reg, reg) + maskUnsignedResult = true; + Add3OperandInstr(ChooseSubInstructionByType( + subtreeRoot->getInstruction()->getType()), + subtreeRoot, mvec); + break; + + case 135: // reg: Mul(todouble, todouble) + checkCast = true; + // FALL THROUGH + + case 35: // reg: Mul(reg, reg) + { + maskUnsignedResult = true; + MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) + ? (MachineOpCode)V9::FSMULD + : -1); + Instruction* mulInstr = subtreeRoot->getInstruction(); + CreateMulInstruction(target, mulInstr->getParent()->getParent(), + subtreeRoot->leftChild()->getValue(), + subtreeRoot->rightChild()->getValue(), + mulInstr, mvec, + MachineCodeForInstruction::get(mulInstr),forceOp); + break; + } + case 335: // reg: Mul(todouble, todoubleConst) + checkCast = true; + // FALL THROUGH + + case 235: // reg: Mul(reg, Constant) + { + maskUnsignedResult = true; + MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) + ? (MachineOpCode)V9::FSMULD + : -1); + Instruction* mulInstr = subtreeRoot->getInstruction(); + CreateMulInstruction(target, mulInstr->getParent()->getParent(), + subtreeRoot->leftChild()->getValue(), + subtreeRoot->rightChild()->getValue(), + mulInstr, mvec, + MachineCodeForInstruction::get(mulInstr), + forceOp); + break; + } + case 236: // reg: Div(reg, Constant) + maskUnsignedResult = true; + L = mvec.size(); + CreateDivConstInstruction(target, subtreeRoot, mvec); + if (mvec.size() > L) + break; + // ELSE FALL THROUGH + + case 36: // reg: Div(reg, reg) + { + maskUnsignedResult = true; + + // If either operand of divide is smaller than 64 bits, we have + // to make sure the unused top bits are correct because they affect + // the result. These bits are already correct for unsigned values. + // They may be incorrect for signed values, so sign extend to fill in. + Instruction* divI = subtreeRoot->getInstruction(); + Value* divOp1 = subtreeRoot->leftChild()->getValue(); + Value* divOp2 = subtreeRoot->rightChild()->getValue(); + Value* divOp1ToUse = divOp1; + Value* divOp2ToUse = divOp2; + if (divI->getType()->isSigned()) { + unsigned opSize=target.getTargetData().getTypeSize(divI->getType()); + if (opSize < 8) { + MachineCodeForInstruction& mcfi=MachineCodeForInstruction::get(divI); + divOp1ToUse = new TmpInstruction(mcfi, divOp1); + divOp2ToUse = new TmpInstruction(mcfi, divOp2); + CreateSignExtensionInstructions(target, + divI->getParent()->getParent(), + divOp1, divOp1ToUse, + 8*opSize, mvec, mcfi); + CreateSignExtensionInstructions(target, + divI->getParent()->getParent(), + divOp2, divOp2ToUse, + 8*opSize, mvec, mcfi); + } + } + + mvec.push_back(BuildMI(ChooseDivInstruction(target, subtreeRoot), 3) + .addReg(divOp1ToUse) + .addReg(divOp2ToUse) + .addRegDef(divI)); + + break; + } + + case 37: // reg: Rem(reg, reg) + case 237: // reg: Rem(reg, Constant) + { + maskUnsignedResult = true; + + Instruction* remI = subtreeRoot->getInstruction(); + Value* divOp1 = subtreeRoot->leftChild()->getValue(); + Value* divOp2 = subtreeRoot->rightChild()->getValue(); + + MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(remI); + + // If second operand of divide is smaller than 64 bits, we have + // to make sure the unused top bits are correct because they affect + // the result. These bits are already correct for unsigned values. + // They may be incorrect for signed values, so sign extend to fill in. + // + Value* divOpToUse = divOp2; + if (divOp2->getType()->isSigned()) { + unsigned opSize=target.getTargetData().getTypeSize(divOp2->getType()); + if (opSize < 8) { + divOpToUse = new TmpInstruction(mcfi, divOp2); + CreateSignExtensionInstructions(target, + remI->getParent()->getParent(), + divOp2, divOpToUse, + 8*opSize, mvec, mcfi); + } + } + + // Now compute: result = rem V1, V2 as: + // result = V1 - (V1 / signExtend(V2)) * signExtend(V2) + // + TmpInstruction* quot = new TmpInstruction(mcfi, divOp1, divOpToUse); + TmpInstruction* prod = new TmpInstruction(mcfi, quot, divOpToUse); + + mvec.push_back(BuildMI(ChooseDivInstruction(target, subtreeRoot), 3) + .addReg(divOp1).addReg(divOpToUse).addRegDef(quot)); + + mvec.push_back(BuildMI(ChooseMulInstructionByType(remI->getType()), 3) + .addReg(quot).addReg(divOpToUse).addRegDef(prod)); + + mvec.push_back(BuildMI(ChooseSubInstructionByType(remI->getType()), 3) + .addReg(divOp1).addReg(prod).addRegDef(remI)); + + break; + } + + case 38: // bool: And(bool, bool) + case 138: // bool: And(bool, not) + case 238: // bool: And(bool, boolconst) + case 338: // reg : BAnd(reg, reg) + case 538: // reg : BAnd(reg, Constant) + Add3OperandInstr(V9::ANDr, subtreeRoot, mvec); + break; + + case 438: // bool: BAnd(bool, bnot) + { // Use the argument of NOT as the second argument! + // Mark the NOT node so that no code is generated for it. + // If the type is boolean, set 1 or 0 in the result register. + InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); + Value* notArg = BinaryOperator::getNotArgument( + cast(notNode->getInstruction())); + notNode->markFoldedIntoParent(); + Value *lhs = subtreeRoot->leftChild()->getValue(); + Value *dest = subtreeRoot->getValue(); + mvec.push_back(BuildMI(V9::ANDNr, 3).addReg(lhs).addReg(notArg) + .addReg(dest, MachineOperand::Def)); + + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MachineOperand::UseAndDef)); + } + + break; + } + + case 39: // bool: Or(bool, bool) + case 139: // bool: Or(bool, not) + case 239: // bool: Or(bool, boolconst) + case 339: // reg : BOr(reg, reg) + case 539: // reg : BOr(reg, Constant) + Add3OperandInstr(V9::ORr, subtreeRoot, mvec); + break; + + case 439: // bool: BOr(bool, bnot) + { // Use the argument of NOT as the second argument! + // Mark the NOT node so that no code is generated for it. + // If the type is boolean, set 1 or 0 in the result register. + InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); + Value* notArg = BinaryOperator::getNotArgument( + cast(notNode->getInstruction())); + notNode->markFoldedIntoParent(); + Value *lhs = subtreeRoot->leftChild()->getValue(); + Value *dest = subtreeRoot->getValue(); + + mvec.push_back(BuildMI(V9::ORNr, 3).addReg(lhs).addReg(notArg) + .addReg(dest, MachineOperand::Def)); + + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MachineOperand::UseAndDef)); + } + + break; + } + + case 40: // bool: Xor(bool, bool) + case 140: // bool: Xor(bool, not) + case 240: // bool: Xor(bool, boolconst) + case 340: // reg : BXor(reg, reg) + case 540: // reg : BXor(reg, Constant) + Add3OperandInstr(V9::XORr, subtreeRoot, mvec); + break; + + case 440: // bool: BXor(bool, bnot) + { // Use the argument of NOT as the second argument! + // Mark the NOT node so that no code is generated for it. + // If the type is boolean, set 1 or 0 in the result register. + InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); + Value* notArg = BinaryOperator::getNotArgument( + cast(notNode->getInstruction())); + notNode->markFoldedIntoParent(); + Value *lhs = subtreeRoot->leftChild()->getValue(); + Value *dest = subtreeRoot->getValue(); + mvec.push_back(BuildMI(V9::XNORr, 3).addReg(lhs).addReg(notArg) + .addReg(dest, MachineOperand::Def)); + + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MachineOperand::UseAndDef)); + } + break; + } + + case 41: // setCCconst: SetCC(reg, Constant) + { // Comparison is with a constant: + // + // If the bool result must be computed into a register (see below), + // and the constant is int ZERO, we can use the MOVR[op] instructions + // and avoid the SUBcc instruction entirely. + // Otherwise this is just the same as case 42, so just fall through. + // + // The result of the SetCC must be computed and stored in a register if + // it is used outside the current basic block (so it must be computed + // as a boolreg) or it is used by anything other than a branch. + // We will use a conditional move to do this. + // + Instruction* setCCInstr = subtreeRoot->getInstruction(); + bool computeBoolVal = (subtreeRoot->parent() == NULL || + ! AllUsesAreBranches(setCCInstr)); + + if (computeBoolVal) { + InstrTreeNode* constNode = subtreeRoot->rightChild(); + assert(constNode && + constNode->getNodeType() ==InstrTreeNode::NTConstNode); + Constant *constVal = cast(constNode->getValue()); + bool isValidConst; + + if ((constVal->getType()->isInteger() + || isa(constVal->getType())) + && ConvertConstantToIntType(target, + constVal, constVal->getType(), isValidConst) == 0 + && isValidConst) + { + // That constant is an integer zero after all... + // Use a MOVR[op] to compute the boolean result + // Unconditionally set register to 0 + mvec.push_back(BuildMI(V9::SETHI, 2).addZImm(0) + .addRegDef(setCCInstr)); + + // Now conditionally move 1 into the register. + // Mark the register as a use (as well as a def) because the old + // value will be retained if the condition is false. + MachineOpCode movOpCode = ChooseMovpregiForSetCC(subtreeRoot); + mvec.push_back(BuildMI(movOpCode, 3) + .addReg(subtreeRoot->leftChild()->getValue()) + .addZImm(1) + .addReg(setCCInstr, MachineOperand::UseAndDef)); + + break; + } + } + // ELSE FALL THROUGH + } + + case 42: // bool: SetCC(reg, reg): + { + // This generates a SUBCC instruction, putting the difference in a + // result reg. if needed, and/or setting a condition code if needed. + // + Instruction* setCCInstr = subtreeRoot->getInstruction(); + Value* leftVal = subtreeRoot->leftChild()->getValue(); + Value* rightVal = subtreeRoot->rightChild()->getValue(); + const Type* opType = leftVal->getType(); + bool isFPCompare = opType->isFloatingPoint(); + + // If the boolean result of the SetCC is used outside the current basic + // block (so it must be computed as a boolreg) or is used by anything + // other than a branch, the boolean must be computed and stored + // in a result register. We will use a conditional move to do this. + // + bool computeBoolVal = (subtreeRoot->parent() == NULL || + ! AllUsesAreBranches(setCCInstr)); + + // A TmpInstruction is created to represent the CC "result". + // Unlike other instances of TmpInstruction, this one is used + // by machine code of multiple LLVM instructions, viz., + // the SetCC and the branch. Make sure to get the same one! + // Note that we do this even for FP CC registers even though they + // are explicit operands, because the type of the operand + // needs to be a floating point condition code, not an integer + // condition code. Think of this as casting the bool result to + // a FP condition code register. + // Later, we mark the 4th operand as being a CC register, and as a def. + // + TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr, + setCCInstr->getParent()->getParent(), + leftVal->getType(), + MachineCodeForInstruction::get(setCCInstr)); + + // If the operands are signed values smaller than 4 bytes, then they + // must be sign-extended in order to do a valid 32-bit comparison + // and get the right result in the 32-bit CC register (%icc). + // + Value* leftOpToUse = leftVal; + Value* rightOpToUse = rightVal; + if (opType->isIntegral() && opType->isSigned()) { + unsigned opSize = target.getTargetData().getTypeSize(opType); + if (opSize < 4) { + MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get(setCCInstr); + + // create temporary virtual regs. to hold the sign-extensions + leftOpToUse = new TmpInstruction(mcfi, leftVal); + rightOpToUse = new TmpInstruction(mcfi, rightVal); + + // sign-extend each operand and put the result in the temporary reg. + CreateSignExtensionInstructions + (target, setCCInstr->getParent()->getParent(), + leftVal, leftOpToUse, 8*opSize, mvec, mcfi); + CreateSignExtensionInstructions + (target, setCCInstr->getParent()->getParent(), + rightVal, rightOpToUse, 8*opSize, mvec, mcfi); + } + } + + if (! isFPCompare) { + // Integer condition: set CC and discard result. + mvec.push_back(BuildMI(V9::SUBccr, 4) + .addReg(leftOpToUse) + .addReg(rightOpToUse) + .addMReg(target.getRegInfo()-> + getZeroRegNum(), MachineOperand::Def) + .addCCReg(tmpForCC, MachineOperand::Def)); + } else { + // FP condition: dest of FCMP should be some FCCn register + mvec.push_back(BuildMI(ChooseFcmpInstruction(subtreeRoot), 3) + .addCCReg(tmpForCC, MachineOperand::Def) + .addReg(leftOpToUse) + .addReg(rightOpToUse)); + } + + if (computeBoolVal) { + MachineOpCode movOpCode = (isFPCompare + ? ChooseMovFpcciInstruction(subtreeRoot) + : ChooseMovpcciForSetCC(subtreeRoot)); + + // Unconditionally set register to 0 + M = BuildMI(V9::SETHI, 2).addZImm(0).addRegDef(setCCInstr); + mvec.push_back(M); + + // Now conditionally move 1 into the register. + // Mark the register as a use (as well as a def) because the old + // value will be retained if the condition is false. + M = (BuildMI(movOpCode, 3).addCCReg(tmpForCC).addZImm(1) + .addReg(setCCInstr, MachineOperand::UseAndDef)); + mvec.push_back(M); + } + break; + } + + case 51: // reg: Load(reg) + case 52: // reg: Load(ptrreg) + SetOperandsForMemInstr(ChooseLoadInstruction( + subtreeRoot->getValue()->getType()), + mvec, subtreeRoot, target); + break; + + case 55: // reg: GetElemPtr(reg) + case 56: // reg: GetElemPtrIdx(reg,reg) + // If the GetElemPtr was folded into the user (parent), it will be + // caught above. For other cases, we have to compute the address. + SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target); + break; + + case 57: // reg: Alloca: Implement as 1 instruction: + { // add %fp, offsetFromFP -> result + AllocationInst* instr = + cast(subtreeRoot->getInstruction()); + unsigned tsize = + target.getTargetData().getTypeSize(instr->getAllocatedType()); + assert(tsize != 0); + CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec); + break; + } + + case 58: // reg: Alloca(reg): Implement as 3 instructions: + // mul num, typeSz -> tmp + // sub %sp, tmp -> %sp + { // add %sp, frameSizeBelowDynamicArea -> result + AllocationInst* instr = + cast(subtreeRoot->getInstruction()); + const Type* eltType = instr->getAllocatedType(); + + // If #elements is constant, use simpler code for fixed-size allocas + int tsize = (int) target.getTargetData().getTypeSize(eltType); + Value* numElementsVal = NULL; + bool isArray = instr->isArrayAllocation(); + + if (!isArray || isa(numElementsVal = instr->getArraySize())) { + // total size is constant: generate code for fixed-size alloca + unsigned numElements = isArray? + cast(numElementsVal)->getValue() : 1; + CreateCodeForFixedSizeAlloca(target, instr, tsize, + numElements, mvec); + } else { + // total size is not constant. + CreateCodeForVariableSizeAlloca(target, instr, tsize, + numElementsVal, mvec); + } + break; + } + + case 61: // reg: Call + { // Generate a direct (CALL) or indirect (JMPL) call. + // Mark the return-address register, the indirection + // register (for indirect calls), the operands of the Call, + // and the return value (if any) as implicit operands + // of the machine instruction. + // + // If this is a varargs function, floating point arguments + // have to passed in integer registers so insert + // copy-float-to-int instructions for each float operand. + // + CallInst *callInstr = cast(subtreeRoot->getInstruction()); + Value *callee = callInstr->getCalledValue(); + Function* calledFunc = dyn_cast(callee); + + // Check if this is an intrinsic function that needs a special code + // sequence (e.g., va_start). Indirect calls cannot be special. + // + bool specialIntrinsic = false; + Intrinsic::ID iid; + if (calledFunc && (iid=(Intrinsic::ID)calledFunc->getIntrinsicID())) + specialIntrinsic = CodeGenIntrinsic(iid, *callInstr, target, mvec); + + // If not, generate the normal call sequence for the function. + // This can also handle any intrinsics that are just function calls. + // + if (! specialIntrinsic) { + Function* currentFunc = callInstr->getParent()->getParent(); + MachineFunction& MF = MachineFunction::get(currentFunc); + MachineCodeForInstruction& mcfi = + MachineCodeForInstruction::get(callInstr); + const SparcV9RegInfo& regInfo = + (SparcV9RegInfo&) *target.getRegInfo(); + const TargetFrameInfo& frameInfo = *target.getFrameInfo(); + + // Create hidden virtual register for return address with type void* + TmpInstruction* retAddrReg = + new TmpInstruction(mcfi, PointerType::get(Type::VoidTy), callInstr); + + // Generate the machine instruction and its operands. + // Use CALL for direct function calls; this optimistically assumes + // the PC-relative address fits in the CALL address field (22 bits). + // Use JMPL for indirect calls. + // This will be added to mvec later, after operand copies. + // + MachineInstr* callMI; + if (calledFunc) // direct function call + callMI = BuildMI(V9::CALL, 1).addPCDisp(callee); + else // indirect function call + callMI = (BuildMI(V9::JMPLCALLi,3).addReg(callee) + .addSImm((int64_t)0).addRegDef(retAddrReg)); + + const FunctionType* funcType = + cast(cast(callee->getType()) + ->getElementType()); + bool isVarArgs = funcType->isVarArg(); + bool noPrototype = isVarArgs && funcType->getNumParams() == 0; + + // Use a descriptor to pass information about call arguments + // to the register allocator. This descriptor will be "owned" + // and freed automatically when the MachineCodeForInstruction + // object for the callInstr goes away. + CallArgsDescriptor* argDesc = + new CallArgsDescriptor(callInstr, retAddrReg,isVarArgs,noPrototype); + assert(callInstr->getOperand(0) == callee + && "This is assumed in the loop below!"); + + // Insert sign-extension instructions for small signed values, + // if this is an unknown function (i.e., called via a funcptr) + // or an external one (i.e., which may not be compiled by llc). + // + if (calledFunc == NULL || calledFunc->isExternal()) { + for (unsigned i=1, N=callInstr->getNumOperands(); i < N; ++i) { + Value* argVal = callInstr->getOperand(i); + const Type* argType = argVal->getType(); + if (argType->isIntegral() && argType->isSigned()) { + unsigned argSize = target.getTargetData().getTypeSize(argType); + if (argSize <= 4) { + // create a temporary virtual reg. to hold the sign-extension + TmpInstruction* argExtend = new TmpInstruction(mcfi, argVal); + + // sign-extend argVal and put the result in the temporary reg. + CreateSignExtensionInstructions + (target, currentFunc, argVal, argExtend, + 8*argSize, mvec, mcfi); + + // replace argVal with argExtend in CallArgsDescriptor + argDesc->getArgInfo(i-1).replaceArgVal(argExtend); + } + } + } + } + + // Insert copy instructions to get all the arguments into + // all the places that they need to be. + // + for (unsigned i=1, N=callInstr->getNumOperands(); i < N; ++i) { + int argNo = i-1; + CallArgInfo& argInfo = argDesc->getArgInfo(argNo); + Value* argVal = argInfo.getArgVal(); // don't use callInstr arg here + const Type* argType = argVal->getType(); + unsigned regType = regInfo.getRegTypeForDataType(argType); + unsigned argSize = target.getTargetData().getTypeSize(argType); + int regNumForArg = SparcV9RegInfo::getInvalidRegNum(); + unsigned regClassIDOfArgReg; + + // Check for FP arguments to varargs functions. + // Any such argument in the first $K$ args must be passed in an + // integer register. If there is no prototype, it must also + // be passed as an FP register. + // K = #integer argument registers. + bool isFPArg = argVal->getType()->isFloatingPoint(); + if (isVarArgs && isFPArg) { + + if (noPrototype) { + // It is a function with no prototype: pass value + // as an FP value as well as a varargs value. The FP value + // may go in a register or on the stack. The copy instruction + // to the outgoing reg/stack is created by the normal argument + // handling code since this is the "normal" passing mode. + // + regNumForArg = regInfo.regNumForFPArg(regType, + false, false, argNo, + regClassIDOfArgReg); + if (regNumForArg == regInfo.getInvalidRegNum()) + argInfo.setUseStackSlot(); + else + argInfo.setUseFPArgReg(); + } + + // If this arg. is in the first $K$ regs, add special copy- + // float-to-int instructions to pass the value as an int. + // To check if it is in the first $K$, get the register + // number for the arg #i. These copy instructions are + // generated here because they are extra cases and not needed + // for the normal argument handling (some code reuse is + // possible though -- later). + // + int copyRegNum = regInfo.regNumForIntArg(false, false, argNo, + regClassIDOfArgReg); + if (copyRegNum != regInfo.getInvalidRegNum()) { + // Create a virtual register to represent copyReg. Mark + // this vreg as being an implicit operand of the call MI + const Type* loadTy = (argType == Type::FloatTy + ? Type::IntTy : Type::LongTy); + TmpInstruction* argVReg = new TmpInstruction(mcfi, loadTy, + argVal, NULL, + "argRegCopy"); + callMI->addImplicitRef(argVReg); + + // Get a temp stack location to use to copy + // float-to-int via the stack. + // + // FIXME: For now, we allocate permanent space because + // the stack frame manager does not allow locals to be + // allocated (e.g., for alloca) after a temp is + // allocated! + // + // int tmpOffset = MF.getInfo()->pushTempValue(argSize); + int tmpOffset = MF.getInfo()->allocateLocalVar(argVReg); + + // Generate the store from FP reg to stack + unsigned StoreOpcode = ChooseStoreInstruction(argType); + M = BuildMI(convertOpcodeFromRegToImm(StoreOpcode), 3) + .addReg(argVal).addMReg(regInfo.getFramePointer()) + .addSImm(tmpOffset); + mvec.push_back(M); + + // Generate the load from stack to int arg reg + unsigned LoadOpcode = ChooseLoadInstruction(loadTy); + M = BuildMI(convertOpcodeFromRegToImm(LoadOpcode), 3) + .addMReg(regInfo.getFramePointer()).addSImm(tmpOffset) + .addReg(argVReg, MachineOperand::Def); + + // Mark operand with register it should be assigned + // both for copy and for the callMI + M->SetRegForOperand(M->getNumOperands()-1, copyRegNum); + callMI->SetRegForImplicitRef(callMI->getNumImplicitRefs()-1, + copyRegNum); + mvec.push_back(M); + + // Add info about the argument to the CallArgsDescriptor + argInfo.setUseIntArgReg(); + argInfo.setArgCopy(copyRegNum); + } else { + // Cannot fit in first $K$ regs so pass arg on stack + argInfo.setUseStackSlot(); + } + } else if (isFPArg) { + // Get the outgoing arg reg to see if there is one. + regNumForArg = regInfo.regNumForFPArg(regType, false, false, + argNo, regClassIDOfArgReg); + if (regNumForArg == regInfo.getInvalidRegNum()) + argInfo.setUseStackSlot(); + else { + argInfo.setUseFPArgReg(); + regNumForArg =regInfo.getUnifiedRegNum(regClassIDOfArgReg, + regNumForArg); + } + } else { + // Get the outgoing arg reg to see if there is one. + regNumForArg = regInfo.regNumForIntArg(false,false, + argNo, regClassIDOfArgReg); + if (regNumForArg == regInfo.getInvalidRegNum()) + argInfo.setUseStackSlot(); + else { + argInfo.setUseIntArgReg(); + regNumForArg =regInfo.getUnifiedRegNum(regClassIDOfArgReg, + regNumForArg); + } + } + + // + // Now insert copy instructions to stack slot or arg. register + // + if (argInfo.usesStackSlot()) { + // Get the stack offset for this argument slot. + // FP args on stack are right justified so adjust offset! + // int arguments are also right justified but they are + // always loaded as a full double-word so the offset does + // not need to be adjusted. + int argOffset = frameInfo.getOutgoingArgOffset(MF, argNo); + if (argType->isFloatingPoint()) { + unsigned slotSize = frameInfo.getSizeOfEachArgOnStack(); + assert(argSize <= slotSize && "Insufficient slot size!"); + argOffset += slotSize - argSize; + } + + // Now generate instruction to copy argument to stack + MachineOpCode storeOpCode = + (argType->isFloatingPoint() + ? ((argSize == 4)? V9::STFi : V9::STDFi) : V9::STXi); + + M = BuildMI(storeOpCode, 3).addReg(argVal) + .addMReg(regInfo.getStackPointer()).addSImm(argOffset); + mvec.push_back(M); + } + else if (regNumForArg != regInfo.getInvalidRegNum()) { + + // Create a virtual register to represent the arg reg. Mark + // this vreg as being an implicit operand of the call MI. + TmpInstruction* argVReg = + new TmpInstruction(mcfi, argVal, NULL, "argReg"); + + callMI->addImplicitRef(argVReg); + + // Generate the reg-to-reg copy into the outgoing arg reg. + // -- For FP values, create a FMOVS or FMOVD instruction + // -- For non-FP values, create an add-with-0 instruction + if (argType->isFloatingPoint()) + M=(BuildMI(argType==Type::FloatTy? V9::FMOVS :V9::FMOVD,2) + .addReg(argVal).addReg(argVReg, MachineOperand::Def)); + else + M = (BuildMI(ChooseAddInstructionByType(argType), 3) + .addReg(argVal).addSImm((int64_t) 0) + .addReg(argVReg, MachineOperand::Def)); + + // Mark the operand with the register it should be assigned + M->SetRegForOperand(M->getNumOperands()-1, regNumForArg); + callMI->SetRegForImplicitRef(callMI->getNumImplicitRefs()-1, + regNumForArg); + + mvec.push_back(M); + } + else + assert(argInfo.getArgCopy() != regInfo.getInvalidRegNum() && + "Arg. not in stack slot, primary or secondary register?"); + } + + // add call instruction and delay slot before copying return value + mvec.push_back(callMI); + mvec.push_back(BuildMI(V9::NOP, 0)); + + // Add the return value as an implicit ref. The call operands + // were added above. Also, add code to copy out the return value. + // This is always register-to-register for int or FP return values. + // + if (callInstr->getType() != Type::VoidTy) { + // Get the return value reg. + const Type* retType = callInstr->getType(); + + int regNum = (retType->isFloatingPoint() + ? (unsigned) SparcV9FloatRegClass::f0 + : (unsigned) SparcV9IntRegClass::o0); + unsigned regClassID = regInfo.getRegClassIDOfType(retType); + regNum = regInfo.getUnifiedRegNum(regClassID, regNum); + + // Create a virtual register to represent it and mark + // this vreg as being an implicit operand of the call MI + TmpInstruction* retVReg = + new TmpInstruction(mcfi, callInstr, NULL, "argReg"); + + callMI->addImplicitRef(retVReg, /*isDef*/ true); + + // Generate the reg-to-reg copy from the return value reg. + // -- For FP values, create a FMOVS or FMOVD instruction + // -- For non-FP values, create an add-with-0 instruction + if (retType->isFloatingPoint()) + M = (BuildMI(retType==Type::FloatTy? V9::FMOVS : V9::FMOVD, 2) + .addReg(retVReg).addReg(callInstr, MachineOperand::Def)); + else + M = (BuildMI(ChooseAddInstructionByType(retType), 3) + .addReg(retVReg).addSImm((int64_t) 0) + .addReg(callInstr, MachineOperand::Def)); + + // Mark the operand with the register it should be assigned + // Also mark the implicit ref of the call defining this operand + M->SetRegForOperand(0, regNum); + callMI->SetRegForImplicitRef(callMI->getNumImplicitRefs()-1,regNum); + + mvec.push_back(M); + } + + // For the CALL instruction, the ret. addr. reg. is also implicit + if (isa(callee)) + callMI->addImplicitRef(retAddrReg, /*isDef*/ true); + + MF.getInfo()->popAllTempValues(); // free temps used for this inst + } + + break; + } + + case 62: // reg: Shl(reg, reg) + { + Value* argVal1 = subtreeRoot->leftChild()->getValue(); + Value* argVal2 = subtreeRoot->rightChild()->getValue(); + Instruction* shlInstr = subtreeRoot->getInstruction(); + + const Type* opType = argVal1->getType(); + assert((opType->isInteger() || isa(opType)) && + "Shl unsupported for other types"); + unsigned opSize = target.getTargetData().getTypeSize(opType); + + CreateShiftInstructions(target, shlInstr->getParent()->getParent(), + (opSize > 4)? V9::SLLXr6:V9::SLLr5, + argVal1, argVal2, 0, shlInstr, mvec, + MachineCodeForInstruction::get(shlInstr)); + break; + } + + case 63: // reg: Shr(reg, reg) + { + const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); + assert((opType->isInteger() || isa(opType)) && + "Shr unsupported for other types"); + unsigned opSize = target.getTargetData().getTypeSize(opType); + Add3OperandInstr(opType->isSigned() + ? (opSize > 4? V9::SRAXr6 : V9::SRAr5) + : (opSize > 4? V9::SRLXr6 : V9::SRLr5), + subtreeRoot, mvec); + break; + } + + case 64: // reg: Phi(reg,reg) + break; // don't forward the value + + case 65: // reg: VANext(reg): the va_next(va_list, type) instruction + { // Increment the va_list pointer register according to the type. + // All LLVM argument types are <= 64 bits, so use one doubleword. + Instruction* vaNextI = subtreeRoot->getInstruction(); + assert(target.getTargetData().getTypeSize(vaNextI->getType()) <= 8 && + "We assumed that all LLVM parameter types <= 8 bytes!"); + int argSize = target.getFrameInfo()->getSizeOfEachArgOnStack(); + mvec.push_back(BuildMI(V9::ADDi, 3).addReg(vaNextI->getOperand(0)). + addSImm(argSize).addRegDef(vaNextI)); + break; + } + + case 66: // reg: VAArg (reg): the va_arg instruction + { // Load argument from stack using current va_list pointer value. + // Use 64-bit load for all non-FP args, and LDDF or double for FP. + Instruction* vaArgI = subtreeRoot->getInstruction(); + MachineOpCode loadOp = (vaArgI->getType()->isFloatingPoint() + ? (vaArgI->getType() == Type::FloatTy + ? V9::LDFi : V9::LDDFi) + : V9::LDXi); + mvec.push_back(BuildMI(loadOp, 3).addReg(vaArgI->getOperand(0)). + addSImm(0).addRegDef(vaArgI)); + break; + } + + case 71: // reg: VReg + case 72: // reg: Constant + break; // don't forward the value + + default: + assert(0 && "Unrecognized BURG rule"); + break; + } + } + + if (forwardOperandNum >= 0) { + // We did not generate a machine instruction but need to use operand. + // If user is in the same tree, replace Value in its machine operand. + // If not, insert a copy instruction which should get coalesced away + // by register allocation. + if (subtreeRoot->parent() != NULL) + ForwardOperand(subtreeRoot, subtreeRoot->parent(), forwardOperandNum); + else { + std::vector minstrVec; + Instruction* instr = subtreeRoot->getInstruction(); + CreateCopyInstructionsByType(target, + instr->getParent()->getParent(), + instr->getOperand(forwardOperandNum), + instr, minstrVec, + MachineCodeForInstruction::get(instr)); + assert(minstrVec.size() > 0); + mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); + } + } + + if (maskUnsignedResult) { + // If result is unsigned and smaller than int reg size, + // we need to clear high bits of result value. + assert(forwardOperandNum < 0 && "Need mask but no instruction generated"); + Instruction* dest = subtreeRoot->getInstruction(); + if (dest->getType()->isUnsigned()) { + unsigned destSize=target.getTargetData().getTypeSize(dest->getType()); + if (destSize <= 4) { + // Mask high 64 - N bits, where N = 4*destSize. + + // Use a TmpInstruction to represent the + // intermediate result before masking. Since those instructions + // have already been generated, go back and substitute tmpI + // for dest in the result position of each one of them. + // + MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(dest); + TmpInstruction *tmpI = new TmpInstruction(mcfi, dest->getType(), + dest, NULL, "maskHi"); + Value* srlArgToUse = tmpI; + + unsigned numSubst = 0; + for (unsigned i=0, N=mvec.size(); i < N; ++i) { + + // Make sure we substitute all occurrences of dest in these instrs. + // Otherwise, we will have bogus code. + bool someArgsWereIgnored = false; + + // Make sure not to substitute an upwards-exposed use -- that would + // introduce a use of `tmpI' with no preceding def. Therefore, + // substitute a use or def-and-use operand only if a previous def + // operand has already been substituted (i.e., numSubst > 0). + // + numSubst += mvec[i]->substituteValue(dest, tmpI, + /*defsOnly*/ numSubst == 0, + /*notDefsAndUses*/ numSubst > 0, + someArgsWereIgnored); + assert(!someArgsWereIgnored && + "Operand `dest' exists but not replaced: probably bogus!"); + } + assert(numSubst > 0 && "Operand `dest' not replaced: probably bogus!"); + + // Left shift 32-N if size (N) is less than 32 bits. + // Use another tmp. virtual register to represent this result. + if (destSize < 4) { + srlArgToUse = new TmpInstruction(mcfi, dest->getType(), + tmpI, NULL, "maskHi2"); + mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpI) + .addZImm(8*(4-destSize)) + .addReg(srlArgToUse, MachineOperand::Def)); + } + + // Logical right shift 32-N to get zero extension in top 64-N bits. + mvec.push_back(BuildMI(V9::SRLi5, 3).addReg(srlArgToUse) + .addZImm(8*(4-destSize)) + .addReg(dest, MachineOperand::Def)); + + } else if (destSize < 8) { + assert(0 && "Unsupported type size: 32 < size < 64 bits"); + } + } + } + } + + } // End llvm namespace + + //==------------------------------------------------------------------------==// + // Class V9ISel Implementation + //==------------------------------------------------------------------------==// + + bool V9ISel::runOnFunction(Function &F) { + // First pass - Walk the function, lowering any calls to intrinsic functions + // which the instruction selector cannot handle. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) + if (CallInst *CI = dyn_cast(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::not_intrinsic: + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: + // We directly implement these intrinsics. Note that this knowledge + // is incestuously entangled with the code in + // SparcInstrSelection.cpp and must be updated when it is updated. + // Since ALL of the code in this library is incestuously intertwined + // with it already and sparc specific, we will live with this. + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + Target.getIntrinsicLowering().LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + } + + // Build the instruction trees to be given as inputs to BURG. + InstrForest instrForest(&F); + if (SelectDebugLevel >= Select_DebugInstTrees) { + std::cerr << "\n\n*** Input to instruction selection for function " + << F.getName() << "\n\n" << F + << "\n\n*** Instruction trees for function " + << F.getName() << "\n\n"; + instrForest.dump(); + } + + // Invoke BURG instruction selection for each tree + for (InstrForest::const_root_iterator RI = instrForest.roots_begin(); + RI != instrForest.roots_end(); ++RI) { + InstructionNode* basicNode = *RI; + assert(basicNode->parent() == NULL && "A `root' node has a parent?"); + + // Invoke BURM to label each tree node with a state + burm_label(basicNode); + if (SelectDebugLevel >= Select_DebugBurgTrees) { + printcover(basicNode, 1, 0); + std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n"; + printMatches(basicNode); + } + + // Then recursively walk the tree to select instructions + SelectInstructionsForTree(basicNode, /*goalnt*/1); + } + + // Create the MachineBasicBlocks and add all of the MachineInstrs + // defined in the MachineCodeForInstruction objects to the MachineBasicBlocks. + MachineFunction &MF = MachineFunction::get(&F); + std::map MBBMap; + for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { + MachineBasicBlock *MBB = new MachineBasicBlock(BI); + MF.getBasicBlockList().push_back(MBB); + MBBMap[BI] = MBB; + + for (BasicBlock::iterator II = BI->begin(); II != BI->end(); ++II) { + MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(II); + MBB->insert(MBB->end(), mvec.begin(), mvec.end()); + } + } + + // Initialize Machine-CFG for the function. + for (MachineFunction::iterator i = MF.begin (), e = MF.end (); i != e; ++i) { + MachineBasicBlock &MBB = *i; + const BasicBlock *BB = MBB.getBasicBlock (); + // for each successor S of BB, add MBBMap[S] as a successor of MBB. + for (succ_const_iterator si = succ_begin(BB), se = succ_end(BB); si != se; + ++si) { + MachineBasicBlock *succMBB = MBBMap[*si]; + assert (succMBB && "Can't find MachineBasicBlock for this successor"); + MBB.addSuccessor (succMBB); + } + } + + // Insert phi elimination code + InsertCodeForPhis(F); + + if (SelectDebugLevel >= Select_PrintMachineCode) { + std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n"; + MachineFunction::get(&F).dump(); + } + + return true; + } + + /// InsertCodeForPhis - This method inserts Phi elimination code for + /// all Phi nodes in the given function. After this method is called, + /// the Phi nodes still exist in the LLVM code, but copies are added to the + /// machine code. + /// + void V9ISel::InsertCodeForPhis(Function &F) { + // Iterate over every Phi node PN in F: + MachineFunction &MF = MachineFunction::get(&F); + for (MachineFunction::iterator BB = MF.begin(); BB != MF.end(); ++BB) { + for (BasicBlock::const_iterator IIt = BB->getBasicBlock()->begin(); + const PHINode *PN = dyn_cast(IIt); ++IIt) { + // Create a new temporary register to hold the result of the Phi copy. + // The leak detector shouldn't track these nodes. They are not garbage, + // even though their parent field is never filled in. + Value *PhiCpRes = new PHINode(PN->getType(), PN->getName() + ":PhiCp"); + LeakDetector::removeGarbageObject(PhiCpRes); + + // For each of PN's incoming values, insert a copy in the corresponding + // predecessor block. + MachineCodeForInstruction &MCforPN = MachineCodeForInstruction::get (PN); + for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) { + std::vector mvec, CpVec; + Target.getRegInfo()->cpValue2Value(PN->getIncomingValue(i), + PhiCpRes, mvec); + for (std::vector::iterator MI=mvec.begin(); + MI != mvec.end(); ++MI) { + std::vector CpVec2 = + FixConstantOperandsForInstr(const_cast(PN), *MI, Target); + CpVec2.push_back(*MI); + CpVec.insert(CpVec.end(), CpVec2.begin(), CpVec2.end()); + } + // Insert the copy instructions into the predecessor BB. + InsertPhiElimInstructions(PN->getIncomingBlock(i), CpVec); + MCforPN.insert (MCforPN.end (), CpVec.begin (), CpVec.end ()); + } + // Insert a copy instruction from PhiCpRes to PN. + std::vector mvec; + Target.getRegInfo()->cpValue2Value(PhiCpRes, const_cast(PN), + mvec); + BB->insert(BB->begin(), mvec.begin(), mvec.end()); + MCforPN.insert (MCforPN.end (), mvec.begin (), mvec.end ()); + } // for each Phi Instr in BB + } // for all BBs in function + } + + /// InsertPhiElimInstructions - Inserts the instructions in CpVec into the + /// MachineBasicBlock corresponding to BB, just before its terminator + /// instruction. This is used by InsertCodeForPhis() to insert copies, above. + /// + void V9ISel::InsertPhiElimInstructions(BasicBlock *BB, + const std::vector& CpVec) + { + Instruction *TermInst = (Instruction*)BB->getTerminator(); + MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst); + MachineInstr *FirstMIOfTerm = MC4Term.front(); + assert (FirstMIOfTerm && "No Machine Instrs for terminator"); + + MachineBasicBlock *MBB = FirstMIOfTerm->getParent(); + assert(MBB && "Machine BB for predecessor's terminator not found"); + MachineBasicBlock::iterator MCIt = FirstMIOfTerm; + assert(MCIt != MBB->end() && "Start inst of terminator not found"); + + // Insert the copy instructions just before the first machine instruction + // generated for the terminator. + MBB->insert(MCIt, CpVec.begin(), CpVec.end()); + } + + /// SelectInstructionsForTree - Recursively walk the tree to select + /// instructions. Do this top-down so that child instructions can exploit + /// decisions made at the child instructions. + /// + /// E.g., if br(setle(reg,const)) decides the constant is 0 and uses + /// a branch-on-integer-register instruction, then the setle node + /// can use that information to avoid generating the SUBcc instruction. + /// + /// Note that this cannot be done bottom-up because setle must do this + /// only if it is a child of the branch (otherwise, the result of setle + /// may be used by multiple instructions). + /// + void V9ISel::SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt) { + // Get the rule that matches this node. + int ruleForNode = burm_rule(treeRoot->state, goalnt); + + if (ruleForNode == 0) { + std::cerr << "Could not match instruction tree for instr selection\n"; + abort(); + } + + // Get this rule's non-terminals and the corresponding child nodes (if any) + short *nts = burm_nts[ruleForNode]; + + // First, select instructions for the current node and rule. + // (If this is a list node, not an instruction, then skip this step). + // This function is specific to the target architecture. + if (treeRoot->opLabel != VRegListOp) { + std::vector minstrVec; + InstructionNode* instrNode = (InstructionNode*)treeRoot; + assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); + GetInstructionsByRule(instrNode, ruleForNode, nts, Target, minstrVec); + MachineCodeForInstruction &mvec = + MachineCodeForInstruction::get(instrNode->getInstruction()); + mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); + } + + // Then, recursively compile the child nodes, if any. + // + if (nts[0]) { + // i.e., there is at least one kid + InstrTreeNode* kids[2]; + int currentRule = ruleForNode; + burm_kids(treeRoot, currentRule, kids); + + // First skip over any chain rules so that we don't visit + // the current node again. + while (ThisIsAChainRule(currentRule)) { + currentRule = burm_rule(treeRoot->state, nts[0]); + nts = burm_nts[currentRule]; + burm_kids(treeRoot, currentRule, kids); + } + + // Now we have the first non-chain rule so we have found + // the actual child nodes. Recursively compile them. + for (unsigned i = 0; nts[i]; i++) { + assert(i < 2); + InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); + if (nodeType == InstrTreeNode::NTVRegListNode || + nodeType == InstrTreeNode::NTInstructionNode) + SelectInstructionsForTree(kids[i], nts[i]); + } + } + + // Finally, do any post-processing on this node after its children + // have been translated. + if (treeRoot->opLabel != VRegListOp) + PostprocessMachineCodeForTree((InstructionNode*)treeRoot, ruleForNode, nts); + } + + /// PostprocessMachineCodeForTree - Apply any final cleanups to + /// machine code for the root of a subtree after selection for all its + /// children has been completed. + /// + void V9ISel::PostprocessMachineCodeForTree(InstructionNode *instrNode, + int ruleForNode, short *nts) { + // Fix up any constant operands in the machine instructions to either + // use an immediate field or to load the constant into a register. + // Walk backwards and use direct indexes to allow insertion before current. + Instruction* vmInstr = instrNode->getInstruction(); + MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(vmInstr); + for (unsigned i = mvec.size(); i != 0; --i) { + std::vector loadConstVec = + FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target); + mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end()); + } + } + + /// createSparcV9BurgInstSelector - Creates and returns a new SparcV9 + /// BURG-based instruction selection pass. + /// + FunctionPass *llvm::createSparcV9BurgInstSelector(TargetMachine &TM) { + return new V9ISel(TM); + } Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.h diff -c /dev/null llvm/lib/Target/SparcV9/SparcV9BurgISel.h:1.1 *** /dev/null Wed Aug 4 02:29:02 2004 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.h Wed Aug 4 02:28:51 2004 *************** *** 0 **** --- 1,56 ---- + //===-- SparcV9BurgISel.h ---------------------------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Global functions exposed by the BURG-based instruction selector + // for the SparcV9 target. + // + //===----------------------------------------------------------------------===// + + #ifndef SPARCV9BURGISEL_H + #define SPARCV9BURGISEL_H + + //#include "llvm/DerivedTypes.h" + //#include "llvm/Instruction.h" + //#include "SparcV9Internals.h" + + namespace llvm { + + class Constant; + class Instruction; + class TargetMachine; + class Function; + class Value; + class MachineInstr; + class MachineCodeForInstruction; + class FunctionPass; + + /// ConstantMayNotFitInImmedField - Test if this constant may not fit in the + /// immediate field of the machine instructions (probably) generated for this + /// instruction. + /// + bool ConstantMayNotFitInImmedField (const Constant *CV, const Instruction *I); + + /// CreateCodeToLoadConst - Create an instruction sequence to put the + /// constant `val' into the virtual register `dest'. `val' may be a Constant + /// or a GlobalValue, viz., the constant address of a global variable or + /// function. The generated instructions are returned in `mvec'. Any temp. + /// registers (TmpInstruction) created are recorded in mcfi. + /// + void CreateCodeToLoadConst (const TargetMachine &target, Function *F, + Value *val, Instruction *dest, std::vector &mvec, + MachineCodeForInstruction &mcfi); + + /// createSparcV9BurgInstSelector - Creates and returns a new SparcV9 + /// BURG-based instruction selection pass. + /// + FunctionPass *createSparcV9BurgInstSelector(TargetMachine &TM); + + } // End llvm namespace + + #endif Index: llvm/lib/Target/SparcV9/Makefile diff -u llvm/lib/Target/SparcV9/Makefile:1.42 llvm/lib/Target/SparcV9/Makefile:1.43 --- llvm/lib/Target/SparcV9/Makefile:1.42 Sun Apr 25 02:04:49 2004 +++ llvm/lib/Target/SparcV9/Makefile Wed Aug 4 02:28:51 2004 @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../.. LIBRARYNAME = sparcv9 -DIRS = InstrSelection RegAlloc LiveVar +DIRS = RegAlloc LiveVar ExtraSource = SparcV9.burm.cpp From gaeke at cs.uiuc.edu Wed Aug 4 02:29:15 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9TmpInstr.cpp SparcV9TmpInstr.h Message-ID: <200408040729.CAA13670@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TmpInstr.cpp added (r1.1) SparcV9TmpInstr.h added (r1.1) --- Log message: Add a new file containing just TmpInstruction and its implementation. Many other pieces of the SparcV9 backend want to use TmpInstruction, but don't need any other instruction selector baggage. --- Diffs of the changes: (+132 -0) Index: llvm/lib/Target/SparcV9/SparcV9TmpInstr.cpp diff -c /dev/null llvm/lib/Target/SparcV9/SparcV9TmpInstr.cpp:1.1 *** /dev/null Wed Aug 4 02:29:14 2004 --- llvm/lib/Target/SparcV9/SparcV9TmpInstr.cpp Wed Aug 4 02:29:04 2004 *************** *** 0 **** --- 1,60 ---- + //===- SparcV9TmpInstr.cpp - SparcV9 Intermediate Value class -------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Methods of class for temporary intermediate values used within the current + // SparcV9 backend. + // + //===----------------------------------------------------------------------===// + + #include "SparcV9TmpInstr.h" + #include "Support/LeakDetector.h" + + namespace llvm { + + TmpInstruction::TmpInstruction(Value *s1, Value *s2, const std::string &name) + : Instruction(s1->getType(), Instruction::UserOp1, name) { + Operands.push_back(Use(s1, this)); // s1 must be non-null + if (s2) + Operands.push_back(Use(s2, this)); + + // TmpInstructions should not be garbage checked. + LeakDetector::removeGarbageObject(this); + } + + TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, + Value *s1, Value *s2, const std::string &name) + : Instruction(s1->getType(), Instruction::UserOp1, name) { + mcfi.addTemp(this); + + Operands.push_back(Use(s1, this)); // s1 must be non-null + if (s2) + Operands.push_back(Use(s2, this)); + + // TmpInstructions should not be garbage checked. + LeakDetector::removeGarbageObject(this); + } + + // Constructor that requires the type of the temporary to be specified. + // Both S1 and S2 may be NULL. + TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, + const Type *Ty, Value *s1, Value* s2, + const std::string &name) + : Instruction(Ty, Instruction::UserOp1, name) { + mcfi.addTemp(this); + + if (s1) + Operands.push_back(Use(s1, this)); + if (s2) + Operands.push_back(Use(s2, this)); + + // TmpInstructions should not be garbage checked. + LeakDetector::removeGarbageObject(this); + } + + } // end namespace llvm Index: llvm/lib/Target/SparcV9/SparcV9TmpInstr.h diff -c /dev/null llvm/lib/Target/SparcV9/SparcV9TmpInstr.h:1.1 *** /dev/null Wed Aug 4 02:29:15 2004 --- llvm/lib/Target/SparcV9/SparcV9TmpInstr.h Wed Aug 4 02:29:04 2004 *************** *** 0 **** --- 1,72 ---- + //===-- SparcV9TmpInstr.h ---------------------------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Definition of class for temporary intermediate values used within the current + // SparcV9 backend. + // + //===----------------------------------------------------------------------===// + + #ifndef SPARCV9TMPINSTR_H + #define SPARCV9TMPINSTR_H + + #include "llvm/Instruction.h" + #include "llvm/CodeGen/MachineCodeForInstruction.h" + + namespace llvm { + + /// TmpInstruction - This class represents temporary intermediate + /// values used within the SparcV9 machine code for an LLVM instruction. + /// + class TmpInstruction : public Instruction { + TmpInstruction(const TmpInstruction &TI) + : Instruction(TI.getType(), TI.getOpcode()) { + if (!TI.Operands.empty()) { + Operands.push_back(Use(TI.Operands[0], this)); + if (TI.Operands.size() == 2) + Operands.push_back(Use(TI.Operands[1], this)); + else + assert(0 && "Bad # operands to TmpInstruction!"); + } + } + public: + // Constructor that uses the type of S1 as the type of the temporary. + // s1 must be a valid value. s2 may be NULL. + TmpInstruction(MachineCodeForInstruction &mcfi, + Value *s1, Value *s2 = 0, const std::string &name = ""); + + // Constructor that uses the type of S1 as the type of the temporary, + // but does not require a MachineCodeForInstruction. + // s1 must be a valid value. s2 may be NULL. + TmpInstruction(Value *s1, Value *s2 = 0, const std::string &name = ""); + + // Constructor that requires the type of the temporary to be specified. + // Both S1 and S2 may be NULL. + TmpInstruction(MachineCodeForInstruction& mcfi, + const Type *Ty, Value *s1 = 0, Value* s2 = 0, + const std::string &name = ""); + + virtual Instruction *clone() const { + assert(0 && "Cannot clone TmpInstructions!"); + return 0; + } + virtual const char *getOpcodeName() const { return "TmpInstruction"; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const TmpInstruction *) { return true; } + static inline bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::UserOp1); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + + } // End llvm namespace + + #endif From gaeke at cs.uiuc.edu Wed Aug 4 02:29:38 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9InstrInfo.h Message-ID: <200408040729.CAA13756@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9InstrInfo.h updated: 1.8 -> 1.9 --- Log message: Add a Doxygen comment, and inline the constructor (which is now almost empty). --- Diffs of the changes: (+4 -1) Index: llvm/lib/Target/SparcV9/SparcV9InstrInfo.h diff -u llvm/lib/Target/SparcV9/SparcV9InstrInfo.h:1.8 llvm/lib/Target/SparcV9/SparcV9InstrInfo.h:1.9 --- llvm/lib/Target/SparcV9/SparcV9InstrInfo.h:1.8 Tue Jul 27 12:43:22 2004 +++ llvm/lib/Target/SparcV9/SparcV9InstrInfo.h Wed Aug 4 02:29:28 2004 @@ -25,10 +25,13 @@ namespace llvm { +/// SparcV9InstrInfo - TargetInstrInfo specialized for the SparcV9 target. +/// struct SparcV9InstrInfo : public TargetInstrInfo { const SparcV9RegisterInfo RI; public: - SparcV9InstrInfo(); + SparcV9InstrInfo() + : TargetInstrInfo(SparcV9MachineInstrDesc, V9::NUM_TOTAL_OPCODES) { } /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should From gaeke at cs.uiuc.edu Wed Aug 4 02:30:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:30:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp Message-ID: <200408040730.CAA13858@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9RegInfo.cpp updated: 1.132 -> 1.133 --- Log message: Include SparcV9TmpInstr.h instead of llvm/CodeGen/InstrSelection.h, to pick up the definition of class TmpInstruction. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp diff -u llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp:1.132 llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp:1.133 --- llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp:1.132 Thu Jul 29 12:11:35 2004 +++ llvm/lib/Target/SparcV9/SparcV9RegInfo.cpp Wed Aug 4 02:29:53 2004 @@ -14,7 +14,6 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionInfo.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "MachineInstrAnnot.h" @@ -27,6 +26,7 @@ #include "SparcV9RegClassInfo.h" #include "SparcV9RegInfo.h" #include "SparcV9TargetMachine.h" +#include "SparcV9TmpInstr.h" #include namespace llvm { From gaeke at cs.uiuc.edu Wed Aug 4 02:30:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:30:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Message-ID: <200408040730.CAA13861@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.157 -> 1.158 --- Log message: Include SparcV9TmpInstr.h instead of llvm/CodeGen/InstrSelection.h, to pick up the definition of class TmpInstruction. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.157 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.158 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.157 Thu Jul 29 12:11:37 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Wed Aug 4 02:29:53 2004 @@ -27,13 +27,13 @@ #include "RegClass.h" #include "../LiveVar/FunctionLiveVarInfo.h" #include "../SparcV9InstrInfo.h" +#include "../SparcV9TmpInstr.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionInfo.h" From gaeke at cs.uiuc.edu Wed Aug 4 02:29:50 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp Message-ID: <200408040729.CAA13798@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9PreSelection.cpp updated: 1.39 -> 1.40 --- Log message: Include SparcV9BurgISel.h, because PreSelection uses routines from within the SparcV9 BURG instruction selector. Eww! --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp diff -u llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.39 llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.40 --- llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.39 Thu Jul 29 12:11:35 2004 +++ llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp Wed Aug 4 02:29:40 2004 @@ -16,7 +16,7 @@ //===----------------------------------------------------------------------===// #include "SparcV9Internals.h" -#include "SparcV9InstrSelectionSupport.h" +#include "SparcV9BurgISel.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" From gaeke at cs.uiuc.edu Wed Aug 4 02:29:27 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9InstrForest.h SparcV9.burg.in Message-ID: <200408040729.CAA13714@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9InstrForest.h added (r1.1) SparcV9.burg.in updated: 1.12 -> 1.13 --- Log message: The InstrForest data type has moved from llvm/CodeGen/InstrForest.h to SparcV9InstrForest.h. --- Diffs of the changes: (+135 -1) Index: llvm/lib/Target/SparcV9/SparcV9InstrForest.h diff -c /dev/null llvm/lib/Target/SparcV9/SparcV9InstrForest.h:1.1 *** /dev/null Wed Aug 4 02:29:26 2004 --- llvm/lib/Target/SparcV9/SparcV9InstrForest.h Wed Aug 4 02:29:16 2004 *************** *** 0 **** --- 1,134 ---- + //===- SparcV9InstrForest.cpp - SparcV9 BURG Instruction Selector Trees ---===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // A forest of BURG instruction trees (class InstrForest) which represents + // a function to the BURG-based instruction selector, and a bunch of constants + // and declarations used by the generated BURG code. + // + //===----------------------------------------------------------------------===// + + #ifndef SPARCV9INSTRFOREST_H + #define SPARCV9INSTRFOREST_H + + #include "llvm/Instruction.h" + using namespace llvm; + + /// OpLabel values for special-case nodes created for instruction selection. + /// All op-labels not defined here are identical to the instruction + /// opcode returned by Instruction::getOpcode(). + /// + static const int + InvalidOp = -1, + VRegListOp = 97, + VRegNodeOp = 98, + ConstantNodeOp = 99, + LabelNodeOp = 100, + RetValueOp = 100 + Instruction::Ret, // 101 + BrCondOp = 100 + Instruction::Br, // 102 + BAndOp = 100 + Instruction::And, // 111 + BOrOp = 100 + Instruction::Or, // 112 + BXorOp = 100 + Instruction::Xor, // 113 + BNotOp = 200 + Instruction::Xor, // 213 + NotOp = 300 + Instruction::Xor, // 313 + SetCCOp = 100 + Instruction::SetEQ, // 114 + AllocaN = 100 + Instruction::Alloca, // 122 + LoadIdx = 100 + Instruction::Load, // 123 + GetElemPtrIdx = 100 + Instruction::GetElementPtr, // 125 + ToBoolTy = 100 + Instruction::Cast; // 127 + static const int + ToUByteTy = ToBoolTy + 1, + ToSByteTy = ToBoolTy + 2, + ToUShortTy = ToBoolTy + 3, + ToShortTy = ToBoolTy + 4, + ToUIntTy = ToBoolTy + 5, + ToIntTy = ToBoolTy + 6, + ToULongTy = ToBoolTy + 7, + ToLongTy = ToBoolTy + 8, + ToFloatTy = ToBoolTy + 9, + ToDoubleTy = ToBoolTy + 10, + ToArrayTy = ToBoolTy + 11, + ToPointerTy = ToBoolTy + 12; + + /// Data types needed by BURG + /// + typedef int OpLabel; + typedef int StateLabel; + + /// Declarations of data and functions created by BURG + /// + namespace llvm { + class InstrTreeNode; + }; + extern short* burm_nts[]; + extern StateLabel burm_label (InstrTreeNode* p); + extern StateLabel burm_state (OpLabel op, StateLabel leftState, + StateLabel rightState); + extern StateLabel burm_rule (StateLabel state, int goalNT); + extern InstrTreeNode** burm_kids (InstrTreeNode* p, int eruleno, + InstrTreeNode* kids[]); + extern void printcover (InstrTreeNode*, int, int); + extern void printtree (InstrTreeNode*); + extern int treecost (InstrTreeNode*, int, int); + extern void printMatches (InstrTreeNode*); + + namespace llvm { + + /// InstrTreeNode - A single tree node in the instruction tree used for + /// instruction selection via BURG. + /// + class InstrTreeNode { + InstrTreeNode(const InstrTreeNode &); // DO NOT IMPLEMENT + void operator=(const InstrTreeNode &); // DO NOT IMPLEMENT + public: + enum InstrTreeNodeType { NTInstructionNode, + NTVRegListNode, + NTVRegNode, + NTConstNode, + NTLabelNode }; + InstrTreeNode* LeftChild; + InstrTreeNode* RightChild; + InstrTreeNode* Parent; + OpLabel opLabel; + StateLabel state; + + protected: + InstrTreeNodeType treeNodeType; + Value* val; + + public: + InstrTreeNode(InstrTreeNodeType nodeType, Value* _val) + : treeNodeType(nodeType), val(_val) { + LeftChild = RightChild = Parent = 0; + opLabel = InvalidOp; + } + virtual ~InstrTreeNode() { + delete LeftChild; + delete RightChild; + } + InstrTreeNodeType getNodeType () const { return treeNodeType; } + Value* getValue () const { return val; } + inline OpLabel getOpLabel () const { return opLabel; } + inline InstrTreeNode *leftChild () const { return LeftChild; } + inline InstrTreeNode *parent () const { return Parent; } + + // If right child is a list node, recursively get its *left* child + inline InstrTreeNode* rightChild() const { + return (!RightChild ? 0 : + (RightChild->getOpLabel() == VRegListOp + ? RightChild->LeftChild : RightChild)); + } + void dump(int dumpChildren, int indent) const; + protected: + virtual void dumpNode(int indent) const = 0; + friend class InstrForest; + }; + + } // end namespace llvm. + + #endif Index: llvm/lib/Target/SparcV9/SparcV9.burg.in diff -u llvm/lib/Target/SparcV9/SparcV9.burg.in:1.12 llvm/lib/Target/SparcV9/SparcV9.burg.in:1.13 --- llvm/lib/Target/SparcV9/SparcV9.burg.in:1.12 Wed Feb 25 12:44:15 2004 +++ llvm/lib/Target/SparcV9/SparcV9.burg.in Wed Aug 4 02:29:16 2004 @@ -9,7 +9,7 @@ //===----------------------------------------------------------------------===*/ Xinclude -Xinclude +Xinclude "SparcV9InstrForest.h" typedef llvm::InstrTreeNode* NODEPTR_TYPE; Xdefine OP_LABEL(p) ((p)->opLabel) From gaeke at cs.uiuc.edu Wed Aug 4 02:30:15 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:30:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Message-ID: <200408040730.CAA13903@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.118 -> 1.119 --- Log message: Include SparcV9BurgISel.h, to pick up the definition of createSparcV9BurgInstSelector(). --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.118 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.119 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.118 Sat Jul 10 23:16:54 2004 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Wed Aug 4 02:30:04 2004 @@ -16,7 +16,6 @@ #include "llvm/Function.h" #include "llvm/PassManager.h" #include "llvm/Assembly/PrintModulePass.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrScheduling.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/CodeGen/MachineFunction.h" @@ -29,6 +28,7 @@ #include "MappingInfo.h" #include "SparcV9Internals.h" #include "SparcV9TargetMachine.h" +#include "SparcV9BurgISel.h" #include "Support/CommandLine.h" using namespace llvm; @@ -184,7 +184,7 @@ // so %fp+offset-8 and %fp+offset-16 are empty slots now! PM.add(createStackSlotsPass(*this)); - PM.add(createInstructionSelectionPass(*this)); + PM.add(createSparcV9BurgInstSelector(*this)); if (!DisableSched) PM.add(createInstructionSchedulingWithSSAPass(*this)); @@ -268,7 +268,7 @@ // Construct and initialize the MachineFunction object for this fn. PM.add(createMachineCodeConstructionPass(TM)); - PM.add(createInstructionSelectionPass(TM)); + PM.add(createSparcV9BurgInstSelector(TM)); if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n")); From gaeke at cs.uiuc.edu Wed Aug 4 02:29:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:29:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/InstrSelection/InstrForest.cpp InstrSelection.cpp InstrSelectionSupport.cpp Makefile Message-ID: <200408040729.CAA13626@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/InstrSelection: InstrForest.cpp (r1.57) removed InstrSelection.cpp (r1.84) removed InstrSelectionSupport.cpp (r1.70) removed Makefile (r1.5) removed --- Log message: All the SparcV9 BURG instruction selector pieces have been collected into the new file SparcV9BurgISel.cpp, with exposed interfaces in SparcV9BurgISel.h. The InstrSelection directory is now dead. --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Wed Aug 4 02:34:54 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:34:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstrAnnot.cpp Message-ID: <200408040734.CAA14316@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstrAnnot.cpp updated: 1.13 -> 1.14 --- Log message: Tighten up some whitespace. Include SparcV9TmpInstr.h to pick up the def. of TmpInstruction, instead of InstrSelection.h, which is dead. --- Diffs of the changes: (+4 -10) Index: llvm/lib/CodeGen/MachineInstrAnnot.cpp diff -u llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.13 llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.14 --- llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.13 Thu Jul 29 12:20:54 2004 +++ llvm/lib/CodeGen/MachineInstrAnnot.cpp Wed Aug 4 02:34:44 2004 @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #include "../Target/SparcV9/MachineInstrAnnot.h" -#include "llvm/CodeGen/InstrSelection.h" +#include "../Target/SparcV9/SparcV9TmpInstr.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/Instructions.h" #include "llvm/Type.h" @@ -27,8 +27,7 @@ ? NULL : _callInstr->getCalledValue()), retAddrReg(_retAddrReg), isVarArgs(_isVarArgs), - noPrototype(_noPrototype) -{ + noPrototype(_noPrototype) { unsigned int numArgs = callInstr->getNumOperands(); argInfoVec.reserve(numArgs); assert(callInstr->getOperand(0) == callInstr->getCalledValue() @@ -41,14 +40,10 @@ MachineCodeForInstruction::get(callInstr).setCallArgsDescriptor(this); } - -CallInst* -CallArgsDescriptor::getReturnValue() const -{ +CallInst *CallArgsDescriptor::getReturnValue() const { return (callInstr->getType() == Type::VoidTy? NULL : callInstr); } - // Mechanism to get the descriptor for a CALL MachineInstr. // We get the LLVM CallInstr from the ret. addr. register argument // of the CALL MachineInstr (which is explicit operand #3 for indirect @@ -58,8 +53,7 @@ // This is roundabout but avoids adding a new map or annotation just // to keep track of CallArgsDescriptors. // -CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr* MI) -{ +CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr* MI) { const TmpInstruction* retAddrReg = cast(isa(MI->getOperand(0).getVRegValue()) ? MI->getImplicitRef(MI->getNumImplicitRefs()-1) From gaeke at cs.uiuc.edu Wed Aug 4 02:35:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:35:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Message-ID: <200408040735.CAA14359@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: ModuloScheduling.cpp updated: 1.23 -> 1.24 --- Log message: Include SparcV9TmpInstr.h to pick up the def. of TmpInstruction, instead of InstrSelection.h, which is dead. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.23 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.24 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.23 Tue Aug 3 22:51:55 2004 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Wed Aug 4 02:34:57 2004 @@ -17,7 +17,6 @@ #include "ModuloScheduling.h" #include "llvm/Instructions.h" #include "llvm/Function.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/Passes.h" @@ -32,6 +31,7 @@ #include #include #include +#include "../../Target/SparcV9/SparcV9TmpInstr.h" #include "../../Target/SparcV9/SparcV9Internals.h" #include "../../Target/SparcV9/SparcV9RegisterInfo.h" using namespace llvm; From gaeke at cs.uiuc.edu Wed Aug 4 02:38:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:38:07 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/InstrForest.h InstrSelection.h Message-ID: <200408040738.CAA14715@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: InstrForest.h (r1.32) removed InstrSelection.h (r1.33) removed --- Log message: These headers have been moved/merged into other files. --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Wed Aug 4 02:39:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:39:02 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200408040739.CAA14859@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.53 -> 1.54 --- Log message: libsparcv9select is history --- Diffs of the changes: (+0 -1) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.53 llvm/tools/llc/Makefile:1.54 --- llvm/tools/llc/Makefile:1.53 Fri Jul 16 02:12:46 2004 +++ llvm/tools/llc/Makefile Wed Aug 4 02:38:52 2004 @@ -16,7 +16,6 @@ selectiondag \ sparcv9regalloc \ sched \ - sparcv9select \ codegen \ target.a \ sparcv9livevar \ From gaeke at cs.uiuc.edu Wed Aug 4 02:39:32 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 02:39:32 -0500 Subject: [llvm-commits] CVS: llvm/tools/lli/Makefile Message-ID: <200408040739.CAA14932@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: Makefile updated: 1.42 -> 1.43 --- Log message: sparcv9select is history --- Diffs of the changes: (+1 -1) Index: llvm/tools/lli/Makefile diff -u llvm/tools/lli/Makefile:1.42 llvm/tools/lli/Makefile:1.43 --- llvm/tools/lli/Makefile:1.42 Wed Feb 25 13:08:11 2004 +++ llvm/tools/lli/Makefile Wed Aug 4 02:39:21 2004 @@ -43,7 +43,7 @@ JITLIBS += sparcv9 ARCHLIBS += sched sparcv9livevar instrument.a profpaths \ bcwriter transforms.a ipo.a ipa.a datastructure.a \ - sparcv9regalloc sparcv9select + sparcv9regalloc endif USEDLIBS = lli-interpreter $(JITLIBS) $(ARCHLIBS) scalaropts analysis.a \ From lattner at cs.uiuc.edu Wed Aug 4 02:45:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 02:45:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040745.CAA14317@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.78 -> 1.79 --- Log message: FindGlobalNamed used to take 2.92s out of 8.39s running a profile build of gccld -disable-opt on 252.eon. This patch deletes it and replaces it with a map. The proper fix for this is to fix PR411: http://llvm.cs.uiuc.edu/PR411 , but this will do in the short term. gccld on eon now takes 5.51s, which is 50% faster than before this patch. :) --- Diffs of the changes: (+36 -53) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.78 llvm/lib/VMCore/Linker.cpp:1.79 --- llvm/lib/VMCore/Linker.cpp:1.78 Wed Aug 4 02:28:06 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 02:44:58 2004 @@ -368,41 +368,6 @@ return 0; } -/// FindGlobalNamed - Look in the specified symbol table for a global with the -/// specified name and type. If an exactly matching global does not exist, see -/// if there is a global which is "type compatible" with the specified -/// name/type. This allows us to resolve things like '%x = global int*' with -/// '%x = global opaque*'. -/// -static GlobalValue *FindGlobalNamed(const std::string &Name, const Type *Ty, - SymbolTable *ST) { - // See if an exact match exists in the symbol table... - if (Value *V = ST->lookup(Ty, Name)) return cast(V); - - // It doesn't exist exactly, scan through all of the type planes in the symbol - // table, checking each of them for a type-compatible version. - // - for (SymbolTable::plane_iterator PI = ST->plane_begin(), PE = ST->plane_end(); - PI != PE; ++PI) { - // Does this type plane contain an entry with the specified name? - SymbolTable::ValueMap &VM = PI->second; - SymbolTable::value_iterator VI = VM.find(Name); - - if (VI != VM.end()) { - // Ensure that this type if placed correctly into the symbol table. - GlobalValue *ValPtr = cast(VI->second); - assert(ValPtr->getType() == PI->first && "Type conflict!"); - - // Determine whether we can fold the two types together, resolving them. - // If so, we can use this value. - if (!ValPtr->hasInternalLinkage() && - !RecursiveResolveTypes(Ty, PI->first, ST, "")) - return ValPtr; - } - } - return 0; // Otherwise, nothing could be found. -} - /// ForceRenaming - The LLVM SymbolTable class autorenames globals that conflict /// in the symbol table. This is good for all clients except for us. Go /// through the trouble to force this back. @@ -431,6 +396,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src, std::map &ValueMap, std::multimap &AppendingVars, + std::map &GlobalsByName, std::string *Err) { // We will need a module level symbol table if the src module has a module // level symbol table... @@ -441,13 +407,12 @@ for (Module::const_giterator I = Src->gbegin(), E = Src->gend(); I != E; ++I){ const GlobalVariable *SGV = I; GlobalVariable *DGV = 0; + // Check to see if may have to link the global. if (SGV->hasName() && !SGV->hasInternalLinkage()) { - // A same named thing is a global variable, because the only two things - // that may be in a module level symbol table are Global Vars and - // Functions, and they both have distinct, nonoverlapping, possible types. - // - DGV = cast_or_null(FindGlobalNamed(SGV->getName(), - SGV->getType(), ST)); + std::map::iterator EGV = + GlobalsByName.find(SGV->getName()); + if (EGV != GlobalsByName.end()) + DGV = dyn_cast(EGV->second); } assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && @@ -610,6 +575,7 @@ // static bool LinkFunctionProtos(Module *Dest, const Module *Src, std::map &ValueMap, + std::map &GlobalsByName, std::string *Err) { SymbolTable *ST = (SymbolTable*)&Dest->getSymbolTable(); @@ -619,13 +585,13 @@ for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction Function *DF = 0; - if (SF->hasName() && !SF->hasInternalLinkage()) - // The same named thing is a Function, because the only two things - // that may be in a module level symbol table are Global Vars and - // Functions, and they both have distinct, nonoverlapping, possible types. - // - DF = cast_or_null(FindGlobalNamed(SF->getName(), SF->getType(), - ST)); + if (SF->hasName() && !SF->hasInternalLinkage()) { + // Check to see if may have to link the function. + std::map::iterator EF = + GlobalsByName.find(SF->getName()); + if (EF != GlobalsByName.end()) + DF = dyn_cast(EF->second); + } if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { // Function does not already exist, simply insert an function signature @@ -886,16 +852,32 @@ // std::multimap AppendingVars; - // Add all of the appending globals already in the Dest module to - // AppendingVars. - for (Module::giterator I = Dest->gbegin(), E = Dest->gend(); I != E; ++I) + // GlobalsByName - The LLVM SymbolTable class fights our best efforts at + // linking by separating globals by type. Until PR411 is fixed, we replicate + // it's functionality here. + std::map GlobalsByName; + + for (Module::giterator I = Dest->gbegin(), E = Dest->gend(); I != E; ++I) { + // Add all of the appending globals already in the Dest module to + // AppendingVars. if (I->hasAppendingLinkage()) AppendingVars.insert(std::make_pair(I->getName(), I)); + // Keep track of all globals by name. + if (!I->hasInternalLinkage() && I->hasName()) + GlobalsByName[I->getName()] = I; + } + + // Keep track of all globals by name. + for (Module::iterator I = Dest->begin(), E = Dest->end(); I != E; ++I) + if (!I->hasInternalLinkage() && I->hasName()) + GlobalsByName[I->getName()] = I; + // Insert all of the globals in src into the Dest module... without linking // initializers (which could refer to functions not yet mapped over). // - if (LinkGlobals(Dest, Src, ValueMap, AppendingVars, ErrorMsg)) return true; + if (LinkGlobals(Dest, Src, ValueMap, AppendingVars, GlobalsByName, ErrorMsg)) + return true; // Link the functions together between the two modules, without doing function // bodies... this just adds external function prototypes to the Dest @@ -903,7 +885,8 @@ // all of the global values that may be referenced are available in our // ValueMap. // - if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true; + if (LinkFunctionProtos(Dest, Src, ValueMap, GlobalsByName, ErrorMsg)) + return true; // Update the initializers in the Dest module now that all globals that may // be referenced are in Dest. From lattner at cs.uiuc.edu Wed Aug 4 03:00:57 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 03:00:57 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408040800.DAA16011@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.224 -> 1.225 --- Log message: Add note --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.224 llvm/docs/ReleaseNotes.html:1.225 --- llvm/docs/ReleaseNotes.html:1.224 Tue Aug 3 19:43:50 2004 +++ llvm/docs/ReleaseNotes.html Wed Aug 4 03:00:45 2004 @@ -206,6 +206,7 @@ class cleanup, Type should not derive from Value, eliminate ConstantPointerRef class.

    • The memory footprint of the LLVM IR has been reduced substantially.
    • +
    • The LLVM linker and many core classes have been sped up substantially.
    • @@ -760,7 +761,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/08/04 00:43:50 $ + Last modified: $Date: 2004/08/04 08:00:45 $ From alkis at cs.uiuc.edu Wed Aug 4 03:03:10 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:03:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200408040803.DAA17855@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.98 -> 1.99 --- Log message: Stop using getValues(). --- Diffs of the changes: (+6 -6) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.98 llvm/lib/VMCore/Constants.cpp:1.99 --- llvm/lib/VMCore/Constants.cpp:1.98 Tue Aug 3 23:48:01 2004 +++ llvm/lib/VMCore/Constants.cpp Wed Aug 4 03:02:59 2004 @@ -439,9 +439,9 @@ assert(isa(To) && "Cannot make Constant refer to non-constant!"); std::vector Values; - Values.reserve(getValues().size()); // Build replacement array... - for (unsigned i = 0, e = getValues().size(); i != e; ++i) { - Constant *Val = cast(getValues()[i]); + Values.reserve(getNumOperands()); // Build replacement array... + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + Constant *Val = getOperand(i); if (Val == From) Val = cast(To); Values.push_back(Val); } @@ -464,9 +464,9 @@ assert(isa(To) && "Cannot make Constant refer to non-constant!"); std::vector Values; - Values.reserve(getValues().size()); - for (unsigned i = 0, e = getValues().size(); i != e; ++i) { - Constant *Val = cast(getValues()[i]); + Values.reserve(getNumOperands()); // Build replacement array... + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + Constant *Val = getOperand(i); if (Val == From) Val = cast(To); Values.push_back(Val); } From gaeke at cs.uiuc.edu Wed Aug 4 03:05:37 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 03:05:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Message-ID: <200408040805.DAA18257@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9BurgISel.cpp updated: 1.1 -> 1.2 --- Log message: Get rid of the only use of TargetInstrInfo::getResultPos(), a deprecated method. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp diff -u llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.1 llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.2 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.1 Wed Aug 4 02:28:51 2004 +++ llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Wed Aug 4 03:05:27 2004 @@ -1423,7 +1423,7 @@ MachineOpCode opCode = minstr->getOpcode(); const TargetInstrInfo& instrInfo = *target.getInstrInfo(); - int resultPos = instrInfo.getResultPos(opCode); + int resultPos = instrInfo.get(opCode).resultPos; int immedPos = instrInfo.getImmedConstantPos(opCode); Function *F = vmInstr->getParent()->getParent(); From gaeke at cs.uiuc.edu Wed Aug 4 03:06:41 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed, 4 Aug 2004 03:06:41 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200408040806.DAA18430@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.66 -> 1.67 --- Log message: getResultPos() is dead. --- Diffs of the changes: (+0 -3) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.66 llvm/include/llvm/Target/TargetInstrInfo.h:1.67 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.66 Sun Aug 1 13:17:36 2004 +++ llvm/include/llvm/Target/TargetInstrInfo.h Wed Aug 4 03:06:30 2004 @@ -180,9 +180,6 @@ // //------------------------------------------------------------------------- - int getResultPos(MachineOpCode Opcode) const { - return get(Opcode).resultPos; - } unsigned getNumDelaySlots(MachineOpCode Opcode) const { return get(Opcode).numDelaySlots; } From alkis at cs.uiuc.edu Wed Aug 4 03:08:23 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:08:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040808.DAA18609@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.79 -> 1.80 --- Log message: Stop using getValues(). --- Diffs of the changes: (+10 -12) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.79 llvm/lib/VMCore/Linker.cpp:1.80 --- llvm/lib/VMCore/Linker.cpp:1.79 Wed Aug 4 02:44:58 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 03:08:13 2004 @@ -292,18 +292,16 @@ Constant *Result = 0; if (const ConstantArray *CPA = dyn_cast(CPV)) { - const std::vector &Ops = CPA->getValues(); - std::vector Operands(Ops.size()); - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - Operands[i] = - cast(RemapOperand(Ops[i], LocalMap, GlobalMap)); + std::vector Operands(CPA->getNumOperands()); + for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) + Operands[i] = + cast(RemapOperand(CPA->getOperand(i), LocalMap, GlobalMap)); Result = ConstantArray::get(cast(CPA->getType()), Operands); } else if (const ConstantStruct *CPS = dyn_cast(CPV)) { - const std::vector &Ops = CPS->getValues(); - std::vector Operands(Ops.size()); - for (unsigned i = 0; i < Ops.size(); ++i) - Operands[i] = - cast(RemapOperand(Ops[i], LocalMap, GlobalMap)); + std::vector Operands(CPS->getNumOperands()); + for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) + Operands[i] = + cast(RemapOperand(CPS->getOperand(i), LocalMap, GlobalMap)); Result = ConstantStruct::get(cast(CPS->getType()), Operands); } else if (isa(CPV)) { Result = const_cast(CPV); @@ -774,7 +772,7 @@ Inits.reserve(NewSize); if (ConstantArray *I = dyn_cast(G1->getInitializer())) { for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) - Inits.push_back(cast(I->getValues()[i])); + Inits.push_back(I->getOperand(i)); } else { assert(isa(G1->getInitializer())); Constant *CV = Constant::getNullValue(T1->getElementType()); @@ -783,7 +781,7 @@ } if (ConstantArray *I = dyn_cast(G2->getInitializer())) { for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) - Inits.push_back(cast(I->getValues()[i])); + Inits.push_back(I->getOperand(i)); } else { assert(isa(G2->getInitializer())); Constant *CV = Constant::getNullValue(T2->getElementType()); From alkis at cs.uiuc.edu Wed Aug 4 03:22:26 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:22:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/ValueMapper.cpp Message-ID: <200408040822.DAA20828@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: ValueMapper.cpp updated: 1.16 -> 1.17 --- Log message: Stop using getValues(). --- Diffs of the changes: (+12 -14) Index: llvm/lib/Transforms/Utils/ValueMapper.cpp diff -u llvm/lib/Transforms/Utils/ValueMapper.cpp:1.16 llvm/lib/Transforms/Utils/ValueMapper.cpp:1.17 --- llvm/lib/Transforms/Utils/ValueMapper.cpp:1.16 Sun Jul 18 03:41:47 2004 +++ llvm/lib/Transforms/Utils/ValueMapper.cpp Wed Aug 4 03:22:15 2004 @@ -34,40 +34,38 @@ isa(C) || isa(C)) return VMSlot = C; // Primitive constants map directly else if (ConstantArray *CA = dyn_cast(C)) { - const std::vector &Vals = CA->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - Value *MV = MapValue(Vals[i], VM); - if (MV != Vals[i]) { + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) { + Value *MV = MapValue(CA->getOperand(i), VM); + if (MV != CA->getOperand(i)) { // This array must contain a reference to a global, make a new array // and return it. // std::vector Values; - Values.reserve(Vals.size()); + Values.reserve(CA->getNumOperands()); for (unsigned j = 0; j != i; ++j) - Values.push_back(cast(Vals[j])); + Values.push_back(CA->getOperand(j)); Values.push_back(cast(MV)); for (++i; i != e; ++i) - Values.push_back(cast(MapValue(Vals[i], VM))); + Values.push_back(cast(MapValue(CA->getOperand(i), VM))); return VMSlot = ConstantArray::get(CA->getType(), Values); } } return VMSlot = C; } else if (ConstantStruct *CS = dyn_cast(C)) { - const std::vector &Vals = CS->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - Value *MV = MapValue(Vals[i], VM); - if (MV != Vals[i]) { + for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { + Value *MV = MapValue(CS->getOperand(i), VM); + if (MV != CS->getOperand(i)) { // This struct must contain a reference to a global, make a new struct // and return it. // std::vector Values; - Values.reserve(Vals.size()); + Values.reserve(CS->getNumOperands()); for (unsigned j = 0; j != i; ++j) - Values.push_back(cast(Vals[j])); + Values.push_back(CS->getOperand(j)); Values.push_back(cast(MV)); for (++i; i != e; ++i) - Values.push_back(cast(MapValue(Vals[i], VM))); + Values.push_back(cast(MapValue(CS->getOperand(i), VM))); return VMSlot = ConstantStruct::get(CS->getType(), Values); } } From alkis at cs.uiuc.edu Wed Aug 4 03:24:35 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:24:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200408040824.DAA21104@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.236 -> 1.237 --- Log message: Stop using getValues(). --- Diffs of the changes: (+2 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.236 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.237 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.236 Sun Aug 1 14:42:59 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Aug 4 03:24:25 2004 @@ -2947,7 +2947,7 @@ assert(CU->getValue() < STy->getNumElements() && "Struct index out of range!"); if (ConstantStruct *CS = dyn_cast(C)) { - C = cast(CS->getValues()[CU->getValue()]); + C = CS->getOperand(CU->getValue()); } else if (isa(C)) { C = Constant::getNullValue(STy->getElementType(CU->getValue())); } else { @@ -2957,7 +2957,7 @@ const ArrayType *ATy = cast(*I); if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0; if (ConstantArray *CA = dyn_cast(C)) - C = cast(CA->getValues()[CI->getRawValue()]); + C = CA->getOperand(CI->getRawValue()); else if (isa(C)) C = Constant::getNullValue(ATy->getElementType()); else From alkis at cs.uiuc.edu Wed Aug 4 03:28:44 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:28:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200408040828.DAA21401@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.98 -> 1.99 --- Log message: Stop using getValues(). --- Diffs of the changes: (+4 -4) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.98 llvm/lib/Transforms/Scalar/SCCP.cpp:1.99 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.98 Sun Jul 18 03:34:52 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Wed Aug 4 03:28:33 2004 @@ -753,13 +753,13 @@ if (ConstantUInt *CU = dyn_cast(CE->getOperand(i))) { ConstantStruct *CS = dyn_cast(C); if (CS == 0) return 0; - if (CU->getValue() >= CS->getValues().size()) return 0; - C = cast(CS->getValues()[CU->getValue()]); + if (CU->getValue() >= CS->getNumOperands()) return 0; + C = CS->getOperand(CU->getValue()); } else if (ConstantSInt *CS = dyn_cast(CE->getOperand(i))) { ConstantArray *CA = dyn_cast(C); if (CA == 0) return 0; - if ((uint64_t)CS->getValue() >= CA->getValues().size()) return 0; - C = cast(CA->getValues()[CS->getValue()]); + if ((uint64_t)CS->getValue() >= CA->getNumOperands()) return 0; + C = CA->getOperand(CS->getValue()); } else return 0; return C; From lattner at cs.uiuc.edu Wed Aug 4 03:30:55 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 03:30:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408040830.DAA02359@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.80 -> 1.81 --- Log message: Fix a major regression in my previous checkin --- Diffs of the changes: (+4 -0) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.80 llvm/lib/VMCore/Linker.cpp:1.81 --- llvm/lib/VMCore/Linker.cpp:1.80 Wed Aug 4 03:08:13 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 03:30:43 2004 @@ -411,6 +411,8 @@ GlobalsByName.find(SGV->getName()); if (EGV != GlobalsByName.end()) DGV = dyn_cast(EGV->second); + if (DGV && RecursiveResolveTypes(SGV->getType(), DGV->getType(), ST, "")) + DGV = 0; // FIXME: gross. } assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && @@ -589,6 +591,8 @@ GlobalsByName.find(SF->getName()); if (EF != GlobalsByName.end()) DF = dyn_cast(EF->second); + if (DF && RecursiveResolveTypes(SF->getType(), DF->getType(), ST, "")) + DF = 0; // FIXME: gross. } if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { From alkis at cs.uiuc.edu Wed Aug 4 03:33:31 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:33:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp Message-ID: <200408040833.DAA23941@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.72 -> 1.73 --- Log message: Stop using getValues(). --- Diffs of the changes: (+3 -4) Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.72 llvm/lib/Bytecode/Writer/Writer.cpp:1.73 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.72 Sun Jul 25 16:32:02 2004 +++ llvm/lib/Bytecode/Writer/Writer.cpp Wed Aug 4 03:33:20 2004 @@ -338,7 +338,7 @@ const ConstantArray *CPA = cast(CPV); assert(!CPA->isString() && "Constant strings should be handled specially!"); - for (unsigned i = 0; i != CPA->getNumOperands(); ++i) { + for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) { int Slot = Table.getSlot(CPA->getOperand(i)); assert(Slot != -1 && "Constant used but not available!!"); output_vbr((unsigned)Slot); @@ -348,10 +348,9 @@ case Type::StructTyID: { const ConstantStruct *CPS = cast(CPV); - const std::vector &Vals = CPS->getValues(); - for (unsigned i = 0; i < Vals.size(); ++i) { - int Slot = Table.getSlot(Vals[i]); + for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) { + int Slot = Table.getSlot(CPS->getOperand(i)); assert(Slot != -1 && "Constant used but not available!!"); output_vbr((unsigned)Slot); } From alkis at cs.uiuc.edu Wed Aug 4 03:38:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:38:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200408040838.DAA24873@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.110 -> 1.111 --- Log message: Stop using getValues(). --- Diffs of the changes: (+5 -7) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.110 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.111 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.110 Sun Aug 1 03:22:29 2004 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Wed Aug 4 03:37:52 2004 @@ -270,22 +270,20 @@ printAsCString(O, CVA); O << "\n"; } else { // Not a string. Print the values in successive locations - const std::vector &constValues = CVA->getValues(); - for (unsigned i=0; i < constValues.size(); i++) - emitGlobalConstant(cast(constValues[i].get())); + for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) + emitGlobalConstant(CVA->getOperand(i)); } return; } else if (const ConstantStruct *CVS = dyn_cast(CV)) { // Print the fields in successive locations. Pad to align if needed! const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType()); - const std::vector& constValues = CVS->getValues(); unsigned sizeSoFar = 0; - for (unsigned i=0, N = constValues.size(); i < N; i++) { - const Constant* field = cast(constValues[i].get()); + for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { + const Constant* field = CVS->getOperand(i); // Check if padding is needed and insert one or more 0s. unsigned fieldSize = TD.getTypeSize(field->getType()); - unsigned padSize = ((i == N-1? cvsLayout->StructSize + unsigned padSize = ((i == e-1? cvsLayout->StructSize : cvsLayout->MemberOffsets[i+1]) - cvsLayout->MemberOffsets[i]) - fieldSize; sizeSoFar += fieldSize + padSize; From alkis at cs.uiuc.edu Wed Aug 4 03:41:05 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:41:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200408040841.DAA25630@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.56 -> 1.57 --- Log message: Stop using getValues(). --- Diffs of the changes: (+4 -7) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.56 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.57 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.56 Sat Jul 17 19:41:27 2004 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Wed Aug 4 03:40:55 2004 @@ -446,11 +446,10 @@ switch (Init->getType()->getTypeID()) { case Type::ArrayTyID: { const ConstantArray *CPA = cast(Init); - const std::vector &Val = CPA->getValues(); unsigned ElementSize = getTargetData().getTypeSize(cast(CPA->getType())->getElementType()); - for (unsigned i = 0; i < Val.size(); ++i) - InitializeMemory(cast(Val[i].get()), (char*)Addr+i*ElementSize); + for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) + InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); return; } @@ -458,10 +457,8 @@ const ConstantStruct *CPS = cast(Init); const StructLayout *SL = getTargetData().getStructLayout(cast(CPS->getType())); - const std::vector &Val = CPS->getValues(); - for (unsigned i = 0; i < Val.size(); ++i) - InitializeMemory(cast(Val[i].get()), - (char*)Addr+SL->MemberOffsets[i]); + for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) + InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->MemberOffsets[i]); return; } From alkis at cs.uiuc.edu Wed Aug 4 03:44:53 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:44:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Message-ID: <200408040844.DAA25708@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9AsmPrinter.cpp updated: 1.116 -> 1.117 --- Log message: Stop using getValues(). --- Diffs of the changes: (+5 -7) Index: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp diff -u llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.116 llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.117 --- llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.116 Sat Jul 17 19:36:44 2004 +++ llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Wed Aug 4 03:44:43 2004 @@ -365,23 +365,21 @@ toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; } else { // Not a string. Print the values in successive locations - const std::vector &constValues = CVA->getValues(); - for (unsigned i=0; i < constValues.size(); i++) - printConstantValueOnly(cast(constValues[i].get())); + for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) + printConstantValueOnly(CVA->getOperand(i)); } } else if (const ConstantStruct *CVS = dyn_cast(CV)) { // Print the fields in successive locations. Pad to align if needed! const StructLayout *cvsLayout = Target.getTargetData().getStructLayout(CVS->getType()); - const std::vector& constValues = CVS->getValues(); unsigned sizeSoFar = 0; - for (unsigned i=0, N = constValues.size(); i < N; i++) { - const Constant* field = cast(constValues[i].get()); + for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { + const Constant* field = CVS->getOperand(i); // Check if padding is needed and insert one or more 0s. unsigned fieldSize = Target.getTargetData().getTypeSize(field->getType()); - int padSize = ((i == N-1? cvsLayout->StructSize + int padSize = ((i == e-1? cvsLayout->StructSize : cvsLayout->MemberOffsets[i+1]) - cvsLayout->MemberOffsets[i]) - fieldSize; sizeSoFar += (fieldSize + padSize); From alkis at cs.uiuc.edu Wed Aug 4 03:47:32 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 03:47:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200408040847.DAA25752@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.53 -> 1.54 --- Log message: Remove uneeded getValues() functions. --- Diffs of the changes: (+0 -8) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.53 llvm/include/llvm/Constants.h:1.54 --- llvm/include/llvm/Constants.h:1.53 Tue Aug 3 21:42:17 2004 +++ llvm/include/llvm/Constants.h Wed Aug 4 03:47:21 2004 @@ -367,10 +367,6 @@ /// std::string getAsString() const; - /// getValues - Return a vector of the component constants that make up this - /// array. - inline const std::vector &getValues() const { return Operands; } - /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. This always returns false because zero arrays are always /// created as ConstantAggregateZero objects. @@ -410,10 +406,6 @@ return reinterpret_cast(Value::getType()); } - /// getValues - Return a vector of the component constants that make up this - /// structure. - inline const std::vector &getValues() const { return Operands; } - /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. This always returns false because zero structs are always /// created as ConstantAggregateZero objects. From alkis at cs.uiuc.edu Wed Aug 4 04:42:32 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:42:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.h Message-ID: <200408040942.EAA26311@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.h updated: 1.38 -> 1.39 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+152 -152) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.h diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.38 llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.39 --- llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.38 Sat Jul 24 06:44:15 2004 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.h Wed Aug 4 04:42:21 2004 @@ -25,160 +25,160 @@ namespace llvm { - class LiveVariables; - class MRegisterInfo; - class VirtRegMap; - - class LiveIntervals : public MachineFunctionPass { - MachineFunction* mf_; - const TargetMachine* tm_; - const MRegisterInfo* mri_; - LiveVariables* lv_; - - typedef std::map Mi2IndexMap; - Mi2IndexMap mi2iMap_; - - typedef std::vector Index2MiMap; - Index2MiMap i2miMap_; - - typedef std::map Reg2IntervalMap; - Reg2IntervalMap r2iMap_; - - typedef std::map Reg2RegMap; - Reg2RegMap r2rMap_; - - public: - struct InstrSlots - { - enum { - LOAD = 0, - USE = 1, - DEF = 2, - STORE = 3, - NUM = 4, - }; - }; - - static unsigned getBaseIndex(unsigned index) { - return index - (index % InstrSlots::NUM); - } - static unsigned getBoundaryIndex(unsigned index) { - return getBaseIndex(index + InstrSlots::NUM - 1); - } - static unsigned getLoadIndex(unsigned index) { - return getBaseIndex(index) + InstrSlots::LOAD; - } - static unsigned getUseIndex(unsigned index) { - return getBaseIndex(index) + InstrSlots::USE; - } - static unsigned getDefIndex(unsigned index) { - return getBaseIndex(index) + InstrSlots::DEF; - } - static unsigned getStoreIndex(unsigned index) { - return getBaseIndex(index) + InstrSlots::STORE; - } - - // FIXME: this should really be a const_iterator - typedef Reg2IntervalMap::iterator iterator; - iterator begin() { return r2iMap_.begin(); } - iterator end() { return r2iMap_.end(); } - unsigned getNumIntervals() const { return r2iMap_.size(); } - - LiveInterval &getInterval(unsigned reg) { - Reg2IntervalMap::iterator I = r2iMap_.find(reg); - assert(I != r2iMap_.end() && "Interval does not exist for register"); - return I->second; - } - - const LiveInterval &getInterval(unsigned reg) const { - Reg2IntervalMap::const_iterator I = r2iMap_.find(reg); - assert(I != r2iMap_.end() && "Interval does not exist for register"); - return I->second; - } - - /// getInstructionIndex - returns the base index of instr - unsigned getInstructionIndex(MachineInstr* instr) const { - Mi2IndexMap::const_iterator it = mi2iMap_.find(instr); - assert(it != mi2iMap_.end() && "Invalid instruction!"); - return it->second; - } - - /// getInstructionFromIndex - given an index in any slot of an - /// instruction return a pointer the instruction - MachineInstr* getInstructionFromIndex(unsigned index) const { - index /= InstrSlots::NUM; // convert index to vector index - assert(index < i2miMap_.size() && - "index does not correspond to an instruction"); - return i2miMap_[index]; - } - - std::vector addIntervalsForSpills(const LiveInterval& i, - VirtRegMap& vrm, - int slot); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual void releaseMemory(); - - /// runOnMachineFunction - pass entry point - virtual bool runOnMachineFunction(MachineFunction&); - - private: - /// computeIntervals - compute live intervals - void computeIntervals(); - - /// joinIntervals - join compatible live intervals - void joinIntervals(); - - /// joinIntervalsInMachineBB - Join intervals based on move - /// instructions in the specified basic block. - void joinIntervalsInMachineBB(MachineBasicBlock *MBB); - - /// handleRegisterDef - update intervals for a register def - /// (calls handlePhysicalRegisterDef and - /// handleVirtualRegisterDef) - void handleRegisterDef(MachineBasicBlock* mbb, - MachineBasicBlock::iterator mi, - unsigned reg); - - /// handleVirtualRegisterDef - update intervals for a virtual - /// register def - void handleVirtualRegisterDef(MachineBasicBlock* mbb, - MachineBasicBlock::iterator mi, - LiveInterval& interval); - - /// handlePhysicalRegisterDef - update intervals for a - /// physical register def - void handlePhysicalRegisterDef(MachineBasicBlock* mbb, - MachineBasicBlock::iterator mi, - LiveInterval& interval); - - /// Return true if the two specified registers belong to different - /// register classes. The registers may be either phys or virt regs. - bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; - - bool overlapsAliases(const LiveInterval *lhs, - const LiveInterval *rhs) const; - - static LiveInterval createInterval(unsigned Reg); - - LiveInterval &getOrCreateInterval(unsigned reg) { - Reg2IntervalMap::iterator I = r2iMap_.find(reg); - if (I == r2iMap_.end()) - I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg))); - return I->second; - } - - /// rep - returns the representative of this register - unsigned rep(unsigned reg) { - Reg2RegMap::iterator it = r2rMap_.find(reg); - if (it != r2rMap_.end()) - return it->second = rep(it->second); - return reg; - } - - void printRegName(unsigned reg) const; + class LiveVariables; + class MRegisterInfo; + class VirtRegMap; + + class LiveIntervals : public MachineFunctionPass { + MachineFunction* mf_; + const TargetMachine* tm_; + const MRegisterInfo* mri_; + LiveVariables* lv_; + + typedef std::map Mi2IndexMap; + Mi2IndexMap mi2iMap_; + + typedef std::vector Index2MiMap; + Index2MiMap i2miMap_; + + typedef std::map Reg2IntervalMap; + Reg2IntervalMap r2iMap_; + + typedef std::map Reg2RegMap; + Reg2RegMap r2rMap_; + + public: + struct InstrSlots + { + enum { + LOAD = 0, + USE = 1, + DEF = 2, + STORE = 3, + NUM = 4, + }; }; + static unsigned getBaseIndex(unsigned index) { + return index - (index % InstrSlots::NUM); + } + static unsigned getBoundaryIndex(unsigned index) { + return getBaseIndex(index + InstrSlots::NUM - 1); + } + static unsigned getLoadIndex(unsigned index) { + return getBaseIndex(index) + InstrSlots::LOAD; + } + static unsigned getUseIndex(unsigned index) { + return getBaseIndex(index) + InstrSlots::USE; + } + static unsigned getDefIndex(unsigned index) { + return getBaseIndex(index) + InstrSlots::DEF; + } + static unsigned getStoreIndex(unsigned index) { + return getBaseIndex(index) + InstrSlots::STORE; + } + + // FIXME: this should really be a const_iterator + typedef Reg2IntervalMap::iterator iterator; + iterator begin() { return r2iMap_.begin(); } + iterator end() { return r2iMap_.end(); } + unsigned getNumIntervals() const { return r2iMap_.size(); } + + LiveInterval &getInterval(unsigned reg) { + Reg2IntervalMap::iterator I = r2iMap_.find(reg); + assert(I != r2iMap_.end() && "Interval does not exist for register"); + return I->second; + } + + const LiveInterval &getInterval(unsigned reg) const { + Reg2IntervalMap::const_iterator I = r2iMap_.find(reg); + assert(I != r2iMap_.end() && "Interval does not exist for register"); + return I->second; + } + + /// getInstructionIndex - returns the base index of instr + unsigned getInstructionIndex(MachineInstr* instr) const { + Mi2IndexMap::const_iterator it = mi2iMap_.find(instr); + assert(it != mi2iMap_.end() && "Invalid instruction!"); + return it->second; + } + + /// getInstructionFromIndex - given an index in any slot of an + /// instruction return a pointer the instruction + MachineInstr* getInstructionFromIndex(unsigned index) const { + index /= InstrSlots::NUM; // convert index to vector index + assert(index < i2miMap_.size() && + "index does not correspond to an instruction"); + return i2miMap_[index]; + } + + std::vector addIntervalsForSpills(const LiveInterval& i, + VirtRegMap& vrm, + int slot); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory(); + + /// runOnMachineFunction - pass entry point + virtual bool runOnMachineFunction(MachineFunction&); + + private: + /// computeIntervals - compute live intervals + void computeIntervals(); + + /// joinIntervals - join compatible live intervals + void joinIntervals(); + + /// joinIntervalsInMachineBB - Join intervals based on move + /// instructions in the specified basic block. + void joinIntervalsInMachineBB(MachineBasicBlock *MBB); + + /// handleRegisterDef - update intervals for a register def + /// (calls handlePhysicalRegisterDef and + /// handleVirtualRegisterDef) + void handleRegisterDef(MachineBasicBlock* mbb, + MachineBasicBlock::iterator mi, + unsigned reg); + + /// handleVirtualRegisterDef - update intervals for a virtual + /// register def + void handleVirtualRegisterDef(MachineBasicBlock* mbb, + MachineBasicBlock::iterator mi, + LiveInterval& interval); + + /// handlePhysicalRegisterDef - update intervals for a + /// physical register def + void handlePhysicalRegisterDef(MachineBasicBlock* mbb, + MachineBasicBlock::iterator mi, + LiveInterval& interval); + + /// Return true if the two specified registers belong to different + /// register classes. The registers may be either phys or virt regs. + bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; + + bool overlapsAliases(const LiveInterval *lhs, + const LiveInterval *rhs) const; + + static LiveInterval createInterval(unsigned Reg); + + LiveInterval &getOrCreateInterval(unsigned reg) { + Reg2IntervalMap::iterator I = r2iMap_.find(reg); + if (I == r2iMap_.end()) + I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg))); + return I->second; + } + + /// rep - returns the representative of this register + unsigned rep(unsigned reg) { + Reg2RegMap::iterator it = r2rMap_.find(reg); + if (it != r2rMap_.end()) + return it->second = rep(it->second); + return reg; + } + + void printRegName(unsigned reg) const; + }; + } // End llvm namespace #endif From alkis at cs.uiuc.edu Wed Aug 4 04:43:49 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:43:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.h Message-ID: <200408040943.EAA26353@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.h updated: 1.39 -> 1.40 --- Log message: Clean up whitespace. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.h diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.39 llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.40 --- llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.39 Wed Aug 4 04:42:21 2004 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.h Wed Aug 4 04:43:38 2004 @@ -156,7 +156,7 @@ /// register classes. The registers may be either phys or virt regs. bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; - bool overlapsAliases(const LiveInterval *lhs, + bool overlapsAliases(const LiveInterval *lhs, const LiveInterval *rhs) const; static LiveInterval createInterval(unsigned Reg); From alkis at cs.uiuc.edu Wed Aug 4 04:45:24 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:45:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200408040945.EAA26381@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.114 -> 1.115 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+405 -406) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.114 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.115 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.114 Sun Jul 25 02:47:25 2004 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Aug 4 04:45:14 2004 @@ -37,447 +37,446 @@ using namespace llvm; namespace { - RegisterAnalysis X("liveintervals", - "Live Interval Analysis"); + RegisterAnalysis X("liveintervals", "Live Interval Analysis"); - Statistic<> numIntervals - ("liveintervals", "Number of original intervals"); + Statistic<> numIntervals + ("liveintervals", "Number of original intervals"); - Statistic<> numIntervalsAfter - ("liveintervals", "Number of intervals after coalescing"); + Statistic<> numIntervalsAfter + ("liveintervals", "Number of intervals after coalescing"); - Statistic<> numJoins - ("liveintervals", "Number of interval joins performed"); + Statistic<> numJoins + ("liveintervals", "Number of interval joins performed"); - Statistic<> numPeep - ("liveintervals", "Number of identity moves eliminated after coalescing"); + Statistic<> numPeep + ("liveintervals", "Number of identity moves eliminated after coalescing"); - Statistic<> numFolded - ("liveintervals", "Number of loads/stores folded into instructions"); + Statistic<> numFolded + ("liveintervals", "Number of loads/stores folded into instructions"); - cl::opt - EnableJoining("join-liveintervals", - cl::desc("Join compatible live intervals"), - cl::init(true)); + cl::opt + EnableJoining("join-liveintervals", + cl::desc("Join compatible live intervals"), + cl::init(true)); }; void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); - AU.addRequired(); - AU.addPreservedID(PHIEliminationID); - AU.addRequiredID(PHIEliminationID); - AU.addRequiredID(TwoAddressInstructionPassID); - AU.addRequired(); - MachineFunctionPass::getAnalysisUsage(AU); + AU.addPreserved(); + AU.addRequired(); + AU.addPreservedID(PHIEliminationID); + AU.addRequiredID(PHIEliminationID); + AU.addRequiredID(TwoAddressInstructionPassID); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); } void LiveIntervals::releaseMemory() { - mi2iMap_.clear(); - i2miMap_.clear(); - r2iMap_.clear(); - r2rMap_.clear(); + mi2iMap_.clear(); + i2miMap_.clear(); + r2iMap_.clear(); + r2rMap_.clear(); } /// runOnMachineFunction - Register allocate the whole function /// bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { - mf_ = &fn; - tm_ = &fn.getTarget(); - mri_ = tm_->getRegisterInfo(); - lv_ = &getAnalysis(); - - // number MachineInstrs - unsigned miIndex = 0; - for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end(); - mbb != mbbEnd; ++mbb) - for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); - mi != miEnd; ++mi) { - bool inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second; - assert(inserted && "multiple MachineInstr -> index mappings"); - i2miMap_.push_back(mi); - miIndex += InstrSlots::NUM; - } + mf_ = &fn; + tm_ = &fn.getTarget(); + mri_ = tm_->getRegisterInfo(); + lv_ = &getAnalysis(); + + // number MachineInstrs + unsigned miIndex = 0; + for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end(); + mbb != mbbEnd; ++mbb) + for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); + mi != miEnd; ++mi) { + bool inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second; + assert(inserted && "multiple MachineInstr -> index mappings"); + i2miMap_.push_back(mi); + miIndex += InstrSlots::NUM; + } - computeIntervals(); + computeIntervals(); - numIntervals += getNumIntervals(); + numIntervals += getNumIntervals(); #if 1 - DEBUG(std::cerr << "********** INTERVALS **********\n"); - DEBUG(for (iterator I = begin(), E = end(); I != E; ++I) - std::cerr << I->second << "\n"); + DEBUG(std::cerr << "********** INTERVALS **********\n"); + DEBUG(for (iterator I = begin(), E = end(); I != E; ++I) + std::cerr << I->second << "\n"); #endif - // join intervals if requested - if (EnableJoining) joinIntervals(); - - numIntervalsAfter += getNumIntervals(); + // join intervals if requested + if (EnableJoining) joinIntervals(); - // perform a final pass over the instructions and compute spill - // weights, coalesce virtual registers and remove identity moves - const LoopInfo& loopInfo = getAnalysis(); - const TargetInstrInfo& tii = *tm_->getInstrInfo(); - - for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); - mbbi != mbbe; ++mbbi) { - MachineBasicBlock* mbb = mbbi; - unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock()); + numIntervalsAfter += getNumIntervals(); - for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end(); - mii != mie; ) { - // if the move will be an identity move delete it - unsigned srcReg, dstReg, RegRep; - if (tii.isMoveInstr(*mii, srcReg, dstReg) && - (RegRep = rep(srcReg)) == rep(dstReg)) { - // remove from def list - LiveInterval &interval = getOrCreateInterval(RegRep); - // remove index -> MachineInstr and - // MachineInstr -> index mappings - Mi2IndexMap::iterator mi2i = mi2iMap_.find(mii); - if (mi2i != mi2iMap_.end()) { - i2miMap_[mi2i->second/InstrSlots::NUM] = 0; - mi2iMap_.erase(mi2i); - } - mii = mbbi->erase(mii); - ++numPeep; - } - else { - for (unsigned i = 0; i < mii->getNumOperands(); ++i) { - const MachineOperand& mop = mii->getOperand(i); - if (mop.isRegister() && mop.getReg() && - MRegisterInfo::isVirtualRegister(mop.getReg())) { - // replace register with representative register - unsigned reg = rep(mop.getReg()); - mii->SetMachineOperandReg(i, reg); - - LiveInterval &RegInt = getInterval(reg); - RegInt.weight += - (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth); - } - } - ++mii; - } + // perform a final pass over the instructions and compute spill + // weights, coalesce virtual registers and remove identity moves + const LoopInfo& loopInfo = getAnalysis(); + const TargetInstrInfo& tii = *tm_->getInstrInfo(); + + for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); + mbbi != mbbe; ++mbbi) { + MachineBasicBlock* mbb = mbbi; + unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock()); + + for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end(); + mii != mie; ) { + // if the move will be an identity move delete it + unsigned srcReg, dstReg, RegRep; + if (tii.isMoveInstr(*mii, srcReg, dstReg) && + (RegRep = rep(srcReg)) == rep(dstReg)) { + // remove from def list + LiveInterval &interval = getOrCreateInterval(RegRep); + // remove index -> MachineInstr and + // MachineInstr -> index mappings + Mi2IndexMap::iterator mi2i = mi2iMap_.find(mii); + if (mi2i != mi2iMap_.end()) { + i2miMap_[mi2i->second/InstrSlots::NUM] = 0; + mi2iMap_.erase(mi2i); } + mii = mbbi->erase(mii); + ++numPeep; + } + else { + for (unsigned i = 0; i < mii->getNumOperands(); ++i) { + const MachineOperand& mop = mii->getOperand(i); + if (mop.isRegister() && mop.getReg() && + MRegisterInfo::isVirtualRegister(mop.getReg())) { + // replace register with representative register + unsigned reg = rep(mop.getReg()); + mii->SetMachineOperandReg(i, reg); + + LiveInterval &RegInt = getInterval(reg); + RegInt.weight += + (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth); + } + } + ++mii; + } } + } - DEBUG(std::cerr << "********** INTERVALS **********\n"); - DEBUG (for (iterator I = begin(), E = end(); I != E; ++I) - std::cerr << I->second << "\n"); - DEBUG(std::cerr << "********** MACHINEINSTRS **********\n"); - DEBUG( - for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); - mbbi != mbbe; ++mbbi) { - std::cerr << ((Value*)mbbi->getBasicBlock())->getName() << ":\n"; - for (MachineBasicBlock::iterator mii = mbbi->begin(), - mie = mbbi->end(); mii != mie; ++mii) { - std::cerr << getInstructionIndex(mii) << '\t'; - mii->print(std::cerr, tm_); - } - }); + DEBUG(std::cerr << "********** INTERVALS **********\n"); + DEBUG (for (iterator I = begin(), E = end(); I != E; ++I) + std::cerr << I->second << "\n"); + DEBUG(std::cerr << "********** MACHINEINSTRS **********\n"); + DEBUG( + for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); + mbbi != mbbe; ++mbbi) { + std::cerr << ((Value*)mbbi->getBasicBlock())->getName() << ":\n"; + for (MachineBasicBlock::iterator mii = mbbi->begin(), + mie = mbbi->end(); mii != mie; ++mii) { + std::cerr << getInstructionIndex(mii) << '\t'; + mii->print(std::cerr, tm_); + } + }); - return true; + return true; } std::vector LiveIntervals::addIntervalsForSpills( - const LiveInterval& li, - VirtRegMap& vrm, - int slot) + const LiveInterval& li, + VirtRegMap& vrm, + int slot) { - std::vector added; + std::vector added; - assert(li.weight != HUGE_VAL && - "attempt to spill already spilled interval!"); + assert(li.weight != HUGE_VAL && + "attempt to spill already spilled interval!"); - DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: " - << li << '\n'); + DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: " + << li << '\n'); - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg); - - for (LiveInterval::Ranges::const_iterator - i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) { - unsigned index = getBaseIndex(i->start); - unsigned end = getBaseIndex(i->end-1) + InstrSlots::NUM; - for (; index != end; index += InstrSlots::NUM) { - // skip deleted instructions - while (index != end && !getInstructionFromIndex(index)) - index += InstrSlots::NUM; - if (index == end) break; - - MachineBasicBlock::iterator mi = getInstructionFromIndex(index); - - for_operand: - for (unsigned i = 0; i != mi->getNumOperands(); ++i) { - MachineOperand& mop = mi->getOperand(i); - if (mop.isRegister() && mop.getReg() == li.reg) { - if (MachineInstr* fmi = - mri_->foldMemoryOperand(mi, i, slot)) { - lv_->instructionChanged(mi, fmi); - vrm.virtFolded(li.reg, mi, fmi); - mi2iMap_.erase(mi); - i2miMap_[index/InstrSlots::NUM] = fmi; - mi2iMap_[fmi] = index; - MachineBasicBlock& mbb = *mi->getParent(); - mi = mbb.insert(mbb.erase(mi), fmi); - ++numFolded; - goto for_operand; - } - else { - // This is tricky. We need to add information in - // the interval about the spill code so we have to - // use our extra load/store slots. - // - // If we have a use we are going to have a load so - // we start the interval from the load slot - // onwards. Otherwise we start from the def slot. - unsigned start = (mop.isUse() ? - getLoadIndex(index) : - getDefIndex(index)); - // If we have a def we are going to have a store - // right after it so we end the interval after the - // use of the next instruction. Otherwise we end - // after the use of this instruction. - unsigned end = 1 + (mop.isDef() ? - getStoreIndex(index) : - getUseIndex(index)); - - // create a new register for this spill - unsigned nReg = - mf_->getSSARegMap()->createVirtualRegister(rc); - mi->SetMachineOperandReg(i, nReg); - vrm.grow(); - vrm.assignVirt2StackSlot(nReg, slot); - LiveInterval& nI = getOrCreateInterval(nReg); - assert(nI.empty()); - // the spill weight is now infinity as it - // cannot be spilled again - nI.weight = HUGE_VAL; - LiveRange LR(start, end, nI.getNextValue()); - DEBUG(std::cerr << " +" << LR); - nI.addRange(LR); - added.push_back(&nI); - // update live variables - lv_->addVirtualRegisterKilled(nReg, mi); - DEBUG(std::cerr << "\t\t\t\tadded new interval: " - << nI << '\n'); - } - } - } + const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg); + + for (LiveInterval::Ranges::const_iterator + i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) { + unsigned index = getBaseIndex(i->start); + unsigned end = getBaseIndex(i->end-1) + InstrSlots::NUM; + for (; index != end; index += InstrSlots::NUM) { + // skip deleted instructions + while (index != end && !getInstructionFromIndex(index)) + index += InstrSlots::NUM; + if (index == end) break; + + MachineBasicBlock::iterator mi = getInstructionFromIndex(index); + + for_operand: + for (unsigned i = 0; i != mi->getNumOperands(); ++i) { + MachineOperand& mop = mi->getOperand(i); + if (mop.isRegister() && mop.getReg() == li.reg) { + if (MachineInstr* fmi = + mri_->foldMemoryOperand(mi, i, slot)) { + lv_->instructionChanged(mi, fmi); + vrm.virtFolded(li.reg, mi, fmi); + mi2iMap_.erase(mi); + i2miMap_[index/InstrSlots::NUM] = fmi; + mi2iMap_[fmi] = index; + MachineBasicBlock& mbb = *mi->getParent(); + mi = mbb.insert(mbb.erase(mi), fmi); + ++numFolded; + goto for_operand; + } + else { + // This is tricky. We need to add information in + // the interval about the spill code so we have to + // use our extra load/store slots. + // + // If we have a use we are going to have a load so + // we start the interval from the load slot + // onwards. Otherwise we start from the def slot. + unsigned start = (mop.isUse() ? + getLoadIndex(index) : + getDefIndex(index)); + // If we have a def we are going to have a store + // right after it so we end the interval after the + // use of the next instruction. Otherwise we end + // after the use of this instruction. + unsigned end = 1 + (mop.isDef() ? + getStoreIndex(index) : + getUseIndex(index)); + + // create a new register for this spill + unsigned nReg = + mf_->getSSARegMap()->createVirtualRegister(rc); + mi->SetMachineOperandReg(i, nReg); + vrm.grow(); + vrm.assignVirt2StackSlot(nReg, slot); + LiveInterval& nI = getOrCreateInterval(nReg); + assert(nI.empty()); + // the spill weight is now infinity as it + // cannot be spilled again + nI.weight = HUGE_VAL; + LiveRange LR(start, end, nI.getNextValue()); + DEBUG(std::cerr << " +" << LR); + nI.addRange(LR); + added.push_back(&nI); + // update live variables + lv_->addVirtualRegisterKilled(nReg, mi); + DEBUG(std::cerr << "\t\t\t\tadded new interval: " + << nI << '\n'); + } } + } } + } - return added; + return added; } void LiveIntervals::printRegName(unsigned reg) const { - if (MRegisterInfo::isPhysicalRegister(reg)) - std::cerr << mri_->getName(reg); - else - std::cerr << "%reg" << reg; + if (MRegisterInfo::isPhysicalRegister(reg)) + std::cerr << mri_->getName(reg); + else + std::cerr << "%reg" << reg; } void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, MachineBasicBlock::iterator mi, LiveInterval& interval) { - DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); - LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); + DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); + LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); - // Virtual registers may be defined multiple times (due to phi - // elimination and 2-addr elimination). Much of what we do only has to be - // done once for the vreg. We use an empty interval to detect the first - // time we see a vreg. - if (interval.empty()) { - // Get the Idx of the defining instructions. - unsigned defIndex = getDefIndex(getInstructionIndex(mi)); - - unsigned ValNum = interval.getNextValue(); - assert(ValNum == 0 && "First value in interval is not 0?"); - ValNum = 0; // Clue in the optimizer. - - // Loop over all of the blocks that the vreg is defined in. There are - // two cases we have to handle here. The most common case is a vreg - // whose lifetime is contained within a basic block. In this case there - // will be a single kill, in MBB, which comes after the definition. - if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { - // FIXME: what about dead vars? - unsigned killIdx; - if (vi.Kills[0] != mi) - killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1; - else - killIdx = defIndex+1; - - // If the kill happens after the definition, we have an intra-block - // live range. - if (killIdx > defIndex) { - assert(vi.AliveBlocks.empty() && - "Shouldn't be alive across any blocks!"); - LiveRange LR(defIndex, killIdx, ValNum); - interval.addRange(LR); - DEBUG(std::cerr << " +" << LR << "\n"); - return; - } - } - - // The other case we handle is when a virtual register lives to the end - // of the defining block, potentially live across some blocks, then is - // live into some number of blocks, but gets killed. Start by adding a - // range that goes from this definition to the end of the defining block. - LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) + - InstrSlots::NUM, ValNum); - DEBUG(std::cerr << " +" << NewLR); - interval.addRange(NewLR); - - // Iterate over all of the blocks that the variable is completely - // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the - // live interval. - for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) { - if (vi.AliveBlocks[i]) { - MachineBasicBlock* mbb = mf_->getBlockNumbered(i); - if (!mbb->empty()) { - LiveRange LR(getInstructionIndex(&mbb->front()), - getInstructionIndex(&mbb->back())+InstrSlots::NUM, - ValNum); - interval.addRange(LR); - DEBUG(std::cerr << " +" << LR); - } - } - } - - // Finally, this virtual register is live from the start of any killing - // block to the 'use' slot of the killing instruction. - for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { - MachineInstr *Kill = vi.Kills[i]; - LiveRange LR(getInstructionIndex(Kill->getParent()->begin()), - getUseIndex(getInstructionIndex(Kill))+1, ValNum); - interval.addRange(LR); - DEBUG(std::cerr << " +" << LR); - } + // Virtual registers may be defined multiple times (due to phi + // elimination and 2-addr elimination). Much of what we do only has to be + // done once for the vreg. We use an empty interval to detect the first + // time we see a vreg. + if (interval.empty()) { + // Get the Idx of the defining instructions. + unsigned defIndex = getDefIndex(getInstructionIndex(mi)); + + unsigned ValNum = interval.getNextValue(); + assert(ValNum == 0 && "First value in interval is not 0?"); + ValNum = 0; // Clue in the optimizer. + + // Loop over all of the blocks that the vreg is defined in. There are + // two cases we have to handle here. The most common case is a vreg + // whose lifetime is contained within a basic block. In this case there + // will be a single kill, in MBB, which comes after the definition. + if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { + // FIXME: what about dead vars? + unsigned killIdx; + if (vi.Kills[0] != mi) + killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1; + else + killIdx = defIndex+1; + + // If the kill happens after the definition, we have an intra-block + // live range. + if (killIdx > defIndex) { + assert(vi.AliveBlocks.empty() && + "Shouldn't be alive across any blocks!"); + LiveRange LR(defIndex, killIdx, ValNum); + interval.addRange(LR); + DEBUG(std::cerr << " +" << LR << "\n"); + return; + } + } - } else { - // If this is the second time we see a virtual register definition, it - // must be due to phi elimination or two addr elimination. If this is - // the result of two address elimination, then the vreg is the first - // operand, and is a def-and-use. - if (mi->getOperand(0).isRegister() && - mi->getOperand(0).getReg() == interval.reg && - mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) { - // If this is a two-address definition, then we have already processed - // the live range. The only problem is that we didn't realize there - // are actually two values in the live interval. Because of this we - // need to take the LiveRegion that defines this register and split it - // into two values. - unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst)); - unsigned RedefIndex = getDefIndex(getInstructionIndex(mi)); - - // Delete the initial value, which should be short and continuous, - // becuase the 2-addr copy must be in the same MBB as the redef. - interval.removeRange(DefIndex, RedefIndex); + // The other case we handle is when a virtual register lives to the end + // of the defining block, potentially live across some blocks, then is + // live into some number of blocks, but gets killed. Start by adding a + // range that goes from this definition to the end of the defining block. + LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) + + InstrSlots::NUM, ValNum); + DEBUG(std::cerr << " +" << NewLR); + interval.addRange(NewLR); + + // Iterate over all of the blocks that the variable is completely + // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the + // live interval. + for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) { + if (vi.AliveBlocks[i]) { + MachineBasicBlock* mbb = mf_->getBlockNumbered(i); + if (!mbb->empty()) { + LiveRange LR(getInstructionIndex(&mbb->front()), + getInstructionIndex(&mbb->back())+InstrSlots::NUM, + ValNum); + interval.addRange(LR); + DEBUG(std::cerr << " +" << LR); + } + } + } + + // Finally, this virtual register is live from the start of any killing + // block to the 'use' slot of the killing instruction. + for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { + MachineInstr *Kill = vi.Kills[i]; + LiveRange LR(getInstructionIndex(Kill->getParent()->begin()), + getUseIndex(getInstructionIndex(Kill))+1, ValNum); + interval.addRange(LR); + DEBUG(std::cerr << " +" << LR); + } + + } else { + // If this is the second time we see a virtual register definition, it + // must be due to phi elimination or two addr elimination. If this is + // the result of two address elimination, then the vreg is the first + // operand, and is a def-and-use. + if (mi->getOperand(0).isRegister() && + mi->getOperand(0).getReg() == interval.reg && + mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) { + // If this is a two-address definition, then we have already processed + // the live range. The only problem is that we didn't realize there + // are actually two values in the live interval. Because of this we + // need to take the LiveRegion that defines this register and split it + // into two values. + unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst)); + unsigned RedefIndex = getDefIndex(getInstructionIndex(mi)); + + // Delete the initial value, which should be short and continuous, + // becuase the 2-addr copy must be in the same MBB as the redef. + interval.removeRange(DefIndex, RedefIndex); - LiveRange LR(DefIndex, RedefIndex, interval.getNextValue()); - DEBUG(std::cerr << " replace range with " << LR); - interval.addRange(LR); - - // If this redefinition is dead, we need to add a dummy unit live - // range covering the def slot. - for (LiveVariables::killed_iterator KI = lv_->dead_begin(mi), - E = lv_->dead_end(mi); KI != E; ++KI) - if (KI->second == interval.reg) { - interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0)); - break; - } - - DEBUG(std::cerr << "RESULT: " << interval); - - } else { - // Otherwise, this must be because of phi elimination. If this is the - // first redefinition of the vreg that we have seen, go back and change - // the live range in the PHI block to be a different value number. - if (interval.containsOneValue()) { - assert(vi.Kills.size() == 1 && - "PHI elimination vreg should have one kill, the PHI itself!"); - - // Remove the old range that we now know has an incorrect number. - MachineInstr *Killer = vi.Kills[0]; - unsigned Start = getInstructionIndex(Killer->getParent()->begin()); - unsigned End = getUseIndex(getInstructionIndex(Killer))+1; - DEBUG(std::cerr << "Removing [" << Start << "," << End << "] from: " - << interval << "\n"); - interval.removeRange(Start, End); - DEBUG(std::cerr << "RESULT: " << interval); - - // Replace the interval with one of a NEW value number. - LiveRange LR(Start, End, interval.getNextValue()); - DEBUG(std::cerr << " replace range with " << LR); - interval.addRange(LR); - DEBUG(std::cerr << "RESULT: " << interval); - } - - // In the case of PHI elimination, each variable definition is only - // live until the end of the block. We've already taken care of the - // rest of the live range. - unsigned defIndex = getDefIndex(getInstructionIndex(mi)); - LiveRange LR(defIndex, - getInstructionIndex(&mbb->back()) + InstrSlots::NUM, - interval.getNextValue()); - interval.addRange(LR); - DEBUG(std::cerr << " +" << LR); - } + LiveRange LR(DefIndex, RedefIndex, interval.getNextValue()); + DEBUG(std::cerr << " replace range with " << LR); + interval.addRange(LR); + + // If this redefinition is dead, we need to add a dummy unit live + // range covering the def slot. + for (LiveVariables::killed_iterator KI = lv_->dead_begin(mi), + E = lv_->dead_end(mi); KI != E; ++KI) + if (KI->second == interval.reg) { + interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0)); + break; + } + + DEBUG(std::cerr << "RESULT: " << interval); + + } else { + // Otherwise, this must be because of phi elimination. If this is the + // first redefinition of the vreg that we have seen, go back and change + // the live range in the PHI block to be a different value number. + if (interval.containsOneValue()) { + assert(vi.Kills.size() == 1 && + "PHI elimination vreg should have one kill, the PHI itself!"); + + // Remove the old range that we now know has an incorrect number. + MachineInstr *Killer = vi.Kills[0]; + unsigned Start = getInstructionIndex(Killer->getParent()->begin()); + unsigned End = getUseIndex(getInstructionIndex(Killer))+1; + DEBUG(std::cerr << "Removing [" << Start << "," << End << "] from: " + << interval << "\n"); + interval.removeRange(Start, End); + DEBUG(std::cerr << "RESULT: " << interval); + + // Replace the interval with one of a NEW value number. + LiveRange LR(Start, End, interval.getNextValue()); + DEBUG(std::cerr << " replace range with " << LR); + interval.addRange(LR); + DEBUG(std::cerr << "RESULT: " << interval); + } + + // In the case of PHI elimination, each variable definition is only + // live until the end of the block. We've already taken care of the + // rest of the live range. + unsigned defIndex = getDefIndex(getInstructionIndex(mi)); + LiveRange LR(defIndex, + getInstructionIndex(&mbb->back()) + InstrSlots::NUM, + interval.getNextValue()); + interval.addRange(LR); + DEBUG(std::cerr << " +" << LR); } + } - DEBUG(std::cerr << '\n'); + DEBUG(std::cerr << '\n'); } void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator mi, LiveInterval& interval) { - // A physical register cannot be live across basic block, so its - // lifetime must end somewhere in its defining basic block. - DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); - typedef LiveVariables::killed_iterator KillIter; - - unsigned baseIndex = getInstructionIndex(mi); - unsigned start = getDefIndex(baseIndex); - unsigned end = start; - - // If it is not used after definition, it is considered dead at - // the instruction defining it. Hence its interval is: - // [defSlot(def), defSlot(def)+1) - for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi); - ki != ke; ++ki) { - if (interval.reg == ki->second) { - DEBUG(std::cerr << " dead"); - end = getDefIndex(start) + 1; - goto exit; - } + // A physical register cannot be live across basic block, so its + // lifetime must end somewhere in its defining basic block. + DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); + typedef LiveVariables::killed_iterator KillIter; + + unsigned baseIndex = getInstructionIndex(mi); + unsigned start = getDefIndex(baseIndex); + unsigned end = start; + + // If it is not used after definition, it is considered dead at + // the instruction defining it. Hence its interval is: + // [defSlot(def), defSlot(def)+1) + for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi); + ki != ke; ++ki) { + if (interval.reg == ki->second) { + DEBUG(std::cerr << " dead"); + end = getDefIndex(start) + 1; + goto exit; } + } - // If it is not dead on definition, it must be killed by a - // subsequent instruction. Hence its interval is: - // [defSlot(def), useSlot(kill)+1) - while (true) { - ++mi; - assert(mi != MBB->end() && "physreg was not killed in defining block!"); - baseIndex += InstrSlots::NUM; - for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi); - ki != ke; ++ki) { - if (interval.reg == ki->second) { - DEBUG(std::cerr << " killed"); - end = getUseIndex(baseIndex) + 1; - goto exit; - } - } + // If it is not dead on definition, it must be killed by a + // subsequent instruction. Hence its interval is: + // [defSlot(def), useSlot(kill)+1) + while (true) { + ++mi; + assert(mi != MBB->end() && "physreg was not killed in defining block!"); + baseIndex += InstrSlots::NUM; + for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi); + ki != ke; ++ki) { + if (interval.reg == ki->second) { + DEBUG(std::cerr << " killed"); + end = getUseIndex(baseIndex) + 1; + goto exit; + } } + } exit: - assert(start < end && "did not find end of interval?"); - LiveRange LR(start, end, interval.getNextValue()); - interval.addRange(LR); - DEBUG(std::cerr << " +" << LR << '\n'); + assert(start < end && "did not find end of interval?"); + LiveRange LR(start, end, interval.getNextValue()); + interval.addRange(LR); + DEBUG(std::cerr << " +" << LR << '\n'); } void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB, @@ -498,35 +497,35 @@ /// which a variable is live void LiveIntervals::computeIntervals() { - DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n"); - DEBUG(std::cerr << "********** Function: " - << ((Value*)mf_->getFunction())->getName() << '\n'); - - for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); - I != E; ++I) { - MachineBasicBlock* mbb = I; - DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n"); - - for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); - mi != miEnd; ++mi) { - const TargetInstrDescriptor& tid = - tm_->getInstrInfo()->get(mi->getOpcode()); - DEBUG(std::cerr << getInstructionIndex(mi) << "\t"; - mi->print(std::cerr, tm_)); - - // handle implicit defs - for (const unsigned* id = tid.ImplicitDefs; *id; ++id) - handleRegisterDef(mbb, mi, *id); - - // handle explicit defs - for (int i = mi->getNumOperands() - 1; i >= 0; --i) { - MachineOperand& mop = mi->getOperand(i); - // handle register defs - build intervals - if (mop.isRegister() && mop.getReg() && mop.isDef()) - handleRegisterDef(mbb, mi, mop.getReg()); - } - } + DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n"); + DEBUG(std::cerr << "********** Function: " + << ((Value*)mf_->getFunction())->getName() << '\n'); + + for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); + I != E; ++I) { + MachineBasicBlock* mbb = I; + DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n"); + + for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); + mi != miEnd; ++mi) { + const TargetInstrDescriptor& tid = + tm_->getInstrInfo()->get(mi->getOpcode()); + DEBUG(std::cerr << getInstructionIndex(mi) << "\t"; + mi->print(std::cerr, tm_)); + + // handle implicit defs + for (const unsigned* id = tid.ImplicitDefs; *id; ++id) + handleRegisterDef(mbb, mi, *id); + + // handle explicit defs + for (int i = mi->getNumOperands() - 1; i >= 0; --i) { + MachineOperand& mop = mi->getOperand(i); + // handle register defs - build intervals + if (mop.isRegister() && mop.getReg() && mop.isDef()) + handleRegisterDef(mbb, mi, mop.getReg()); + } } + } } void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { @@ -543,9 +542,9 @@ unsigned regA, regB; if (TII.isMoveInstr(*mi, regA, regB) && (MRegisterInfo::isVirtualRegister(regA) || - lv_->getAllocatablePhysicalRegisters()[regA]) && + lv_->getAllocatablePhysicalRegisters()[regA]) && (MRegisterInfo::isVirtualRegister(regB) || - lv_->getAllocatablePhysicalRegisters()[regB])) { + lv_->getAllocatablePhysicalRegisters()[regB])) { // Get representative registers. regA = rep(regA); @@ -609,7 +608,7 @@ bool operator()(const DepthMBBPair &LHS, const DepthMBBPair &RHS) const { if (LHS.first > RHS.first) return true; // Deeper loops first return LHS.first == RHS.first && - LHS.second->getNumber() < RHS.second->getNumber(); + LHS.second->getNumber() < RHS.second->getNumber(); } }; } @@ -642,8 +641,8 @@ DEBUG(std::cerr << "*** Register mapping ***\n"); DEBUG(for (std::map::iterator I = r2rMap_.begin(), - E = r2rMap_.end(); I != E; ++I) - std::cerr << " reg " << I->first << " -> reg " << I->second << "\n";); + E = r2rMap_.end(); I != E; ++I) + std::cerr << " reg " << I->first << " -> reg " << I->second << "\n";); } /// Return true if the two specified registers belong to different register From alkis at cs.uiuc.edu Wed Aug 4 04:46:37 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:46:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp RegAllocIterativeScan.cpp Message-ID: <200408040946.EAA26401@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.86 -> 1.87 RegAllocIterativeScan.cpp updated: 1.10 -> 1.11 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+818 -818) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.86 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.87 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.86 Sun Jul 25 03:10:33 2004 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Wed Aug 4 04:46:26 2004 @@ -35,502 +35,502 @@ namespace { - Statistic efficiency - ("regalloc", "Ratio of intervals processed over total intervals"); + Statistic efficiency + ("regalloc", "Ratio of intervals processed over total intervals"); - static unsigned numIterations = 0; - static unsigned numIntervals = 0; + static unsigned numIterations = 0; + static unsigned numIntervals = 0; - class RA : public MachineFunctionPass { - private: - MachineFunction* mf_; - const TargetMachine* tm_; - const MRegisterInfo* mri_; - LiveIntervals* li_; - typedef std::vector IntervalPtrs; - IntervalPtrs handled_, fixed_, active_, inactive_; - typedef std::priority_queue > IntervalHeap; - IntervalHeap unhandled_; - std::auto_ptr prt_; - std::auto_ptr vrm_; - std::auto_ptr spiller_; - - typedef std::vector SpillWeights; - SpillWeights spillWeights_; - - public: - virtual const char* getPassName() const { - return "Linear Scan Register Allocator"; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addRequired(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - /// runOnMachineFunction - register allocate the whole function - bool runOnMachineFunction(MachineFunction&); - - void releaseMemory(); - - private: - /// linearScan - the linear scan algorithm - void linearScan(); - - /// initIntervalSets - initializa the four interval sets: - /// unhandled, fixed, active and inactive - void initIntervalSets(); - - /// processActiveIntervals - expire old intervals and move - /// non-overlapping ones to the incative list - void processActiveIntervals(LiveInterval* cur); - - /// processInactiveIntervals - expire old intervals and move - /// overlapping ones to the active list - void processInactiveIntervals(LiveInterval* cur); - - /// updateSpillWeights - updates the spill weights of the - /// specifed physical register and its weight - void updateSpillWeights(unsigned reg, SpillWeights::value_type weight); - - /// assignRegOrStackSlotAtInterval - assign a register if one - /// is available, or spill. - void assignRegOrStackSlotAtInterval(LiveInterval* cur); - - /// - /// register handling helpers - /// - - /// getFreePhysReg - return a free physical register for this - /// virtual register interval if we have one, otherwise return - /// 0 - unsigned getFreePhysReg(LiveInterval* cur); - - /// assignVirt2StackSlot - assigns this virtual register to a - /// stack slot. returns the stack slot - int assignVirt2StackSlot(unsigned virtReg); - - template - void printIntervals(const char* const str, ItTy i, ItTy e) const { - if (str) std::cerr << str << " intervals:\n"; - for (; i != e; ++i) { - std::cerr << "\t" << **i << " -> "; - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) { - reg = vrm_->getPhys(reg); - } - std::cerr << mri_->getName(reg) << '\n'; - } + class RA : public MachineFunctionPass { + private: + MachineFunction* mf_; + const TargetMachine* tm_; + const MRegisterInfo* mri_; + LiveIntervals* li_; + typedef std::vector IntervalPtrs; + IntervalPtrs handled_, fixed_, active_, inactive_; + typedef std::priority_queue > IntervalHeap; + IntervalHeap unhandled_; + std::auto_ptr prt_; + std::auto_ptr vrm_; + std::auto_ptr spiller_; + + typedef std::vector SpillWeights; + SpillWeights spillWeights_; + + public: + virtual const char* getPassName() const { + return "Linear Scan Register Allocator"; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + /// runOnMachineFunction - register allocate the whole function + bool runOnMachineFunction(MachineFunction&); + + void releaseMemory(); + + private: + /// linearScan - the linear scan algorithm + void linearScan(); + + /// initIntervalSets - initializa the four interval sets: + /// unhandled, fixed, active and inactive + void initIntervalSets(); + + /// processActiveIntervals - expire old intervals and move + /// non-overlapping ones to the incative list + void processActiveIntervals(LiveInterval* cur); + + /// processInactiveIntervals - expire old intervals and move + /// overlapping ones to the active list + void processInactiveIntervals(LiveInterval* cur); + + /// updateSpillWeights - updates the spill weights of the + /// specifed physical register and its weight + void updateSpillWeights(unsigned reg, SpillWeights::value_type weight); + + /// assignRegOrStackSlotAtInterval - assign a register if one + /// is available, or spill. + void assignRegOrStackSlotAtInterval(LiveInterval* cur); + + /// + /// register handling helpers + /// + + /// getFreePhysReg - return a free physical register for this + /// virtual register interval if we have one, otherwise return + /// 0 + unsigned getFreePhysReg(LiveInterval* cur); + + /// assignVirt2StackSlot - assigns this virtual register to a + /// stack slot. returns the stack slot + int assignVirt2StackSlot(unsigned virtReg); + + template + void printIntervals(const char* const str, ItTy i, ItTy e) const { + if (str) std::cerr << str << " intervals:\n"; + for (; i != e; ++i) { + std::cerr << "\t" << **i << " -> "; + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) { + reg = vrm_->getPhys(reg); } - }; + std::cerr << mri_->getName(reg) << '\n'; + } + } + }; } void RA::releaseMemory() { - while (!unhandled_.empty()) unhandled_.pop(); - fixed_.clear(); - active_.clear(); - inactive_.clear(); - handled_.clear(); + while (!unhandled_.empty()) unhandled_.pop(); + fixed_.clear(); + active_.clear(); + inactive_.clear(); + handled_.clear(); } bool RA::runOnMachineFunction(MachineFunction &fn) { - mf_ = &fn; - tm_ = &fn.getTarget(); - mri_ = tm_->getRegisterInfo(); - li_ = &getAnalysis(); - if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); - vrm_.reset(new VirtRegMap(*mf_)); - if (!spiller_.get()) spiller_.reset(createSpiller()); + mf_ = &fn; + tm_ = &fn.getTarget(); + mri_ = tm_->getRegisterInfo(); + li_ = &getAnalysis(); + if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); + vrm_.reset(new VirtRegMap(*mf_)); + if (!spiller_.get()) spiller_.reset(createSpiller()); - initIntervalSets(); + initIntervalSets(); - linearScan(); + linearScan(); - spiller_->runOnMachineFunction(*mf_, *vrm_); + spiller_->runOnMachineFunction(*mf_, *vrm_); - return true; + return true; } void RA::linearScan() { - // linear scan algorithm - DEBUG(std::cerr << "********** LINEAR SCAN **********\n"); - DEBUG(std::cerr << "********** Function: " - << mf_->getFunction()->getName() << '\n'); + // linear scan algorithm + DEBUG(std::cerr << "********** LINEAR SCAN **********\n"); + DEBUG(std::cerr << "********** Function: " + << mf_->getFunction()->getName() << '\n'); + + // DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end())); + DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end())); + DEBUG(printIntervals("active", active_.begin(), active_.end())); + DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); + + while (!unhandled_.empty()) { + // pick the interval with the earliest start point + LiveInterval* cur = unhandled_.top(); + unhandled_.pop(); + ++numIterations; + DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n'); + + processActiveIntervals(cur); + processInactiveIntervals(cur); + + // if this register is fixed we are done + if (MRegisterInfo::isPhysicalRegister(cur->reg)) { + prt_->addRegUse(cur->reg); + active_.push_back(cur); + handled_.push_back(cur); + } + // otherwise we are allocating a virtual register. try to find + // a free physical register or spill an interval in order to + // assign it one (we could spill the current though). + else { + assignRegOrStackSlotAtInterval(cur); + } - // DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end())); - DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end())); DEBUG(printIntervals("active", active_.begin(), active_.end())); DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); + } + numIntervals += li_->getNumIntervals(); + efficiency = double(numIterations) / double(numIntervals); + + // expire any remaining active intervals + for (IntervalPtrs::reverse_iterator + i = active_.rbegin(); i != active_.rend(); ) { + unsigned reg = (*i)->reg; + DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); + } + + // expire any remaining inactive intervals + for (IntervalPtrs::reverse_iterator + i = inactive_.rbegin(); i != inactive_.rend(); ) { + DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); + } - while (!unhandled_.empty()) { - // pick the interval with the earliest start point - LiveInterval* cur = unhandled_.top(); - unhandled_.pop(); - ++numIterations; - DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n'); - - processActiveIntervals(cur); - processInactiveIntervals(cur); - - // if this register is fixed we are done - if (MRegisterInfo::isPhysicalRegister(cur->reg)) { - prt_->addRegUse(cur->reg); - active_.push_back(cur); - handled_.push_back(cur); - } - // otherwise we are allocating a virtual register. try to find - // a free physical register or spill an interval in order to - // assign it one (we could spill the current though). - else { - assignRegOrStackSlotAtInterval(cur); - } - - DEBUG(printIntervals("active", active_.begin(), active_.end())); - DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); - } - numIntervals += li_->getNumIntervals(); - efficiency = double(numIterations) / double(numIntervals); - - // expire any remaining active intervals - for (IntervalPtrs::reverse_iterator - i = active_.rbegin(); i != active_.rend(); ) { - unsigned reg = (*i)->reg; - DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - - // expire any remaining inactive intervals - for (IntervalPtrs::reverse_iterator - i = inactive_.rbegin(); i != inactive_.rend(); ) { - DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - - DEBUG(std::cerr << *vrm_); + DEBUG(std::cerr << *vrm_); } void RA::initIntervalSets() { - assert(unhandled_.empty() && fixed_.empty() && - active_.empty() && inactive_.empty() && - "interval sets should be empty on initialization"); - - for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){ - unhandled_.push(&i->second); - if (MRegisterInfo::isPhysicalRegister(i->second.reg)) - fixed_.push_back(&i->second); - } + assert(unhandled_.empty() && fixed_.empty() && + active_.empty() && inactive_.empty() && + "interval sets should be empty on initialization"); + + for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){ + unhandled_.push(&i->second); + if (MRegisterInfo::isPhysicalRegister(i->second.reg)) + fixed_.push_back(&i->second); + } } void RA::processActiveIntervals(IntervalPtrs::value_type cur) { - DEBUG(std::cerr << "\tprocessing active intervals:\n"); - for (IntervalPtrs::reverse_iterator - i = active_.rbegin(); i != active_.rend();) { - unsigned reg = (*i)->reg; - // remove expired intervals - if ((*i)->expiredAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - // remove from active - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - // move inactive intervals to inactive list - else if (!(*i)->liveAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " inactive\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - // add to inactive - inactive_.push_back(*i); - // remove from active - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - else { - ++i; - } + DEBUG(std::cerr << "\tprocessing active intervals:\n"); + for (IntervalPtrs::reverse_iterator + i = active_.rbegin(); i != active_.rend();) { + unsigned reg = (*i)->reg; + // remove expired intervals + if ((*i)->expiredAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + // remove from active + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); + } + // move inactive intervals to inactive list + else if (!(*i)->liveAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " inactive\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + // add to inactive + inactive_.push_back(*i); + // remove from active + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); + } + else { + ++i; } + } } void RA::processInactiveIntervals(IntervalPtrs::value_type cur) { - DEBUG(std::cerr << "\tprocessing inactive intervals:\n"); - for (IntervalPtrs::reverse_iterator - i = inactive_.rbegin(); i != inactive_.rend();) { - unsigned reg = (*i)->reg; - - // remove expired intervals - if ((*i)->expiredAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - // remove from inactive - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - // move re-activated intervals in active list - else if ((*i)->liveAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " active\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->addRegUse(reg); - // add to active - active_.push_back(*i); - // remove from inactive - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - else { - ++i; - } + DEBUG(std::cerr << "\tprocessing inactive intervals:\n"); + for (IntervalPtrs::reverse_iterator + i = inactive_.rbegin(); i != inactive_.rend();) { + unsigned reg = (*i)->reg; + + // remove expired intervals + if ((*i)->expiredAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); + // remove from inactive + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); + } + // move re-activated intervals in active list + else if ((*i)->liveAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " active\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->addRegUse(reg); + // add to active + active_.push_back(*i); + // remove from inactive + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); } + else { + ++i; + } + } } void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight) { - spillWeights_[reg] += weight; - for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) - spillWeights_[*as] += weight; + spillWeights_[reg] += weight; + for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) + spillWeights_[*as] += weight; } void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur) { - DEBUG(std::cerr << "\tallocating current interval: "); - - PhysRegTracker backupPrt = *prt_; + DEBUG(std::cerr << "\tallocating current interval: "); - spillWeights_.assign(mri_->getNumRegs(), 0.0); - - // for each interval in active update spill weights - for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end(); - i != e; ++i) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - updateSpillWeights(reg, (*i)->weight); - } + PhysRegTracker backupPrt = *prt_; - // for every interval in inactive we overlap with, mark the - // register as not free and update spill weights - for (IntervalPtrs::const_iterator i = inactive_.begin(), - e = inactive_.end(); i != e; ++i) { - if (cur->overlaps(**i)) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->addRegUse(reg); - updateSpillWeights(reg, (*i)->weight); - } - } + spillWeights_.assign(mri_->getNumRegs(), 0.0); - // for every interval in fixed we overlap with, - // mark the register as not free and update spill weights - for (IntervalPtrs::const_iterator i = fixed_.begin(), - e = fixed_.end(); i != e; ++i) { - if (cur->overlaps(**i)) { - unsigned reg = (*i)->reg; - prt_->addRegUse(reg); - updateSpillWeights(reg, (*i)->weight); - } - } - - unsigned physReg = getFreePhysReg(cur); - // restore the physical register tracker - *prt_ = backupPrt; - // if we find a free register, we are done: assign this virtual to - // the free physical register and add this interval to the active - // list. - if (physReg) { - DEBUG(std::cerr << mri_->getName(physReg) << '\n'); - vrm_->assignVirt2Phys(cur->reg, physReg); - prt_->addRegUse(physReg); - active_.push_back(cur); - handled_.push_back(cur); - return; - } - DEBUG(std::cerr << "no free registers\n"); - - DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n"); - - float minWeight = HUGE_VAL; - unsigned minReg = 0; - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); - for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); - i != rc->allocation_order_end(*mf_); ++i) { - unsigned reg = *i; - if (minWeight > spillWeights_[reg]) { - minWeight = spillWeights_[reg]; - minReg = reg; - } - } - DEBUG(std::cerr << "\t\tregister with min weight: " - << mri_->getName(minReg) << " (" << minWeight << ")\n"); - - // if the current has the minimum weight, we need to spill it and - // add any added intervals back to unhandled, and restart - // linearscan. - if (cur->weight <= minWeight) { - DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); - int slot = vrm_->assignVirt2StackSlot(cur->reg); - std::vector added = - li_->addIntervalsForSpills(*cur, *vrm_, slot); - if (added.empty()) - return; // Early exit if all spills were folded. - - // Merge added with unhandled. Note that we know that - // addIntervalsForSpills returns intervals sorted by their starting - // point. - for (unsigned i = 0, e = added.size(); i != e; ++i) - unhandled_.push(added[i]); - return; - } - - // push the current interval back to unhandled since we are going - // to re-run at least this iteration. Since we didn't modify it it - // should go back right in the front of the list - unhandled_.push(cur); - - // otherwise we spill all intervals aliasing the register with - // minimum weight, rollback to the interval with the earliest - // start point and let the linear scan algorithm run again - std::vector added; - assert(MRegisterInfo::isPhysicalRegister(minReg) && - "did not choose a register to spill?"); - std::vector toSpill(mri_->getNumRegs(), false); - // we are going to spill minReg and all its aliases - toSpill[minReg] = true; - for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as) - toSpill[*as] = true; - - // the earliest start of a spilled interval indicates up to where - // in handled we need to roll back - unsigned earliestStart = cur->start(); - - // set of spilled vregs (used later to rollback properly) - std::set spilled; - - // spill live intervals of virtual regs mapped to the physical - // register we want to clear (and its aliases). we only spill - // those that overlap with the current interval as the rest do not - // affect its allocation. we also keep track of the earliest start - // of all spilled live intervals since this will mark our rollback - // point - for (IntervalPtrs::iterator - i = active_.begin(); i != active_.end(); ++i) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg) && - toSpill[vrm_->getPhys(reg)] && - cur->overlaps(**i)) { - DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n'); - earliestStart = std::min(earliestStart, (*i)->start()); - int slot = vrm_->assignVirt2StackSlot((*i)->reg); - std::vector newIs = - li_->addIntervalsForSpills(**i, *vrm_, slot); - std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); - spilled.insert(reg); - } - } - for (IntervalPtrs::iterator - i = inactive_.begin(); i != inactive_.end(); ++i) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg) && - toSpill[vrm_->getPhys(reg)] && - cur->overlaps(**i)) { - DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n'); - earliestStart = std::min(earliestStart, (*i)->start()); - int slot = vrm_->assignVirt2StackSlot((*i)->reg); - std::vector newIs = - li_->addIntervalsForSpills(**i, *vrm_, slot); - std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); - spilled.insert(reg); - } - } - - DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n'); - // scan handled in reverse order up to the earliaset start of a - // spilled live interval and undo each one, restoring the state of - // unhandled - while (!handled_.empty()) { - LiveInterval* i = handled_.back(); - // if this interval starts before t we are done - if (i->start() < earliestStart) - break; - DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n'); - handled_.pop_back(); - // when undoing a live interval allocation we must know if it - // is active or inactive to properly update the PhysRegTracker - // and the VirtRegMap - IntervalPtrs::iterator it; - if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) { - active_.erase(it); - if (MRegisterInfo::isPhysicalRegister(i->reg)) { - prt_->delRegUse(i->reg); - unhandled_.push(i); - } - else { - if (!spilled.count(i->reg)) - unhandled_.push(i); - prt_->delRegUse(vrm_->getPhys(i->reg)); - vrm_->clearVirt(i->reg); - } - } - else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) { - inactive_.erase(it); - if (MRegisterInfo::isPhysicalRegister(i->reg)) - unhandled_.push(i); - else { - if (!spilled.count(i->reg)) - unhandled_.push(i); - vrm_->clearVirt(i->reg); - } - } - else { - if (MRegisterInfo::isVirtualRegister(i->reg)) - vrm_->clearVirt(i->reg); - unhandled_.push(i); - } - } - - // scan the rest and undo each interval that expired after t and - // insert it in active (the next iteration of the algorithm will - // put it in inactive if required) - IntervalPtrs::iterator i = handled_.begin(), e = handled_.end(); - for (; i != e; ++i) { - if (!(*i)->expiredAt(earliestStart) && (*i)->expiredAt(cur->start())) { - DEBUG(std::cerr << "\t\t\tundo changes for: " << **i << '\n'); - active_.push_back(*i); - if (MRegisterInfo::isPhysicalRegister((*i)->reg)) - prt_->addRegUse((*i)->reg); - else - prt_->addRegUse(vrm_->getPhys((*i)->reg)); - } - } - - std::sort(added.begin(), added.end(), less_ptr()); - // merge added with unhandled + // for each interval in active update spill weights + for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end(); + i != e; ++i) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + updateSpillWeights(reg, (*i)->weight); + } + + // for every interval in inactive we overlap with, mark the + // register as not free and update spill weights + for (IntervalPtrs::const_iterator i = inactive_.begin(), + e = inactive_.end(); i != e; ++i) { + if (cur->overlaps(**i)) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->addRegUse(reg); + updateSpillWeights(reg, (*i)->weight); + } + } + + // for every interval in fixed we overlap with, + // mark the register as not free and update spill weights + for (IntervalPtrs::const_iterator i = fixed_.begin(), + e = fixed_.end(); i != e; ++i) { + if (cur->overlaps(**i)) { + unsigned reg = (*i)->reg; + prt_->addRegUse(reg); + updateSpillWeights(reg, (*i)->weight); + } + } + + unsigned physReg = getFreePhysReg(cur); + // restore the physical register tracker + *prt_ = backupPrt; + // if we find a free register, we are done: assign this virtual to + // the free physical register and add this interval to the active + // list. + if (physReg) { + DEBUG(std::cerr << mri_->getName(physReg) << '\n'); + vrm_->assignVirt2Phys(cur->reg, physReg); + prt_->addRegUse(physReg); + active_.push_back(cur); + handled_.push_back(cur); + return; + } + DEBUG(std::cerr << "no free registers\n"); + + DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n"); + + float minWeight = HUGE_VAL; + unsigned minReg = 0; + const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); + for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); + i != rc->allocation_order_end(*mf_); ++i) { + unsigned reg = *i; + if (minWeight > spillWeights_[reg]) { + minWeight = spillWeights_[reg]; + minReg = reg; + } + } + DEBUG(std::cerr << "\t\tregister with min weight: " + << mri_->getName(minReg) << " (" << minWeight << ")\n"); + + // if the current has the minimum weight, we need to spill it and + // add any added intervals back to unhandled, and restart + // linearscan. + if (cur->weight <= minWeight) { + DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';); + int slot = vrm_->assignVirt2StackSlot(cur->reg); + std::vector added = + li_->addIntervalsForSpills(*cur, *vrm_, slot); + if (added.empty()) + return; // Early exit if all spills were folded. + + // Merge added with unhandled. Note that we know that + // addIntervalsForSpills returns intervals sorted by their starting + // point. for (unsigned i = 0, e = added.size(); i != e; ++i) - unhandled_.push(added[i]); + unhandled_.push(added[i]); + return; + } + + // push the current interval back to unhandled since we are going + // to re-run at least this iteration. Since we didn't modify it it + // should go back right in the front of the list + unhandled_.push(cur); + + // otherwise we spill all intervals aliasing the register with + // minimum weight, rollback to the interval with the earliest + // start point and let the linear scan algorithm run again + std::vector added; + assert(MRegisterInfo::isPhysicalRegister(minReg) && + "did not choose a register to spill?"); + std::vector toSpill(mri_->getNumRegs(), false); + // we are going to spill minReg and all its aliases + toSpill[minReg] = true; + for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as) + toSpill[*as] = true; + + // the earliest start of a spilled interval indicates up to where + // in handled we need to roll back + unsigned earliestStart = cur->start(); + + // set of spilled vregs (used later to rollback properly) + std::set spilled; + + // spill live intervals of virtual regs mapped to the physical + // register we want to clear (and its aliases). we only spill + // those that overlap with the current interval as the rest do not + // affect its allocation. we also keep track of the earliest start + // of all spilled live intervals since this will mark our rollback + // point + for (IntervalPtrs::iterator + i = active_.begin(); i != active_.end(); ++i) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg) && + toSpill[vrm_->getPhys(reg)] && + cur->overlaps(**i)) { + DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n'); + earliestStart = std::min(earliestStart, (*i)->start()); + int slot = vrm_->assignVirt2StackSlot((*i)->reg); + std::vector newIs = + li_->addIntervalsForSpills(**i, *vrm_, slot); + std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); + spilled.insert(reg); + } + } + for (IntervalPtrs::iterator + i = inactive_.begin(); i != inactive_.end(); ++i) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg) && + toSpill[vrm_->getPhys(reg)] && + cur->overlaps(**i)) { + DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n'); + earliestStart = std::min(earliestStart, (*i)->start()); + int slot = vrm_->assignVirt2StackSlot((*i)->reg); + std::vector newIs = + li_->addIntervalsForSpills(**i, *vrm_, slot); + std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); + spilled.insert(reg); + } + } + + DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n'); + // scan handled in reverse order up to the earliaset start of a + // spilled live interval and undo each one, restoring the state of + // unhandled + while (!handled_.empty()) { + LiveInterval* i = handled_.back(); + // if this interval starts before t we are done + if (i->start() < earliestStart) + break; + DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n'); + handled_.pop_back(); + // when undoing a live interval allocation we must know if it + // is active or inactive to properly update the PhysRegTracker + // and the VirtRegMap + IntervalPtrs::iterator it; + if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) { + active_.erase(it); + if (MRegisterInfo::isPhysicalRegister(i->reg)) { + prt_->delRegUse(i->reg); + unhandled_.push(i); + } + else { + if (!spilled.count(i->reg)) + unhandled_.push(i); + prt_->delRegUse(vrm_->getPhys(i->reg)); + vrm_->clearVirt(i->reg); + } + } + else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) { + inactive_.erase(it); + if (MRegisterInfo::isPhysicalRegister(i->reg)) + unhandled_.push(i); + else { + if (!spilled.count(i->reg)) + unhandled_.push(i); + vrm_->clearVirt(i->reg); + } + } + else { + if (MRegisterInfo::isVirtualRegister(i->reg)) + vrm_->clearVirt(i->reg); + unhandled_.push(i); + } + } + + // scan the rest and undo each interval that expired after t and + // insert it in active (the next iteration of the algorithm will + // put it in inactive if required) + IntervalPtrs::iterator i = handled_.begin(), e = handled_.end(); + for (; i != e; ++i) { + if (!(*i)->expiredAt(earliestStart) && (*i)->expiredAt(cur->start())) { + DEBUG(std::cerr << "\t\t\tundo changes for: " << **i << '\n'); + active_.push_back(*i); + if (MRegisterInfo::isPhysicalRegister((*i)->reg)) + prt_->addRegUse((*i)->reg); + else + prt_->addRegUse(vrm_->getPhys((*i)->reg)); + } + } + + std::sort(added.begin(), added.end(), less_ptr()); + // merge added with unhandled + for (unsigned i = 0, e = added.size(); i != e; ++i) + unhandled_.push(added[i]); } unsigned RA::getFreePhysReg(LiveInterval* cur) { - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); + const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); - for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); - i != rc->allocation_order_end(*mf_); ++i) { - unsigned reg = *i; - if (prt_->isRegAvail(reg)) - return reg; - } - return 0; + for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); + i != rc->allocation_order_end(*mf_); ++i) { + unsigned reg = *i; + if (prt_->isRegAvail(reg)) + return reg; + } + return 0; } FunctionPass* llvm::createLinearScanRegisterAllocator() { - return new RA(); + return new RA(); } Index: llvm/lib/CodeGen/RegAllocIterativeScan.cpp diff -u llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.10 llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.11 --- llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.10 Sat Jul 24 06:44:15 2004 +++ llvm/lib/CodeGen/RegAllocIterativeScan.cpp Wed Aug 4 04:46:26 2004 @@ -40,439 +40,439 @@ namespace { - Statistic efficiency - ("regalloc", "Ratio of intervals processed over total intervals"); + Statistic efficiency + ("regalloc", "Ratio of intervals processed over total intervals"); - static unsigned numIterations = 0; - static unsigned numIntervals = 0; + static unsigned numIterations = 0; + static unsigned numIntervals = 0; - class RA : public MachineFunctionPass { - private: - MachineFunction* mf_; - const TargetMachine* tm_; - const MRegisterInfo* mri_; - LiveIntervals* li_; - typedef std::vector IntervalPtrs; - IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_; - - std::auto_ptr prt_; - std::auto_ptr vrm_; - std::auto_ptr spiller_; - - typedef std::vector SpillWeights; - SpillWeights spillWeights_; - - public: - virtual const char* getPassName() const { - return "Iterative Scan Register Allocator"; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addRequired(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - /// runOnMachineFunction - register allocate the whole function - bool runOnMachineFunction(MachineFunction&); - - void releaseMemory(); - - private: - /// linearScan - the linear scan algorithm. Returns a boolean - /// indicating if there were any spills - bool linearScan(); - - /// initIntervalSets - initializes the four interval sets: - /// unhandled, fixed, active and inactive - void initIntervalSets(); - - /// processActiveIntervals - expire old intervals and move - /// non-overlapping ones to the incative list - void processActiveIntervals(IntervalPtrs::value_type cur); - - /// processInactiveIntervals - expire old intervals and move - /// overlapping ones to the active list - void processInactiveIntervals(IntervalPtrs::value_type cur); - - /// updateSpillWeights - updates the spill weights of the - /// specifed physical register and its weight - void updateSpillWeights(unsigned reg, SpillWeights::value_type weight); - - /// assignRegOrStackSlotAtInterval - assign a register if one - /// is available, or spill. - void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur); - - /// - /// register handling helpers - /// - - /// getFreePhysReg - return a free physical register for this - /// virtual register interval if we have one, otherwise return - /// 0 - unsigned getFreePhysReg(IntervalPtrs::value_type cur); - - /// assignVirt2StackSlot - assigns this virtual register to a - /// stack slot. returns the stack slot - int assignVirt2StackSlot(unsigned virtReg); - - void printIntervals(const char* const str, - RA::IntervalPtrs::const_iterator i, - RA::IntervalPtrs::const_iterator e) const { - if (str) std::cerr << str << " intervals:\n"; - for (; i != e; ++i) { - std::cerr << "\t" << **i << " -> "; - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) { - reg = vrm_->getPhys(reg); - } - std::cerr << mri_->getName(reg) << '\n'; - } + class RA : public MachineFunctionPass { + private: + MachineFunction* mf_; + const TargetMachine* tm_; + const MRegisterInfo* mri_; + LiveIntervals* li_; + typedef std::vector IntervalPtrs; + IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_; + + std::auto_ptr prt_; + std::auto_ptr vrm_; + std::auto_ptr spiller_; + + typedef std::vector SpillWeights; + SpillWeights spillWeights_; + + public: + virtual const char* getPassName() const { + return "Iterative Scan Register Allocator"; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + /// runOnMachineFunction - register allocate the whole function + bool runOnMachineFunction(MachineFunction&); + + void releaseMemory(); + + private: + /// linearScan - the linear scan algorithm. Returns a boolean + /// indicating if there were any spills + bool linearScan(); + + /// initIntervalSets - initializes the four interval sets: + /// unhandled, fixed, active and inactive + void initIntervalSets(); + + /// processActiveIntervals - expire old intervals and move + /// non-overlapping ones to the incative list + void processActiveIntervals(IntervalPtrs::value_type cur); + + /// processInactiveIntervals - expire old intervals and move + /// overlapping ones to the active list + void processInactiveIntervals(IntervalPtrs::value_type cur); + + /// updateSpillWeights - updates the spill weights of the + /// specifed physical register and its weight + void updateSpillWeights(unsigned reg, SpillWeights::value_type weight); + + /// assignRegOrStackSlotAtInterval - assign a register if one + /// is available, or spill. + void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur); + + /// + /// register handling helpers + /// + + /// getFreePhysReg - return a free physical register for this + /// virtual register interval if we have one, otherwise return + /// 0 + unsigned getFreePhysReg(IntervalPtrs::value_type cur); + + /// assignVirt2StackSlot - assigns this virtual register to a + /// stack slot. returns the stack slot + int assignVirt2StackSlot(unsigned virtReg); + + void printIntervals(const char* const str, + RA::IntervalPtrs::const_iterator i, + RA::IntervalPtrs::const_iterator e) const { + if (str) std::cerr << str << " intervals:\n"; + for (; i != e; ++i) { + std::cerr << "\t" << **i << " -> "; + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) { + reg = vrm_->getPhys(reg); } - }; + std::cerr << mri_->getName(reg) << '\n'; + } + } + }; } void RA::releaseMemory() { - unhandled_.clear(); - fixed_.clear(); - active_.clear(); - inactive_.clear(); - handled_.clear(); - spilled_.clear(); + unhandled_.clear(); + fixed_.clear(); + active_.clear(); + inactive_.clear(); + handled_.clear(); + spilled_.clear(); } bool RA::runOnMachineFunction(MachineFunction &fn) { - mf_ = &fn; - tm_ = &fn.getTarget(); - mri_ = tm_->getRegisterInfo(); - li_ = &getAnalysis(); - if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); - vrm_.reset(new VirtRegMap(*mf_)); - if (!spiller_.get()) spiller_.reset(createSpiller()); - - initIntervalSets(); - - numIntervals += li_->getNumIntervals(); - - while (linearScan()) { - // we spilled some registers, so we need to add intervals for - // the spill code and restart the algorithm - std::set spilledRegs; - for (IntervalPtrs::iterator - i = spilled_.begin(); i != spilled_.end(); ++i) { - int slot = vrm_->assignVirt2StackSlot((*i)->reg); - std::vector added = - li_->addIntervalsForSpills(**i, *vrm_, slot); - std::copy(added.begin(), added.end(), std::back_inserter(handled_)); - spilledRegs.insert((*i)->reg); - } - spilled_.clear(); - for (IntervalPtrs::iterator - i = handled_.begin(); i != handled_.end(); ) - if (spilledRegs.count((*i)->reg)) - i = handled_.erase(i); - else - ++i; - handled_.swap(unhandled_); - vrm_->clearAllVirt(); + mf_ = &fn; + tm_ = &fn.getTarget(); + mri_ = tm_->getRegisterInfo(); + li_ = &getAnalysis(); + if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_)); + vrm_.reset(new VirtRegMap(*mf_)); + if (!spiller_.get()) spiller_.reset(createSpiller()); + + initIntervalSets(); + + numIntervals += li_->getNumIntervals(); + + while (linearScan()) { + // we spilled some registers, so we need to add intervals for + // the spill code and restart the algorithm + std::set spilledRegs; + for (IntervalPtrs::iterator + i = spilled_.begin(); i != spilled_.end(); ++i) { + int slot = vrm_->assignVirt2StackSlot((*i)->reg); + std::vector added = + li_->addIntervalsForSpills(**i, *vrm_, slot); + std::copy(added.begin(), added.end(), std::back_inserter(handled_)); + spilledRegs.insert((*i)->reg); } + spilled_.clear(); + for (IntervalPtrs::iterator + i = handled_.begin(); i != handled_.end(); ) + if (spilledRegs.count((*i)->reg)) + i = handled_.erase(i); + else + ++i; + handled_.swap(unhandled_); + vrm_->clearAllVirt(); + } - efficiency = double(numIterations) / double(numIntervals); + efficiency = double(numIterations) / double(numIntervals); - DEBUG(std::cerr << *vrm_); + DEBUG(std::cerr << *vrm_); - spiller_->runOnMachineFunction(*mf_, *vrm_); + spiller_->runOnMachineFunction(*mf_, *vrm_); - return true; + return true; } bool RA::linearScan() { - // linear scan algorithm - DEBUG(std::cerr << "********** LINEAR SCAN **********\n"); - DEBUG(std::cerr << "********** Function: " - << mf_->getFunction()->getName() << '\n'); - + // linear scan algorithm + DEBUG(std::cerr << "********** LINEAR SCAN **********\n"); + DEBUG(std::cerr << "********** Function: " + << mf_->getFunction()->getName() << '\n'); + + + std::sort(unhandled_.begin(), unhandled_.end(), + greater_ptr()); + DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end())); + DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end())); + DEBUG(printIntervals("active", active_.begin(), active_.end())); + DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); + + while (!unhandled_.empty()) { + // pick the interval with the earliest start point + IntervalPtrs::value_type cur = unhandled_.back(); + unhandled_.pop_back(); + ++numIterations; + DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n'); + + processActiveIntervals(cur); + processInactiveIntervals(cur); + + // if this register is fixed we are done + if (MRegisterInfo::isPhysicalRegister(cur->reg)) { + prt_->addRegUse(cur->reg); + active_.push_back(cur); + handled_.push_back(cur); + } + // otherwise we are allocating a virtual register. try to find + // a free physical register or spill an interval in order to + // assign it one (we could spill the current though). + else { + assignRegOrSpillAtInterval(cur); + } - std::sort(unhandled_.begin(), unhandled_.end(), - greater_ptr()); - DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end())); - DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end())); DEBUG(printIntervals("active", active_.begin(), active_.end())); DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); + } - while (!unhandled_.empty()) { - // pick the interval with the earliest start point - IntervalPtrs::value_type cur = unhandled_.back(); - unhandled_.pop_back(); - ++numIterations; - DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n'); - - processActiveIntervals(cur); - processInactiveIntervals(cur); - - // if this register is fixed we are done - if (MRegisterInfo::isPhysicalRegister(cur->reg)) { - prt_->addRegUse(cur->reg); - active_.push_back(cur); - handled_.push_back(cur); - } - // otherwise we are allocating a virtual register. try to find - // a free physical register or spill an interval in order to - // assign it one (we could spill the current though). - else { - assignRegOrSpillAtInterval(cur); - } + // expire any remaining active intervals + for (IntervalPtrs::reverse_iterator + i = active_.rbegin(); i != active_.rend(); ) { + unsigned reg = (*i)->reg; + DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); + } + + // expire any remaining inactive intervals + for (IntervalPtrs::reverse_iterator + i = inactive_.rbegin(); i != inactive_.rend(); ) { + DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); + } - DEBUG(printIntervals("active", active_.begin(), active_.end())); - DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end())); - } - - // expire any remaining active intervals - for (IntervalPtrs::reverse_iterator - i = active_.rbegin(); i != active_.rend(); ) { - unsigned reg = (*i)->reg; - DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - - // expire any remaining inactive intervals - for (IntervalPtrs::reverse_iterator - i = inactive_.rbegin(); i != inactive_.rend(); ) { - DEBUG(std::cerr << "\tinterval " << **i << " expired\n"); - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - - // return true if we spilled anything - return !spilled_.empty(); + // return true if we spilled anything + return !spilled_.empty(); } void RA::initIntervalSets() { - assert(unhandled_.empty() && fixed_.empty() && - active_.empty() && inactive_.empty() && - "interval sets should be empty on initialization"); - - for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){ - unhandled_.push_back(&i->second); - if (MRegisterInfo::isPhysicalRegister(i->second.reg)) - fixed_.push_back(&i->second); - } + assert(unhandled_.empty() && fixed_.empty() && + active_.empty() && inactive_.empty() && + "interval sets should be empty on initialization"); + + for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){ + unhandled_.push_back(&i->second); + if (MRegisterInfo::isPhysicalRegister(i->second.reg)) + fixed_.push_back(&i->second); + } } void RA::processActiveIntervals(IntervalPtrs::value_type cur) { - DEBUG(std::cerr << "\tprocessing active intervals:\n"); - for (IntervalPtrs::reverse_iterator - i = active_.rbegin(); i != active_.rend();) { - unsigned reg = (*i)->reg; - // remove expired intervals - if ((*i)->expiredAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - // remove from active - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - // move inactive intervals to inactive list - else if (!(*i)->liveAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " inactive\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->delRegUse(reg); - // add to inactive - inactive_.push_back(*i); - // remove from active - i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); - } - else { - ++i; - } + DEBUG(std::cerr << "\tprocessing active intervals:\n"); + for (IntervalPtrs::reverse_iterator + i = active_.rbegin(); i != active_.rend();) { + unsigned reg = (*i)->reg; + // remove expired intervals + if ((*i)->expiredAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + // remove from active + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); + } + // move inactive intervals to inactive list + else if (!(*i)->liveAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " inactive\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->delRegUse(reg); + // add to inactive + inactive_.push_back(*i); + // remove from active + i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1)); } + else { + ++i; + } + } } void RA::processInactiveIntervals(IntervalPtrs::value_type cur) { - DEBUG(std::cerr << "\tprocessing inactive intervals:\n"); - for (IntervalPtrs::reverse_iterator - i = inactive_.rbegin(); i != inactive_.rend();) { - unsigned reg = (*i)->reg; - - // remove expired intervals - if ((*i)->expiredAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - // remove from inactive - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - // move re-activated intervals in active list - else if ((*i)->liveAt(cur->start())) { - DEBUG(std::cerr << "\t\tinterval " << **i << " active\n"); - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->addRegUse(reg); - // add to active - active_.push_back(*i); - // remove from inactive - i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); - } - else { - ++i; - } + DEBUG(std::cerr << "\tprocessing inactive intervals:\n"); + for (IntervalPtrs::reverse_iterator + i = inactive_.rbegin(); i != inactive_.rend();) { + unsigned reg = (*i)->reg; + + // remove expired intervals + if ((*i)->expiredAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); + // remove from inactive + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); + } + // move re-activated intervals in active list + else if ((*i)->liveAt(cur->start())) { + DEBUG(std::cerr << "\t\tinterval " << **i << " active\n"); + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->addRegUse(reg); + // add to active + active_.push_back(*i); + // remove from inactive + i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1)); + } + else { + ++i; } + } } void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight) { - spillWeights_[reg] += weight; - for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) - spillWeights_[*as] += weight; + spillWeights_[reg] += weight; + for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) + spillWeights_[*as] += weight; } void RA::assignRegOrSpillAtInterval(IntervalPtrs::value_type cur) { - DEBUG(std::cerr << "\tallocating current interval: "); - - PhysRegTracker backupPrt = *prt_; - - spillWeights_.assign(mri_->getNumRegs(), 0.0); - - // for each interval in active update spill weights - for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end(); - i != e; ++i) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - updateSpillWeights(reg, (*i)->weight); - } - - // for every interval in inactive we overlap with, mark the - // register as not free and update spill weights - for (IntervalPtrs::const_iterator i = inactive_.begin(), - e = inactive_.end(); i != e; ++i) { - if (cur->overlaps(**i)) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg)) - reg = vrm_->getPhys(reg); - prt_->addRegUse(reg); - updateSpillWeights(reg, (*i)->weight); - } - } - - // for every interval in fixed we overlap with, - // mark the register as not free and update spill weights - for (IntervalPtrs::const_iterator i = fixed_.begin(), - e = fixed_.end(); i != e; ++i) { - if (cur->overlaps(**i)) { - unsigned reg = (*i)->reg; - prt_->addRegUse(reg); - updateSpillWeights(reg, (*i)->weight); - } - } + DEBUG(std::cerr << "\tallocating current interval: "); - unsigned physReg = getFreePhysReg(cur); - // restore the physical register tracker - *prt_ = backupPrt; - // if we find a free register, we are done: assign this virtual to - // the free physical register and add this interval to the active - // list. - if (physReg) { - DEBUG(std::cerr << mri_->getName(physReg) << '\n'); - vrm_->assignVirt2Phys(cur->reg, physReg); - prt_->addRegUse(physReg); - active_.push_back(cur); - handled_.push_back(cur); - return; - } - DEBUG(std::cerr << "no free registers\n"); - - DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n"); - - float minWeight = HUGE_VAL; - unsigned minReg = 0; - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); - for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); - i != rc->allocation_order_end(*mf_); ++i) { - unsigned reg = *i; - if (minWeight > spillWeights_[reg]) { - minWeight = spillWeights_[reg]; - minReg = reg; - } - } - DEBUG(std::cerr << "\t\tregister with min weight: " - << mri_->getName(minReg) << " (" << minWeight << ")\n"); + PhysRegTracker backupPrt = *prt_; - // if the current has the minimum weight, we spill it and move on - if (cur->weight <= minWeight) { - DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n'); - spilled_.push_back(cur); - return; - } - - // otherwise we spill all intervals aliasing the register with - // minimum weight, assigned the newly cleared register to the - // current interval and continue - assert(MRegisterInfo::isPhysicalRegister(minReg) && - "did not choose a register to spill?"); - std::vector toSpill(mri_->getNumRegs(), false); - toSpill[minReg] = true; - for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as) - toSpill[*as] = true; - unsigned earliestStart = cur->start(); + spillWeights_.assign(mri_->getNumRegs(), 0.0); - std::set spilled; - - for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg) && - toSpill[vrm_->getPhys(reg)] && - cur->overlaps(**i)) { - DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n'); - spilled_.push_back(*i); - prt_->delRegUse(vrm_->getPhys(reg)); - vrm_->clearVirt(reg); - i = active_.erase(i); - } - else - ++i; - } - for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) { - unsigned reg = (*i)->reg; - if (MRegisterInfo::isVirtualRegister(reg) && - toSpill[vrm_->getPhys(reg)] && - cur->overlaps(**i)) { - DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n'); - spilled_.push_back(*i); - vrm_->clearVirt(reg); - i = inactive_.erase(i); - } - else - ++i; - } - - vrm_->assignVirt2Phys(cur->reg, minReg); - prt_->addRegUse(minReg); + // for each interval in active update spill weights + for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end(); + i != e; ++i) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + updateSpillWeights(reg, (*i)->weight); + } + + // for every interval in inactive we overlap with, mark the + // register as not free and update spill weights + for (IntervalPtrs::const_iterator i = inactive_.begin(), + e = inactive_.end(); i != e; ++i) { + if (cur->overlaps(**i)) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg)) + reg = vrm_->getPhys(reg); + prt_->addRegUse(reg); + updateSpillWeights(reg, (*i)->weight); + } + } + + // for every interval in fixed we overlap with, + // mark the register as not free and update spill weights + for (IntervalPtrs::const_iterator i = fixed_.begin(), + e = fixed_.end(); i != e; ++i) { + if (cur->overlaps(**i)) { + unsigned reg = (*i)->reg; + prt_->addRegUse(reg); + updateSpillWeights(reg, (*i)->weight); + } + } + + unsigned physReg = getFreePhysReg(cur); + // restore the physical register tracker + *prt_ = backupPrt; + // if we find a free register, we are done: assign this virtual to + // the free physical register and add this interval to the active + // list. + if (physReg) { + DEBUG(std::cerr << mri_->getName(physReg) << '\n'); + vrm_->assignVirt2Phys(cur->reg, physReg); + prt_->addRegUse(physReg); active_.push_back(cur); handled_.push_back(cur); + return; + } + DEBUG(std::cerr << "no free registers\n"); + + DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n"); + + float minWeight = HUGE_VAL; + unsigned minReg = 0; + const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); + for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); + i != rc->allocation_order_end(*mf_); ++i) { + unsigned reg = *i; + if (minWeight > spillWeights_[reg]) { + minWeight = spillWeights_[reg]; + minReg = reg; + } + } + DEBUG(std::cerr << "\t\tregister with min weight: " + << mri_->getName(minReg) << " (" << minWeight << ")\n"); + + // if the current has the minimum weight, we spill it and move on + if (cur->weight <= minWeight) { + DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n'); + spilled_.push_back(cur); + return; + } + + // otherwise we spill all intervals aliasing the register with + // minimum weight, assigned the newly cleared register to the + // current interval and continue + assert(MRegisterInfo::isPhysicalRegister(minReg) && + "did not choose a register to spill?"); + std::vector toSpill(mri_->getNumRegs(), false); + toSpill[minReg] = true; + for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as) + toSpill[*as] = true; + unsigned earliestStart = cur->start(); + + std::set spilled; + + for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg) && + toSpill[vrm_->getPhys(reg)] && + cur->overlaps(**i)) { + DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n'); + spilled_.push_back(*i); + prt_->delRegUse(vrm_->getPhys(reg)); + vrm_->clearVirt(reg); + i = active_.erase(i); + } + else + ++i; + } + for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) { + unsigned reg = (*i)->reg; + if (MRegisterInfo::isVirtualRegister(reg) && + toSpill[vrm_->getPhys(reg)] && + cur->overlaps(**i)) { + DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n'); + spilled_.push_back(*i); + vrm_->clearVirt(reg); + i = inactive_.erase(i); + } + else + ++i; + } + + vrm_->assignVirt2Phys(cur->reg, minReg); + prt_->addRegUse(minReg); + active_.push_back(cur); + handled_.push_back(cur); } unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur) { - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); + const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); - for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); - i != rc->allocation_order_end(*mf_); ++i) { - unsigned reg = *i; - if (prt_->isRegAvail(reg)) - return reg; - } - return 0; + for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); + i != rc->allocation_order_end(*mf_); ++i) { + unsigned reg = *i; + if (prt_->isRegAvail(reg)) + return reg; + } + return 0; } FunctionPass* llvm::createIterativeScanRegisterAllocator() { - return new RA(); + return new RA(); } From alkis at cs.uiuc.edu Wed Aug 4 04:47:07 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:47:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200408040947.EAA26429@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.115 -> 1.116 --- Log message: Clean up whitespace. --- Diffs of the changes: (+14 -15) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.115 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.116 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.115 Wed Aug 4 04:45:14 2004 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Aug 4 04:46:56 2004 @@ -285,9 +285,9 @@ DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); - // Virtual registers may be defined multiple times (due to phi - // elimination and 2-addr elimination). Much of what we do only has to be - // done once for the vreg. We use an empty interval to detect the first + // Virtual registers may be defined multiple times (due to phi + // elimination and 2-addr elimination). Much of what we do only has to be + // done once for the vreg. We use an empty interval to detect the first // time we see a vreg. if (interval.empty()) { // Get the Idx of the defining instructions. @@ -312,7 +312,7 @@ // If the kill happens after the definition, we have an intra-block // live range. if (killIdx > defIndex) { - assert(vi.AliveBlocks.empty() && + assert(vi.AliveBlocks.empty() && "Shouldn't be alive across any blocks!"); LiveRange LR(defIndex, killIdx, ValNum); interval.addRange(LR); @@ -361,7 +361,7 @@ // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is the first // operand, and is a def-and-use. - if (mi->getOperand(0).isRegister() && + if (mi->getOperand(0).isRegister() && mi->getOperand(0).getReg() == interval.reg && mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) { // If this is a two-address definition, then we have already processed @@ -375,7 +375,7 @@ // Delete the initial value, which should be short and continuous, // becuase the 2-addr copy must be in the same MBB as the redef. interval.removeRange(DefIndex, RedefIndex); - + LiveRange LR(DefIndex, RedefIndex, interval.getNextValue()); DEBUG(std::cerr << " replace range with " << LR); interval.addRange(LR); @@ -419,7 +419,7 @@ // live until the end of the block. We've already taken care of the // rest of the live range. unsigned defIndex = getDefIndex(getInstructionIndex(mi)); - LiveRange LR(defIndex, + LiveRange LR(defIndex, getInstructionIndex(&mbb->back()) + InstrSlots::NUM, interval.getNextValue()); interval.addRange(LR); @@ -501,7 +501,7 @@ DEBUG(std::cerr << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'); - for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); + for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); I != E; ++I) { MachineBasicBlock* mbb = I; DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n"); @@ -545,17 +545,17 @@ lv_->getAllocatablePhysicalRegisters()[regA]) && (MRegisterInfo::isVirtualRegister(regB) || lv_->getAllocatablePhysicalRegisters()[regB])) { - + // Get representative registers. regA = rep(regA); regB = rep(regB); - + // If they are already joined we continue. if (regA == regB) continue; - + // If they are both physical registers, we cannot join them. - if (MRegisterInfo::isPhysicalRegister(regA) && + if (MRegisterInfo::isPhysicalRegister(regA) && MRegisterInfo::isPhysicalRegister(regB)) continue; @@ -607,7 +607,7 @@ typedef std::pair DepthMBBPair; bool operator()(const DepthMBBPair &LHS, const DepthMBBPair &RHS) const { if (LHS.first > RHS.first) return true; // Deeper loops first - return LHS.first == RHS.first && + return LHS.first == RHS.first && LHS.second->getNumber() < RHS.second->getNumber(); } }; @@ -634,7 +634,7 @@ // Sort by loop depth. std::sort(MBBs.begin(), MBBs.end(), DepthMBBCompare()); - // Finally, join intervals in loop nest order. + // Finally, join intervals in loop nest order. for (unsigned i = 0, e = MBBs.size(); i != e; ++i) joinIntervalsInMachineBB(MBBs[i].second); } @@ -687,4 +687,3 @@ float Weight = MRegisterInfo::isPhysicalRegister(reg) ? HUGE_VAL :0.0F; return LiveInterval(reg, Weight); } - From alkis at cs.uiuc.edu Wed Aug 4 04:49:29 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:49:29 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408040949.EAA26497@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.72 -> 1.73 --- Log message: Code cleanups/preparation for vtables. --- Diffs of the changes: (+72 -45) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.72 llvm-java/lib/Compiler/Compiler.cpp:1.73 --- llvm-java/lib/Compiler/Compiler.cpp:1.72 Tue Aug 3 02:52:11 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Wed Aug 4 04:49:18 2004 @@ -140,16 +140,27 @@ Locals locals_; BC2BBMap bc2bbMap_; BasicBlock* prologue_; + typedef SetVector FunctionSet; FunctionSet toCompileFunctions_; + struct ClassInfo { - explicit ClassInfo(Type* t) : type(t) { } + ClassInfo() : type(NULL) { } Type* type; typedef std::map Field2IndexMap; Field2IndexMap f2iMap; }; - typedef std::map Class2InfoMap; - Class2InfoMap c2ciMap_; + typedef std::map Class2ClassInfoMap; + Class2ClassInfoMap c2ciMap_; + + struct VTableInfo { + VTableInfo() : vtable(NULL) { } + ConstantStruct* vtable; + typedef std::map Method2IndexMap; + Method2IndexMap m2iMap; + }; + typedef std::map Class2VTableInfoMap; + Class2VTableInfoMap c2viMap_; private: BasicBlock* getBBAt(unsigned bcI) { return bc2bbMap_[bcI]; } @@ -186,12 +197,15 @@ return static_cast(-1); } - Type* getType(ConstantUtf8* descr) { + /// Returns the type of the Java string descriptor. If the + /// Type* self is not NULL then that type is used as the first + /// type in function types + Type* getType(ConstantUtf8* descr, Type* self = NULL) { unsigned i = 0; - return getTypeHelper(descr->str(), i); + return getTypeHelper(descr->str(), i, self); } - Type* getTypeHelper(const std::string& descr, unsigned& i) { + Type* getTypeHelper(const std::string& descr, unsigned& i, Type* self) { assert(i < descr.size()); switch (descr[i++]) { case 'B': return Type::SByteTy; @@ -213,12 +227,14 @@ // FIXME: this should really be a new class // represeting the array of the following type return PointerType::get( - ArrayType::get(getTypeHelper(descr, i), 0)); + ArrayType::get(getTypeHelper(descr, i, NULL), 0)); case '(': { std::vector params; + if (self) + params.push_back(PointerType::get(self)); while (descr[i] != ')') - params.push_back(getTypeHelper(descr, i)); - return FunctionType::get(getTypeHelper(descr, ++i), + params.push_back(getTypeHelper(descr, i, NULL)); + return FunctionType::get(getTypeHelper(descr, ++i, NULL), params, false); } // FIXME: Throw something @@ -226,37 +242,55 @@ } } - ClassInfo& getClassInfo(const std::string& className) { - Class2InfoMap::iterator it = c2ciMap_.lower_bound(className); - if (it == c2ciMap_.end() || it->first != className) { - ClassFile* cf = ClassFile::getClassFile(className); - OpaqueType* newType = OpaqueType::get(); - it = c2ciMap_.insert(it, std::make_pair(className, - ClassInfo(newType))); - std::vector elements; - if (ConstantClass* super = cf->getSuperClass()) - elements.push_back - (getClassInfo(super->getName()->str()).type); - const Fields& fields = cf->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field* field = fields[i]; - if (!field->isStatic()) { - it->second.f2iMap.insert( - std::make_pair(field->getName()->str(), - elements.size())); - elements.push_back(getType(field->getDescriptor())); - } + const ClassInfo& getClassInfo(const std::string& className) { + Class2ClassInfoMap::iterator it = c2ciMap_.lower_bound(className); + if (it != c2ciMap_.end() && it->first == className) + return it->second; + + DEBUG(std::cerr << "Building ClassInfo for: " << className << '\n'); + ClassFile* cf = ClassFile::getClassFile(className); + ClassInfo& ci = c2ciMap_[className]; + assert(!ci.type && ci.f2iMap.empty() && + "got already initialized Classinfo!"); + ci.type = OpaqueType::get(); + + std::vector elements; + ConstantClass* super = cf->getSuperClass(); + const ClassInfo* superCI = + super ? &getClassInfo(super->getName()->str()) : NULL; + if (superCI) + elements.push_back(superCI->type); + else { + // this is java/lang/Object so we must add the opaque + // llvm_java_base type first + Type* base = OpaqueType::get(); + module_->addTypeName("llvm_java_base", base); + elements.push_back(base); + } + + const Fields& fields = cf->getFields(); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + Field* field = fields[i]; + if (!field->isStatic()) { + ci.f2iMap.insert(std::make_pair(field->getName()->str(), + elements.size())); + elements.push_back(getType(field->getDescriptor())); } - PATypeHolder holder = newType; - newType->refineAbstractTypeTo(StructType::get(elements)); - it->second.type = holder.get(); - DEBUG(std::cerr << "Adding " << className << " = " - << *it->second.type << " to type map\n"); - module_->addTypeName(className, it->second.type); } - return it->second; + PATypeHolder holder = ci.type; + cast(ci.type)->refineAbstractTypeTo + (StructType::get(elements)); + ci.type = holder.get(); + DEBUG(std::cerr << "Adding " << className << " = " + << *ci.type << " to type map\n"); + module_->addTypeName(className, ci.type); + + assert(ci.type && "ClassInfo not initialized properly!"); + return ci; } + //const VTableInfo& getVTableInfo(const std::string& className); + Value* getOrCreateLocal(unsigned index, Type* type) { if (!locals_[index] || cast(locals_[index]->getType())->getElementType() != type) { @@ -298,8 +332,8 @@ // deref pointer std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); while (true) { - ClassInfo& info = getClassInfo(className); - ClassInfo::Field2IndexMap::iterator it = + const ClassInfo& info = getClassInfo(className); + ClassInfo::Field2IndexMap::const_iterator it = info.f2iMap.find(fieldName); if (it == info.f2iMap.end()) { className = classfile->getSuperClass()->getName()->str(); @@ -437,13 +471,6 @@ BasicBlock* staticInitBB = new BasicBlock("entry", staticInit); new ReturnInst(NULL, staticInitBB); - // insert an opaque type for java.lang.Object. This is - // defined in runtime.ll - c2ciMap_.insert(std::make_pair("java/lang/Object", - ClassInfo(OpaqueType::get()))); - module.addTypeName("java/lang/Object", - getClassInfo("java/lang/Object").type); - // compile the method requested Function* function = compileMethodOnly(classMethodDesc); // compile all other methods called by this method recursively From alkis at cs.uiuc.edu Wed Aug 4 04:49:29 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 04:49:29 -0500 Subject: [llvm-commits] CVS: llvm-java/runtime/runtime.ll Message-ID: <200408040949.EAA26500@zion.cs.uiuc.edu> Changes in directory llvm-java/runtime: runtime.ll updated: 1.3 -> 1.4 --- Log message: Code cleanups/preparation for vtables. --- Diffs of the changes: (+3 -1) Index: llvm-java/runtime/runtime.ll diff -u llvm-java/runtime/runtime.ll:1.3 llvm-java/runtime/runtime.ll:1.4 --- llvm-java/runtime/runtime.ll:1.3 Sat Jul 24 15:48:53 2004 +++ llvm-java/runtime/runtime.ll Wed Aug 4 04:49:18 2004 @@ -1,4 +1,6 @@ -"java/lang/Object" = type { } +%llvm_java_base = type { %llvm_java_vtable_base* } +%llvm_java_vtable_base = type { %llvm_java_type_info } +%llvm_java_type_info = type { } implementation From alkis at cs.uiuc.edu Wed Aug 4 05:02:14 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:02:14 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200408041002.FAA26629@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.20 -> 1.21 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+388 -388) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.20 llvm-java/lib/ClassFile/ClassFile.cpp:1.21 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.20 Sat Jul 24 17:06:18 2004 +++ llvm-java/lib/ClassFile/ClassFile.cpp Wed Aug 4 05:02:03 2004 @@ -31,17 +31,17 @@ namespace { - using namespace llvm; + using namespace llvm; - static cl::opt - ClassPath("cp", - cl::desc("A : separated list of directories"), - cl::value_desc("class search path"), - cl::init(getenv("CLASSPATH"))); - static cl::alias - ClassPathA("classpath", - cl::desc("Alias for -cp"), - cl::aliasopt(ClassPath)); + static cl::opt + ClassPath("cp", + cl::desc("A : separated list of directories"), + cl::value_desc("class search path"), + cl::init(getenv("CLASSPATH"))); + static cl::alias + ClassPathA("classpath", + cl::desc("Alias for -cp"), + cl::aliasopt(ClassPath)); } @@ -49,110 +49,110 @@ // Internal utility functions namespace { - uint8_t readU1(std::istream& is) { - char val; - if (!is.get(val)) - throw ClassFileParseError("unexpected end of input"); - return val; - } - - uint16_t readU2(std::istream& is) { - uint16_t val = readU1(is); - return (val << 8) | readU1(is); - } - - uint32_t readU4(std::istream& is) { - uint32_t val = readU2(is); - return (val << 16) | readU2(is); - } - - uint64_t readU8(std::istream& is) { - uint64_t hi = readU4(is), lo = readU4(is); - return hi << 32 | lo; - } - - float int2float(uint32_t v) { - union { uint32_t in; float out; } tmp; - tmp.in = v; - return tmp.out; - } - - double long2double(uint64_t v) { - union { uint64_t in; double out; } tmp; - tmp.in = v; - return tmp.out; - } - - void readConstantPool(ConstantPool& cp, std::istream& is) - { - assert(cp.empty() && "Should not call with a non-empty constant pool"); - uint16_t count = readU2(is); - cp.reserve(count); + uint8_t readU1(std::istream& is) { + char val; + if (!is.get(val)) + throw ClassFileParseError("unexpected end of input"); + return val; + } + + uint16_t readU2(std::istream& is) { + uint16_t val = readU1(is); + return (val << 8) | readU1(is); + } + + uint32_t readU4(std::istream& is) { + uint32_t val = readU2(is); + return (val << 16) | readU2(is); + } + + uint64_t readU8(std::istream& is) { + uint64_t hi = readU4(is), lo = readU4(is); + return hi << 32 | lo; + } + + float int2float(uint32_t v) { + union { uint32_t in; float out; } tmp; + tmp.in = v; + return tmp.out; + } + + double long2double(uint64_t v) { + union { uint64_t in; double out; } tmp; + tmp.in = v; + return tmp.out; + } + + void readConstantPool(ConstantPool& cp, std::istream& is) + { + assert(cp.empty() && "Should not call with a non-empty constant pool"); + uint16_t count = readU2(is); + cp.reserve(count); + cp.push_back(NULL); + while (cp.size() < count) { + cp.push_back(Constant::readConstant(cp, is)); + if (cp.back()->isDoubleSlot()) cp.push_back(NULL); - while (cp.size() < count) { - cp.push_back(Constant::readConstant(cp, is)); - if (cp.back()->isDoubleSlot()) - cp.push_back(NULL); - } - } - - void readClasses(Classes& i, const ConstantPool& cp, std::istream& is) - { - assert(i.empty() && - "Should not call with a non-empty classes vector"); - uint16_t count = readU2(is); - i.reserve(count); - while (count--) { - ConstantClass* c = dynamic_cast(cp[readU2(is)]); - if (!c) - throw ClassFileSemanticError("ConstantClass expected"); - i.push_back(c); - } - } - - void readFields(Fields& f, const ConstantPool& cp, std::istream& is) - { - assert(f.empty() && "Should not call with a non-empty fields vector"); - uint16_t count = readU2(is); - f.reserve(count); - while(count--) - f.push_back(Field::readField(cp, is)); - } - - void readMethods(Methods& m, const ConstantPool& cp, std::istream& is) - { - assert(m.empty() && "Should not call with a non-empty methods vector"); - uint16_t count = readU2(is); - m.reserve(count); - while(count--) - m.push_back(Method::readMethod(cp, is)); - } - - void readAttributes(Attributes& a, - const ConstantPool& cp, - std::istream& is) - { - assert(a.empty() && - "Should not call with a non-empty attributes vector"); - uint16_t count = readU2(is); - a.reserve(count); - while(count--) - a.push_back(Attribute::readAttribute(cp, is)); } + } - template - std::ostream& dumpCollection(Container& c, - const char* const name, - std::ostream& os) { - os << '\n' << name << "s:\n"; - for (typename Container::const_iterator - i = c.begin(), e = c.end(); i != e; ++i) - if (*i) - (*i)->dump(os << name << ' ') << '\n'; - else - os << name << " NULL\n"; - return os; - } + void readClasses(Classes& i, const ConstantPool& cp, std::istream& is) + { + assert(i.empty() && + "Should not call with a non-empty classes vector"); + uint16_t count = readU2(is); + i.reserve(count); + while (count--) { + ConstantClass* c = dynamic_cast(cp[readU2(is)]); + if (!c) + throw ClassFileSemanticError("ConstantClass expected"); + i.push_back(c); + } + } + + void readFields(Fields& f, const ConstantPool& cp, std::istream& is) + { + assert(f.empty() && "Should not call with a non-empty fields vector"); + uint16_t count = readU2(is); + f.reserve(count); + while(count--) + f.push_back(Field::readField(cp, is)); + } + + void readMethods(Methods& m, const ConstantPool& cp, std::istream& is) + { + assert(m.empty() && "Should not call with a non-empty methods vector"); + uint16_t count = readU2(is); + m.reserve(count); + while(count--) + m.push_back(Method::readMethod(cp, is)); + } + + void readAttributes(Attributes& a, + const ConstantPool& cp, + std::istream& is) + { + assert(a.empty() && + "Should not call with a non-empty attributes vector"); + uint16_t count = readU2(is); + a.reserve(count); + while(count--) + a.push_back(Attribute::readAttribute(cp, is)); + } + + template + std::ostream& dumpCollection(Container& c, + const char* const name, + std::ostream& os) { + os << '\n' << name << "s:\n"; + for (typename Container::const_iterator + i = c.begin(), e = c.end(); i != e; ++i) + if (*i) + (*i)->dump(os << name << ' ') << '\n'; + else + os << name << " NULL\n"; + return os; + } } @@ -160,125 +160,125 @@ // ClassFile implementation ClassFile* ClassFile::readClassFile(std::istream& is) { - if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic"); - return new ClassFile(is); + return new ClassFile(is); } std::vector ClassFile::getClassPath() { - DEBUG(std::cerr << "CLASSPATH=" << ClassPath << '\n'); + DEBUG(std::cerr << "CLASSPATH=" << ClassPath << '\n'); - std::vector result; - unsigned b = 0, e = 0; - do { - e = ClassPath.find(':', b); - result.push_back(ClassPath.substr(b, e - b)); - b = e + 1; - } while (e != std::string::npos); + std::vector result; + unsigned b = 0, e = 0; + do { + e = ClassPath.find(':', b); + result.push_back(ClassPath.substr(b, e - b)); + b = e + 1; + } while (e != std::string::npos); - return result; + return result; } std::string ClassFile::getFileForClass(const std::string& classname) { - static const std::vector classpath = getClassPath(); - DEBUG(std::cerr << "Looking up class: " << classname << '\n'); + static const std::vector classpath = getClassPath(); + DEBUG(std::cerr << "Looking up class: " << classname << '\n'); - std::string clazz = classname; - // replace '.' with '/' - for (unsigned i = 0, e = clazz.size(); i != e; ++i) - if (clazz[i] == '.') - clazz[i] = '/'; - clazz += ".class"; - - for (unsigned i = 0, e = classpath.size(); i != e; ++i) { - std::string filename = classpath[i] + '/' + clazz; - DEBUG(std::cerr << "Trying file: " << filename << '\n'); - if (FileOpenable(filename)) - return filename; - } + std::string clazz = classname; + // replace '.' with '/' + for (unsigned i = 0, e = clazz.size(); i != e; ++i) + if (clazz[i] == '.') + clazz[i] = '/'; + clazz += ".class"; + + for (unsigned i = 0, e = classpath.size(); i != e; ++i) { + std::string filename = classpath[i] + '/' + clazz; + DEBUG(std::cerr << "Trying file: " << filename << '\n'); + if (FileOpenable(filename)) + return filename; + } - throw ClassNotFoundException("Class " + classname + " not found"); + throw ClassNotFoundException("Class " + classname + " not found"); } ClassFile* ClassFile::getClassFile(const std::string& classname) { - typedef std::map Name2ClassMap; - static Name2ClassMap n2cMap_; + typedef std::map Name2ClassMap; + static Name2ClassMap n2cMap_; - Name2ClassMap::iterator it = n2cMap_.upper_bound(classname); - if (it == n2cMap_.end() || it->first != classname) { - std::ifstream in(getFileForClass(classname).c_str()); - it = n2cMap_.insert(it, std::make_pair(classname, readClassFile(in))); - } + Name2ClassMap::iterator it = n2cMap_.upper_bound(classname); + if (it == n2cMap_.end() || it->first != classname) { + std::ifstream in(getFileForClass(classname).c_str()); + it = n2cMap_.insert(it, std::make_pair(classname, readClassFile(in))); + } - return it->second; + return it->second; } ClassFile::ClassFile(std::istream& is) { - minorV_ = readU2(is); - majorV_ = readU2(is); - readConstantPool(cPool_, is); - accessFlags_ = readU2(is); - thisClass_ = dynamic_cast(cPool_[readU2(is)]); - if (!thisClass_) - throw ClassFileSemanticError( - "Representation of this class is not of type ConstantClass"); - superClass_ = dynamic_cast(cPool_[readU2(is)]); - if (!superClass_ && thisClass_->getName()->str() != "java/lang/Object") - throw ClassFileSemanticError( - "Representation of super class is not of type ConstantClass"); - readClasses(interfaces_, cPool_, is); - readFields(fields_, cPool_, is); - readMethods(methods_, cPool_, is); - readAttributes(attributes_, cPool_, is); - for (Methods::const_iterator - i = methods_.begin(), e = methods_.end(); i != e; ++i) - n2mMap_.insert( - std::make_pair( - (*i)->getName()->str() + (*i)->getDescriptor()->str(), *i)); + minorV_ = readU2(is); + majorV_ = readU2(is); + readConstantPool(cPool_, is); + accessFlags_ = readU2(is); + thisClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!thisClass_) + throw ClassFileSemanticError( + "Representation of this class is not of type ConstantClass"); + superClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!superClass_ && thisClass_->getName()->str() != "java/lang/Object") + throw ClassFileSemanticError( + "Representation of super class is not of type ConstantClass"); + readClasses(interfaces_, cPool_, is); + readFields(fields_, cPool_, is); + readMethods(methods_, cPool_, is); + readAttributes(attributes_, cPool_, is); + for (Methods::const_iterator + i = methods_.begin(), e = methods_.end(); i != e; ++i) + n2mMap_.insert( + std::make_pair( + (*i)->getName()->str() + (*i)->getDescriptor()->str(), *i)); } Method* ClassFile::getMethod(const std::string& nameAndDescr) const { - Name2MethodMap::const_iterator it = n2mMap_.find(nameAndDescr); - return it == n2mMap_.end() ? NULL : it->second; + Name2MethodMap::const_iterator it = n2mMap_.find(nameAndDescr); + return it == n2mMap_.end() ? NULL : it->second; } ClassFile::~ClassFile() { - for_each(cPool_.begin(), cPool_.end(), deleter); - for_each(fields_.begin(), fields_.end(), deleter); - for_each(methods_.begin(), methods_.end(), deleter); - for_each(attributes_.begin(), attributes_.end(), deleter); + for_each(cPool_.begin(), cPool_.end(), deleter); + for_each(fields_.begin(), fields_.end(), deleter); + for_each(methods_.begin(), methods_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); } std::ostream& ClassFile::dump(std::ostream& os) const { - os << "Minor version: " << getMinorVersion() << '\n' - << "Major version: " << getMajorVersion() << "\n\n" - << "class " << *getThisClass(); - if (getSuperClass()) - os << " (" << *getSuperClass() << ")\n"; - - os << "Flags:"; - if (isPublic()) os << " public"; - if (isFinal()) os << " final"; - if (isSuper()) os << " super"; - if (isInterface()) os << " interface"; - if (isAbstract()) os << " abstract"; - - dumpCollection(interfaces_, "Interface", os); - dumpCollection(fields_, "Field", os); - dumpCollection(methods_, "Method", os); - dumpCollection(attributes_, "Attribute", os); + os << "Minor version: " << getMinorVersion() << '\n' + << "Major version: " << getMajorVersion() << "\n\n" + << "class " << *getThisClass(); + if (getSuperClass()) + os << " (" << *getSuperClass() << ")\n"; + + os << "Flags:"; + if (isPublic()) os << " public"; + if (isFinal()) os << " final"; + if (isSuper()) os << " super"; + if (isInterface()) os << " interface"; + if (isAbstract()) os << " abstract"; + + dumpCollection(interfaces_, "Interface", os); + dumpCollection(fields_, "Field", os); + dumpCollection(methods_, "Method", os); + dumpCollection(attributes_, "Attribute", os); - return os; + return os; } //===----------------------------------------------------------------------===// @@ -286,11 +286,11 @@ Attribute* llvm::Java::getAttribute(const Attributes& attrs, const std::string& name) { - for (unsigned i = 0, e = attrs.size(); i != e; ++i) - if (attrs[i]->getName()->str() == name) - return attrs[i]; + for (unsigned i = 0, e = attrs.size(); i != e; ++i) + if (attrs[i]->getName()->str() == name) + return attrs[i]; - return NULL; + return NULL; } //===----------------------------------------------------------------------===// @@ -326,35 +326,35 @@ Constant* Constant::readConstant(const ConstantPool& cp, std::istream& is) { - Constant::Tag tag = static_cast(readU1(is)); - switch (tag) { - case Constant::CLASS: - return new ConstantClass(cp, is); - case Constant::FIELD_REF: - return new ConstantFieldRef(cp, is); - case Constant::METHOD_REF: - return new ConstantMethodRef(cp, is); - case Constant::INTERFACE_METHOD_REF: - return new ConstantInterfaceMethodRef(cp, is); - case Constant::STRING: - return new ConstantString(cp, is); - case Constant::INTEGER: - return new ConstantInteger(cp, is); - case Constant::FLOAT: - return new ConstantFloat(cp, is); - case Constant::LONG: - return new ConstantLong(cp, is); - case Constant::DOUBLE: - return new ConstantDouble(cp, is); - case Constant::NAME_AND_TYPE: - return new ConstantNameAndType(cp, is); - case Constant::UTF8: - return new ConstantUtf8(cp, is); - default: - assert(0 && "Unknown constant tag"); - } + Constant::Tag tag = static_cast(readU1(is)); + switch (tag) { + case Constant::CLASS: + return new ConstantClass(cp, is); + case Constant::FIELD_REF: + return new ConstantFieldRef(cp, is); + case Constant::METHOD_REF: + return new ConstantMethodRef(cp, is); + case Constant::INTERFACE_METHOD_REF: + return new ConstantInterfaceMethodRef(cp, is); + case Constant::STRING: + return new ConstantString(cp, is); + case Constant::INTEGER: + return new ConstantInteger(cp, is); + case Constant::FLOAT: + return new ConstantFloat(cp, is); + case Constant::LONG: + return new ConstantLong(cp, is); + case Constant::DOUBLE: + return new ConstantDouble(cp, is); + case Constant::NAME_AND_TYPE: + return new ConstantNameAndType(cp, is); + case Constant::UTF8: + return new ConstantUtf8(cp, is); + default: + assert(0 && "Unknown constant tag"); + } - return NULL; + return NULL; } Constant::~Constant() @@ -363,216 +363,216 @@ } ConstantMemberRef::ConstantMemberRef(const ConstantPool&cp, std::istream& is) - : Constant(cp), - classIdx_(readU2(is)), - nameAndTypeIdx_(readU2(is)) + : Constant(cp), + classIdx_(readU2(is)), + nameAndTypeIdx_(readU2(is)) { } std::ostream& ConstantMemberRef::dump(std::ostream& os) const { - return os << *getNameAndType() << '(' << *getClass() << ')'; + return os << *getNameAndType() << '(' << *getClass() << ')'; } ConstantClass::ConstantClass(const ConstantPool& cp, std::istream& is) - : Constant(cp), - nameIdx_(readU2(is)) + : Constant(cp), + nameIdx_(readU2(is)) { } std::ostream& ConstantClass::dump(std::ostream& os) const { - return os << *getName(); + return os << *getName(); } ConstantString::ConstantString(const ConstantPool& cp, std::istream& is) - : Constant(cp), - stringIdx_(readU2(is)) + : Constant(cp), + stringIdx_(readU2(is)) { } std::ostream& ConstantString::dump(std::ostream& os) const { - return os << "string " << *getValue(); + return os << "string " << *getValue(); } ConstantInteger::ConstantInteger(const ConstantPool& cp, std::istream& is) - : Constant(cp), - value_(static_cast(readU4(is))) + : Constant(cp), + value_(static_cast(readU4(is))) { } std::ostream& ConstantInteger::dump(std::ostream& os) const { - return os << value_; + return os << value_; } ConstantFloat::ConstantFloat(const ConstantPool& cp, std::istream& is) - : Constant(cp), - value_(int2float(readU4(is))) + : Constant(cp), + value_(int2float(readU4(is))) { } std::ostream& ConstantFloat::dump(std::ostream& os) const { - return os << value_; + return os << value_; } ConstantLong::ConstantLong(const ConstantPool& cp, std::istream& is) - : Constant(cp), - value_(static_cast(readU8(is))) + : Constant(cp), + value_(static_cast(readU8(is))) { } std::ostream& ConstantLong::dump(std::ostream& os) const { - return os << value_; + return os << value_; } ConstantDouble::ConstantDouble(const ConstantPool& cp, std::istream& is) - : Constant(cp), - value_(long2double(readU8(is))) + : Constant(cp), + value_(long2double(readU8(is))) { } std::ostream& ConstantDouble::dump(std::ostream& os) const { - return os << value_; + return os << value_; } ConstantNameAndType::ConstantNameAndType(const ConstantPool& cp, std::istream& is) - : Constant(cp), - nameIdx_(readU2(is)), - descriptorIdx_(readU2(is)) + : Constant(cp), + nameIdx_(readU2(is)), + descriptorIdx_(readU2(is)) { } std::ostream& ConstantNameAndType::dump(std::ostream& os) const { - return os << *getDescriptor() << ' ' << *getName(); + return os << *getDescriptor() << ' ' << *getName(); } ConstantUtf8::ConstantUtf8(const ConstantPool& cp, std::istream& is) - : Constant(cp) + : Constant(cp) { - uint16_t length = readU2(is); - char buf[length]; - std::streamsize s = is.rdbuf()->sgetn(buf, length); - if (s != length) - throw ClassFileParseError( - "Could not read string constant from input stream"); - utf8_.assign(buf, length); + uint16_t length = readU2(is); + char buf[length]; + std::streamsize s = is.rdbuf()->sgetn(buf, length); + if (s != length) + throw ClassFileParseError( + "Could not read string constant from input stream"); + utf8_.assign(buf, length); } std::ostream& ConstantUtf8::dump(std::ostream& os) const { - return os << utf8_; + return os << utf8_; } //===----------------------------------------------------------------------===// // Field implementation Field::Field(const ConstantPool& cp, std::istream& is) { - accessFlags_ = readU2(is); - name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) - throw ClassFileSemanticError( - "Representation of field name is not of type ConstantUtf8"); - descriptor_ = dynamic_cast(cp[readU2(is)]); - if (!descriptor_) - throw ClassFileSemanticError( - "Representation of field descriptor is not of type ConstantUtf8"); - readAttributes(attributes_, cp, is); + accessFlags_ = readU2(is); + name_ = dynamic_cast(cp[readU2(is)]); + if (!name_) + throw ClassFileSemanticError( + "Representation of field name is not of type ConstantUtf8"); + descriptor_ = dynamic_cast(cp[readU2(is)]); + if (!descriptor_) + throw ClassFileSemanticError( + "Representation of field descriptor is not of type ConstantUtf8"); + readAttributes(attributes_, cp, is); } Field::~Field() { - for_each(attributes_.begin(), attributes_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); } std::ostream& Field::dump(std::ostream& os) const { - os << *getName() << ' ' << *getDescriptor() << '\n' - << "Flags:"; - if (isPublic()) os << " public"; - if (isPrivate()) os << " private"; - if (isProtected()) os << " protected"; - if (isStatic()) os << " static"; - if (isFinal()) os << " final"; - if (isVolatile()) os << " volatile"; - if (isTransient()) os << " transient"; + os << *getName() << ' ' << *getDescriptor() << '\n' + << "Flags:"; + if (isPublic()) os << " public"; + if (isPrivate()) os << " private"; + if (isProtected()) os << " protected"; + if (isStatic()) os << " static"; + if (isFinal()) os << " final"; + if (isVolatile()) os << " volatile"; + if (isTransient()) os << " transient"; - dumpCollection(attributes_, "Attribute", os); + dumpCollection(attributes_, "Attribute", os); - return os; + return os; } ConstantValueAttribute* Field::getConstantValueAttribute() const { - if (!isStatic()) - return NULL; + if (!isStatic()) + return NULL; - return (ConstantValueAttribute*) getAttribute(attributes_, - Attribute::CONSTANT_VALUE); + return (ConstantValueAttribute*) getAttribute(attributes_, + Attribute::CONSTANT_VALUE); } //===----------------------------------------------------------------------===// // Method implementation Method::Method(const ConstantPool& cp, std::istream& is) { - accessFlags_ = readU2(is); - name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) - throw ClassFileSemanticError( - "Representation of method name is not of type ConstantUtf8"); - descriptor_ = dynamic_cast(cp[readU2(is)]); - if (!descriptor_) - throw ClassFileSemanticError( - "Representation of method descriptor is not of type ConstantUtf8"); - readAttributes(attributes_, cp, is); + accessFlags_ = readU2(is); + name_ = dynamic_cast(cp[readU2(is)]); + if (!name_) + throw ClassFileSemanticError( + "Representation of method name is not of type ConstantUtf8"); + descriptor_ = dynamic_cast(cp[readU2(is)]); + if (!descriptor_) + throw ClassFileSemanticError( + "Representation of method descriptor is not of type ConstantUtf8"); + readAttributes(attributes_, cp, is); } Method::~Method() { - for_each(attributes_.begin(), attributes_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); } std::ostream& Method::dump(std::ostream& os) const { - os << *getName() << ' ' << *getDescriptor() << '\n' - << "Flags:"; - if (isPublic()) os << " public"; - if (isPrivate()) os << " private"; - if (isProtected()) os << " protected"; - if (isStatic()) os << " static"; - if (isFinal()) os << " final"; - if (isSynchronized()) os << " synchronized"; - if (isNative()) os << " native"; - if (isStrict()) os << " strict"; + os << *getName() << ' ' << *getDescriptor() << '\n' + << "Flags:"; + if (isPublic()) os << " public"; + if (isPrivate()) os << " private"; + if (isProtected()) os << " protected"; + if (isStatic()) os << " static"; + if (isFinal()) os << " final"; + if (isSynchronized()) os << " synchronized"; + if (isNative()) os << " native"; + if (isStrict()) os << " strict"; - dumpCollection(attributes_, "Attribute", os); + dumpCollection(attributes_, "Attribute", os); - return os; + return os; } CodeAttribute* Method::getCodeAttribute() const { - return (CodeAttribute*) getAttribute(attributes_, Attribute::CODE); + return (CodeAttribute*) getAttribute(attributes_, Attribute::CODE); } ExceptionsAttribute* Method::getExceptionsAttribute() const { - return (ExceptionsAttribute*) getAttribute(attributes_, - Attribute::EXCEPTIONS); + return (ExceptionsAttribute*) getAttribute(attributes_, + Attribute::EXCEPTIONS); } //===----------------------------------------------------------------------===// @@ -589,26 +589,26 @@ Attribute* Attribute::readAttribute(const ConstantPool& cp, std::istream& is) { - ConstantUtf8* name = dynamic_cast(cp[readU2(is)]); - if (!name) - throw ClassFileSemanticError( - "Representation of attribute name is not of type ConstantUtf8"); - - if (CONSTANT_VALUE == name->str()) - return new ConstantValueAttribute(name, cp, is); - else if (CODE == name->str()) - return new CodeAttribute(name, cp, is); - else { - uint32_t length = readU4(is); - is.ignore(length); - return new Attribute(name, cp, is); - } + ConstantUtf8* name = dynamic_cast(cp[readU2(is)]); + if (!name) + throw ClassFileSemanticError( + "Representation of attribute name is not of type ConstantUtf8"); + + if (CONSTANT_VALUE == name->str()) + return new ConstantValueAttribute(name, cp, is); + else if (CODE == name->str()) + return new CodeAttribute(name, cp, is); + else { + uint32_t length = readU4(is); + is.ignore(length); + return new Attribute(name, cp, is); + } } Attribute::Attribute(ConstantUtf8* name, const ConstantPool& cp, std::istream& is) - : name_(name) + : name_(name) { } @@ -620,7 +620,7 @@ std::ostream& Attribute::dump(std::ostream& os) const { - return os << *getName(); + return os << *getName(); } //===----------------------------------------------------------------------===// @@ -628,18 +628,18 @@ ConstantValueAttribute::ConstantValueAttribute(ConstantUtf8* name, const ConstantPool& cp, std::istream& is) - : Attribute(name, cp, is) + : Attribute(name, cp, is) { - uint32_t length = readU4(is); - if (length != 2) - throw ClassFileSemanticError( - "Length of ConstantValueAttribute is not 2"); - value_ = cp[readU2(is)]; + uint32_t length = readU4(is); + if (length != 2) + throw ClassFileSemanticError( + "Length of ConstantValueAttribute is not 2"); + value_ = cp[readU2(is)]; } std::ostream& ConstantValueAttribute::dump(std::ostream& os) const { - return Attribute::dump(os) << ": " << *value_; + return Attribute::dump(os) << ": " << *value_; } //===----------------------------------------------------------------------===// @@ -647,69 +647,69 @@ CodeAttribute::CodeAttribute(ConstantUtf8* name, const ConstantPool& cp, std::istream& is) - : Attribute(name, cp, is) + : Attribute(name, cp, is) { - uint32_t length = readU4(is); - maxStack_ = readU2(is); - maxLocals_ = readU2(is); - codeSize_ = readU4(is); - code_ = new uint8_t[codeSize_]; - std::streamsize s = is.rdbuf()->sgetn(reinterpret_cast(code_), codeSize_); - if (s != (std::streamsize) codeSize_) - throw ClassFileParseError( - "Could not read code from input stream"); - uint16_t exceptCount = readU2(is); - exceptions_.reserve(exceptCount); - while (exceptCount--) - exceptions_.push_back(new Exception(cp, is)); - readAttributes(attributes_, cp, is); + uint32_t length = readU4(is); + maxStack_ = readU2(is); + maxLocals_ = readU2(is); + codeSize_ = readU4(is); + code_ = new uint8_t[codeSize_]; + std::streamsize s = is.rdbuf()->sgetn(reinterpret_cast(code_), codeSize_); + if (s != (std::streamsize) codeSize_) + throw ClassFileParseError( + "Could not read code from input stream"); + uint16_t exceptCount = readU2(is); + exceptions_.reserve(exceptCount); + while (exceptCount--) + exceptions_.push_back(new Exception(cp, is)); + readAttributes(attributes_, cp, is); } CodeAttribute::~CodeAttribute() { - delete[] code_; - for_each(exceptions_.begin(), exceptions_.end(), deleter); - for_each(attributes_.begin(), attributes_.end(), deleter); + delete[] code_; + for_each(exceptions_.begin(), exceptions_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); } std::ostream& CodeAttribute::dump(std::ostream& os) const { - Attribute::dump(os) - << '\n' - << "Max stack: " << maxStack_ << '\n' - << "Max locals: " << maxLocals_ << '\n' - << "Code size: " << codeSize_ << '\n'; - dumpCollection(exceptions_, "Exception", os); - dumpCollection(attributes_, "Attribute", os); + Attribute::dump(os) + << '\n' + << "Max stack: " << maxStack_ << '\n' + << "Max locals: " << maxLocals_ << '\n' + << "Code size: " << codeSize_ << '\n'; + dumpCollection(exceptions_, "Exception", os); + dumpCollection(attributes_, "Attribute", os); - return os; + return os; } CodeAttribute::Exception::Exception(const ConstantPool& cp, std::istream& is) - : catchType_(NULL) + : catchType_(NULL) { - startPc_ = readU2(is); - endPc_ = readU2(is); - handlerPc_ = readU2(is); - uint16_t idx = readU2(is); - if (idx) { - catchType_ = dynamic_cast(cp[idx]); - if (!catchType_) - throw ClassFileSemanticError - ("Representation of catch type is not of type ConstantClass"); - } + startPc_ = readU2(is); + endPc_ = readU2(is); + handlerPc_ = readU2(is); + uint16_t idx = readU2(is); + if (idx) { + catchType_ = dynamic_cast(cp[idx]); + if (!catchType_) + throw ClassFileSemanticError + ("Representation of catch type is not of type ConstantClass"); + } } std::ostream& CodeAttribute::Exception::dump(std::ostream& os) const { - if (getCatchType()) - os << *getCatchType() << '\n'; - else - os << "catch-all\n"; - return os << "Start PC: " << startPc_ << '\n' - << "End PC: " << endPc_ << '\n' - << "Handler PC: " << handlerPc_; + if (getCatchType()) + os << *getCatchType() << '\n'; + else + os << "catch-all\n"; + return os << "Start PC: " << startPc_ << '\n' + << "End PC: " << endPc_ << '\n' + << "Handler PC: " << handlerPc_; } //===----------------------------------------------------------------------===// @@ -717,17 +717,17 @@ ExceptionsAttribute::ExceptionsAttribute(ConstantUtf8* name, const ConstantPool& cp, std::istream& is) - : Attribute(name, cp, is) + : Attribute(name, cp, is) { - uint32_t length = readU4(is); - readClasses(exceptions_, cp, is); + uint32_t length = readU4(is); + readClasses(exceptions_, cp, is); } std::ostream& ExceptionsAttribute::dump(std::ostream& os) const { - os << Attribute::dump(os) << ": "; - for (Classes::const_iterator - i = exceptions_.begin(), e = exceptions_.end(); i != e; ++i) - os << *i << ' '; - return os; + os << Attribute::dump(os) << ": "; + for (Classes::const_iterator + i = exceptions_.begin(), e = exceptions_.end(); i != e; ++i) + os << *i << ' '; + return os; } From alkis at cs.uiuc.edu Wed Aug 4 05:02:14 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:02:14 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408041002.FAA26634@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.73 -> 1.74 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+802 -802) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.73 llvm-java/lib/Compiler/Compiler.cpp:1.74 --- llvm-java/lib/Compiler/Compiler.cpp:1.73 Wed Aug 4 04:49:18 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Wed Aug 4 05:02:03 2004 @@ -35,933 +35,933 @@ namespace llvm { namespace Java { namespace { - const std::string TMP("tmp"); + const std::string TMP("tmp"); - typedef std::vector BC2BBMap; - typedef std::stack > OperandStack; - typedef std::vector Locals; - - inline bool isTwoSlotValue(const Value* v) { - return v->getType() == Type::LongTy | v->getType() == Type::DoubleTy; - } - - inline bool isOneSlotValue(const Value* v) { - return !isTwoSlotValue(v); - } - - llvm::Constant* getConstant(Constant* c) { - if (dynamic_cast(c)) - assert(0 && "not implemented"); - else if (ConstantInteger* i = - dynamic_cast(c)) - return ConstantSInt::get(Type::IntTy, i->getValue()); - else if (ConstantFloat* f = dynamic_cast(c)) - return ConstantFP::get(Type::FloatTy, f->getValue()); - else if (ConstantLong* l = dynamic_cast(c)) - return ConstantSInt::get(Type::LongTy, l->getValue()); - else if (ConstantDouble* d = dynamic_cast(c)) - return ConstantFP::get(Type::DoubleTy, d->getValue()); + typedef std::vector BC2BBMap; + typedef std::stack > OperandStack; + typedef std::vector Locals; + + inline bool isTwoSlotValue(const Value* v) { + return v->getType() == Type::LongTy | v->getType() == Type::DoubleTy; + } + + inline bool isOneSlotValue(const Value* v) { + return !isTwoSlotValue(v); + } + + llvm::Constant* getConstant(Constant* c) { + if (dynamic_cast(c)) + assert(0 && "not implemented"); + else if (ConstantInteger* i = + dynamic_cast(c)) + return ConstantSInt::get(Type::IntTy, i->getValue()); + else if (ConstantFloat* f = dynamic_cast(c)) + return ConstantFP::get(Type::FloatTy, f->getValue()); + else if (ConstantLong* l = dynamic_cast(c)) + return ConstantSInt::get(Type::LongTy, l->getValue()); + else if (ConstantDouble* d = dynamic_cast(c)) + return ConstantFP::get(Type::DoubleTy, d->getValue()); + else + return NULL; // FIXME: throw something + } + + struct Bytecode2BasicBlockMapper + : public BytecodeParser { + public: + Bytecode2BasicBlockMapper(Function& f, + BC2BBMap& m, + CodeAttribute& c) + : function_(f), bc2bbMap_(m), codeAttr_(c) { } + + void compute() { + bc2bbMap_.clear(); + bc2bbMap_.assign(codeAttr_.getCodeSize(), NULL); + + BasicBlock* bb = new BasicBlock("entry", &function_); + + parse(codeAttr_.getCode(), codeAttr_.getCodeSize()); + + for (unsigned i = 0; i < bc2bbMap_.size(); ++i) { + if (bc2bbMap_[i]) + bb = bc2bbMap_[i]; else - return NULL; // FIXME: throw something - } - - struct Bytecode2BasicBlockMapper - : public BytecodeParser { - public: - Bytecode2BasicBlockMapper(Function& f, - BC2BBMap& m, - CodeAttribute& c) - : function_(f), bc2bbMap_(m), codeAttr_(c) { } - - void compute() { - bc2bbMap_.clear(); - bc2bbMap_.assign(codeAttr_.getCodeSize(), NULL); + bc2bbMap_[i] = bb; + } - BasicBlock* bb = new BasicBlock("entry", &function_); - - parse(codeAttr_.getCode(), codeAttr_.getCodeSize()); - - for (unsigned i = 0; i < bc2bbMap_.size(); ++i) { - if (bc2bbMap_[i]) - bb = bc2bbMap_[i]; - else - bc2bbMap_[i] = bb; - } + assert(function_.getEntryBlock().getName() == "entry"); + } - assert(function_.getEntryBlock().getName() == "entry"); - } + void do_if(unsigned bcI, JSetCC cc, JType type, + unsigned t, unsigned f) { + if (!bc2bbMap_[t]) + bc2bbMap_[t] = + new BasicBlock("bc" + utostr(t), &function_); + if (!bc2bbMap_[f]) + bc2bbMap_[f] = + new BasicBlock("bc" + utostr(f), &function_); + } - void do_if(unsigned bcI, JSetCC cc, JType type, - unsigned t, unsigned f) { - if (!bc2bbMap_[t]) - bc2bbMap_[t] = - new BasicBlock("bc" + utostr(t), &function_); - if (!bc2bbMap_[f]) - bc2bbMap_[f] = - new BasicBlock("bc" + utostr(f), &function_); - } + void do_ifcmp(unsigned bcI, JSetCC cc, + unsigned t, unsigned f) { + if (!bc2bbMap_[t]) + bc2bbMap_[t] = + new BasicBlock("bc" + utostr(t), &function_); + if (!bc2bbMap_[f]) + bc2bbMap_[f] = + new BasicBlock("bc" + utostr(f), &function_); + } - void do_ifcmp(unsigned bcI, JSetCC cc, - unsigned t, unsigned f) { - if (!bc2bbMap_[t]) - bc2bbMap_[t] = - new BasicBlock("bc" + utostr(t), &function_); - if (!bc2bbMap_[f]) - bc2bbMap_[f] = - new BasicBlock("bc" + utostr(f), &function_); - } + void do_switch(unsigned bcI, + unsigned defTarget, + const SwitchCases& sw) { + for (unsigned i = 0; i < sw.size(); ++i) { + unsigned target = sw[i].second; + if (!bc2bbMap_[target]) + bc2bbMap_[target] = + new BasicBlock("bc" + utostr(target), &function_); + } + if (!bc2bbMap_[defTarget]) + bc2bbMap_[defTarget] = + new BasicBlock("bc" + utostr(defTarget), &function_); + } - void do_switch(unsigned bcI, - unsigned defTarget, - const SwitchCases& sw) { - for (unsigned i = 0; i < sw.size(); ++i) { - unsigned target = sw[i].second; - if (!bc2bbMap_[target]) - bc2bbMap_[target] = - new BasicBlock("bc" + utostr(target), &function_); - } - if (!bc2bbMap_[defTarget]) - bc2bbMap_[defTarget] = - new BasicBlock("bc" + utostr(defTarget), &function_); - } + private: + Function& function_; + BC2BBMap& bc2bbMap_; + const CodeAttribute& codeAttr_; + }; + + struct CompilerImpl : + public BytecodeParser { + private: + Module* module_; + ClassFile* cf_; + OperandStack opStack_; + Locals locals_; + BC2BBMap bc2bbMap_; + BasicBlock* prologue_; + + typedef SetVector FunctionSet; + FunctionSet toCompileFunctions_; + + struct ClassInfo { + ClassInfo() : type(NULL) { } + Type* type; + typedef std::map Field2IndexMap; + Field2IndexMap f2iMap; + }; + typedef std::map Class2ClassInfoMap; + Class2ClassInfoMap c2ciMap_; - private: - Function& function_; - BC2BBMap& bc2bbMap_; - const CodeAttribute& codeAttr_; + struct VTableInfo { + VTableInfo() : vtable(NULL) { } + ConstantStruct* vtable; + typedef std::map Method2IndexMap; + Method2IndexMap m2iMap; }; + typedef std::map Class2VTableInfoMap; + Class2VTableInfoMap c2viMap_; - struct CompilerImpl : - public BytecodeParser { - private: - Module* module_; - ClassFile* cf_; - OperandStack opStack_; - Locals locals_; - BC2BBMap bc2bbMap_; - BasicBlock* prologue_; - - typedef SetVector FunctionSet; - FunctionSet toCompileFunctions_; - - struct ClassInfo { - ClassInfo() : type(NULL) { } - Type* type; - typedef std::map Field2IndexMap; - Field2IndexMap f2iMap; - }; - typedef std::map Class2ClassInfoMap; - Class2ClassInfoMap c2ciMap_; - - struct VTableInfo { - VTableInfo() : vtable(NULL) { } - ConstantStruct* vtable; - typedef std::map Method2IndexMap; - Method2IndexMap m2iMap; - }; - typedef std::map Class2VTableInfoMap; - Class2VTableInfoMap c2viMap_; - - private: - BasicBlock* getBBAt(unsigned bcI) { return bc2bbMap_[bcI]; } - - private: - Type* getType(JType type) { - switch (type) { - case REFERENCE: - return PointerType::get(getClassInfo("java/lang/Object").type); - case BOOLEAN: return Type::BoolTy; - case CHAR: return Type::UShortTy; - case FLOAT: return Type::FloatTy; - case DOUBLE: return Type::DoubleTy; - case BYTE: return Type::SByteTy; - case SHORT: return Type::ShortTy; - case INT: return Type::IntTy; - case LONG: return Type::LongTy; - default: assert(0 && "Invalid JType to Type conversion!"); - } + private: + BasicBlock* getBBAt(unsigned bcI) { return bc2bbMap_[bcI]; } - return NULL; - } + private: + Type* getType(JType type) { + switch (type) { + case REFERENCE: + return PointerType::get(getClassInfo("java/lang/Object").type); + case BOOLEAN: return Type::BoolTy; + case CHAR: return Type::UShortTy; + case FLOAT: return Type::FloatTy; + case DOUBLE: return Type::DoubleTy; + case BYTE: return Type::SByteTy; + case SHORT: return Type::ShortTy; + case INT: return Type::IntTy; + case LONG: return Type::LongTy; + default: assert(0 && "Invalid JType to Type conversion!"); + } - Instruction::BinaryOps getSetCC(JSetCC cc) { - switch (cc) { - case EQ: return Instruction::SetEQ; - case NE: return Instruction::SetNE; - case LT: return Instruction::SetLT; - case GE: return Instruction::SetGE; - case GT: return Instruction::SetGT; - case LE: return Instruction::SetLE; - default: assert(0 && "Invalid JSetCC to BinaryOps conversion!"); - } - return static_cast(-1); - } + return NULL; + } - /// Returns the type of the Java string descriptor. If the - /// Type* self is not NULL then that type is used as the first - /// type in function types - Type* getType(ConstantUtf8* descr, Type* self = NULL) { - unsigned i = 0; - return getTypeHelper(descr->str(), i, self); - } + Instruction::BinaryOps getSetCC(JSetCC cc) { + switch (cc) { + case EQ: return Instruction::SetEQ; + case NE: return Instruction::SetNE; + case LT: return Instruction::SetLT; + case GE: return Instruction::SetGE; + case GT: return Instruction::SetGT; + case LE: return Instruction::SetLE; + default: assert(0 && "Invalid JSetCC to BinaryOps conversion!"); + } + return static_cast(-1); + } - Type* getTypeHelper(const std::string& descr, unsigned& i, Type* self) { - assert(i < descr.size()); - switch (descr[i++]) { - case 'B': return Type::SByteTy; - case 'C': return Type::UShortTy; - case 'D': return Type::DoubleTy; - case 'F': return Type::FloatTy; - case 'I': return Type::IntTy; - case 'J': return Type::LongTy; - case 'S': return Type::ShortTy; - case 'Z': return Type::BoolTy; - case 'V': return Type::VoidTy; - case 'L': { - unsigned e = descr.find(';', i); - std::string className = descr.substr(i, e - i); - i = e + 1; - return PointerType::get(getClassInfo(className).type); - } - case '[': - // FIXME: this should really be a new class - // represeting the array of the following type - return PointerType::get( - ArrayType::get(getTypeHelper(descr, i, NULL), 0)); - case '(': { - std::vector params; - if (self) - params.push_back(PointerType::get(self)); - while (descr[i] != ')') - params.push_back(getTypeHelper(descr, i, NULL)); - return FunctionType::get(getTypeHelper(descr, ++i, NULL), - params, false); - } - // FIXME: Throw something - default: return NULL; - } - } + /// Returns the type of the Java string descriptor. If the + /// Type* self is not NULL then that type is used as the first + /// type in function types + Type* getType(ConstantUtf8* descr, Type* self = NULL) { + unsigned i = 0; + return getTypeHelper(descr->str(), i, self); + } - const ClassInfo& getClassInfo(const std::string& className) { - Class2ClassInfoMap::iterator it = c2ciMap_.lower_bound(className); - if (it != c2ciMap_.end() && it->first == className) - return it->second; - - DEBUG(std::cerr << "Building ClassInfo for: " << className << '\n'); - ClassFile* cf = ClassFile::getClassFile(className); - ClassInfo& ci = c2ciMap_[className]; - assert(!ci.type && ci.f2iMap.empty() && - "got already initialized Classinfo!"); - ci.type = OpaqueType::get(); - - std::vector elements; - ConstantClass* super = cf->getSuperClass(); - const ClassInfo* superCI = - super ? &getClassInfo(super->getName()->str()) : NULL; - if (superCI) - elements.push_back(superCI->type); - else { - // this is java/lang/Object so we must add the opaque - // llvm_java_base type first - Type* base = OpaqueType::get(); - module_->addTypeName("llvm_java_base", base); - elements.push_back(base); - } - - const Fields& fields = cf->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field* field = fields[i]; - if (!field->isStatic()) { - ci.f2iMap.insert(std::make_pair(field->getName()->str(), - elements.size())); - elements.push_back(getType(field->getDescriptor())); - } - } - PATypeHolder holder = ci.type; - cast(ci.type)->refineAbstractTypeTo - (StructType::get(elements)); - ci.type = holder.get(); - DEBUG(std::cerr << "Adding " << className << " = " - << *ci.type << " to type map\n"); - module_->addTypeName(className, ci.type); + Type* getTypeHelper(const std::string& descr, unsigned& i, Type* self) { + assert(i < descr.size()); + switch (descr[i++]) { + case 'B': return Type::SByteTy; + case 'C': return Type::UShortTy; + case 'D': return Type::DoubleTy; + case 'F': return Type::FloatTy; + case 'I': return Type::IntTy; + case 'J': return Type::LongTy; + case 'S': return Type::ShortTy; + case 'Z': return Type::BoolTy; + case 'V': return Type::VoidTy; + case 'L': { + unsigned e = descr.find(';', i); + std::string className = descr.substr(i, e - i); + i = e + 1; + return PointerType::get(getClassInfo(className).type); + } + case '[': + // FIXME: this should really be a new class + // represeting the array of the following type + return PointerType::get( + ArrayType::get(getTypeHelper(descr, i, NULL), 0)); + case '(': { + std::vector params; + if (self) + params.push_back(PointerType::get(self)); + while (descr[i] != ')') + params.push_back(getTypeHelper(descr, i, NULL)); + return FunctionType::get(getTypeHelper(descr, ++i, NULL), + params, false); + } + // FIXME: Throw something + default: return NULL; + } + } - assert(ci.type && "ClassInfo not initialized properly!"); - return ci; - } + const ClassInfo& getClassInfo(const std::string& className) { + Class2ClassInfoMap::iterator it = c2ciMap_.lower_bound(className); + if (it != c2ciMap_.end() && it->first == className) + return it->second; + + DEBUG(std::cerr << "Building ClassInfo for: " << className << '\n'); + ClassFile* cf = ClassFile::getClassFile(className); + ClassInfo& ci = c2ciMap_[className]; + assert(!ci.type && ci.f2iMap.empty() && + "got already initialized Classinfo!"); + ci.type = OpaqueType::get(); + + std::vector elements; + ConstantClass* super = cf->getSuperClass(); + const ClassInfo* superCI = + super ? &getClassInfo(super->getName()->str()) : NULL; + if (superCI) + elements.push_back(superCI->type); + else { + // this is java/lang/Object so we must add the opaque + // llvm_java_base type first + Type* base = OpaqueType::get(); + module_->addTypeName("llvm_java_base", base); + elements.push_back(base); + } + + const Fields& fields = cf->getFields(); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + Field* field = fields[i]; + if (!field->isStatic()) { + ci.f2iMap.insert(std::make_pair(field->getName()->str(), + elements.size())); + elements.push_back(getType(field->getDescriptor())); + } + } + PATypeHolder holder = ci.type; + cast(ci.type)->refineAbstractTypeTo + (StructType::get(elements)); + ci.type = holder.get(); + DEBUG(std::cerr << "Adding " << className << " = " + << *ci.type << " to type map\n"); + module_->addTypeName(className, ci.type); - //const VTableInfo& getVTableInfo(const std::string& className); + assert(ci.type && "ClassInfo not initialized properly!"); + return ci; + } - Value* getOrCreateLocal(unsigned index, Type* type) { - if (!locals_[index] || - cast(locals_[index]->getType())->getElementType() != type) { - locals_[index] = new AllocaInst - (type, NULL, "local" + utostr(index), prologue_); - } + //const VTableInfo& getVTableInfo(const std::string& className); - return locals_[index]; - } + Value* getOrCreateLocal(unsigned index, Type* type) { + if (!locals_[index] || + cast(locals_[index]->getType())->getElementType() != type) { + locals_[index] = new AllocaInst + (type, NULL, "local" + utostr(index), prologue_); + } - GlobalVariable* getStaticField(unsigned index) { - ConstantFieldRef* fieldRef = - (ConstantFieldRef*)(cf_->getConstantPool()[index]); - ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); - - std::string globalName = - fieldRef->getClass()->getName()->str() + '/' + - nameAndType->getName()->str(); + return locals_[index]; + } - GlobalVariable* global = module_->getGlobalVariable - (globalName, getType(nameAndType->getDescriptor())); + GlobalVariable* getStaticField(unsigned index) { + ConstantFieldRef* fieldRef = + (ConstantFieldRef*)(cf_->getConstantPool()[index]); + ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); + + std::string globalName = + fieldRef->getClass()->getName()->str() + '/' + + nameAndType->getName()->str(); - return global; - } + GlobalVariable* global = module_->getGlobalVariable + (globalName, getType(nameAndType->getDescriptor())); - Value* getField(unsigned bcI, unsigned index, Value* ptr) { - ConstantFieldRef* fieldRef = - (ConstantFieldRef*)(cf_->getConstantPool()[index]); - ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); - - // Cast ptr to correct type - std::string className = fieldRef->getClass()->getName()->str(); - ptr = new CastInst(ptr, - PointerType::get(getClassInfo(className).type), - TMP, getBBAt(bcI)); - ClassFile* classfile = ClassFile::getClassFile(className); - std::string fieldName = nameAndType->getName()->str(); - - // deref pointer - std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); - while (true) { - const ClassInfo& info = getClassInfo(className); - ClassInfo::Field2IndexMap::const_iterator it = - info.f2iMap.find(fieldName); - if (it == info.f2iMap.end()) { - className = classfile->getSuperClass()->getName()->str(); - classfile = ClassFile::getClassFile(className); - indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); - } - else { - indices.push_back(ConstantUInt::get(Type::UIntTy, - it->second)); - break; - } - } + return global; + } - return new GetElementPtrInst(ptr, indices, TMP, getBBAt(bcI)); + Value* getField(unsigned bcI, unsigned index, Value* ptr) { + ConstantFieldRef* fieldRef = + (ConstantFieldRef*)(cf_->getConstantPool()[index]); + ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); + + // Cast ptr to correct type + std::string className = fieldRef->getClass()->getName()->str(); + ptr = new CastInst(ptr, + PointerType::get(getClassInfo(className).type), + TMP, getBBAt(bcI)); + ClassFile* classfile = ClassFile::getClassFile(className); + std::string fieldName = nameAndType->getName()->str(); + + // deref pointer + std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); + while (true) { + const ClassInfo& info = getClassInfo(className); + ClassInfo::Field2IndexMap::const_iterator it = + info.f2iMap.find(fieldName); + if (it == info.f2iMap.end()) { + className = classfile->getSuperClass()->getName()->str(); + classfile = ClassFile::getClassFile(className); + indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); + } + else { + indices.push_back(ConstantUInt::get(Type::UIntTy, + it->second)); + break; } + } - Function* compileMethodOnly(const std::string& classMethodDesc) { - DEBUG(std::cerr << "Compiling method: " << classMethodDesc << '\n'); + return new GetElementPtrInst(ptr, indices, TMP, getBBAt(bcI)); + } - Method* method; - tie(cf_, method) = findClassAndMethod(classMethodDesc); + Function* compileMethodOnly(const std::string& classMethodDesc) { + DEBUG(std::cerr << "Compiling method: " << classMethodDesc << '\n'); - std::string name = cf_->getThisClass()->getName()->str(); - name += '/'; - name += method->getName()->str(); - name += method->getDescriptor()->str(); + Method* method; + tie(cf_, method) = findClassAndMethod(classMethodDesc); - Function* function = module_->getOrInsertFunction - (name, cast(getType(method->getDescriptor()))); - function->setLinkage(method->isPrivate() ? - Function::InternalLinkage : - Function::ExternalLinkage); + std::string name = cf_->getThisClass()->getName()->str(); + name += '/'; + name += method->getName()->str(); + name += method->getDescriptor()->str(); - Java::CodeAttribute* codeAttr = method->getCodeAttribute(); + Function* function = module_->getOrInsertFunction + (name, cast(getType(method->getDescriptor()))); + function->setLinkage(method->isPrivate() ? + Function::InternalLinkage : + Function::ExternalLinkage); - while (!opStack_.empty()) - opStack_.pop(); + Java::CodeAttribute* codeAttr = method->getCodeAttribute(); - locals_.clear(); - locals_.assign(codeAttr->getMaxLocals(), NULL); + while (!opStack_.empty()) + opStack_.pop(); - Bytecode2BasicBlockMapper mapper(*function, bc2bbMap_, *codeAttr); - mapper.compute(); + locals_.clear(); + locals_.assign(codeAttr->getMaxLocals(), NULL); - prologue_ = new BasicBlock("prologue"); + Bytecode2BasicBlockMapper mapper(*function, bc2bbMap_, *codeAttr); + mapper.compute(); - parse(codeAttr->getCode(), codeAttr->getCodeSize()); + prologue_ = new BasicBlock("prologue"); - // if the prologue is not empty, make it the entry block - // of the function with entry as its only successor - if (prologue_->empty()) - delete prologue_; - else { - function->getBasicBlockList().push_front(prologue_); - new BranchInst(prologue_->getNext(), prologue_); - } + parse(codeAttr->getCode(), codeAttr->getCodeSize()); - return function; - } + // if the prologue is not empty, make it the entry block + // of the function with entry as its only successor + if (prologue_->empty()) + delete prologue_; + else { + function->getBasicBlockList().push_front(prologue_); + new BranchInst(prologue_->getNext(), prologue_); + } + + return function; + } - void emitStaticInitializers(const ClassFile* classfile) { - const Method* method = classfile->getMethod("()V"); - if (!method) - return; - - std::string name = classfile->getThisClass()->getName()->str(); - name += '/'; - name += method->getName()->str(); - name += method->getDescriptor()->str(); - - Function* hook = - module_->getOrInsertFunction("llvm_java_static_init", - Type::VoidTy, 0); - Function* init = - module_->getOrInsertFunction(name, Type::VoidTy, 0); - - // if this is the first time we scheduled this function - // for compilation insert a call to it right before the - // terminator of the only basic block in - // llvm_java_static_init - if (toCompileFunctions_.insert(init)) { - assert(hook->front().getTerminator() && - "llvm_java_static_init should have a terminator!"); - new CallInst(init, "", hook->front().getTerminator()); - // we also create the global variables of this class - const Fields& fields = classfile->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field* field = fields[i]; - if (field->isStatic()) { - llvm::Constant* init = NULL; - if (ConstantValueAttribute* cv = - field->getConstantValueAttribute()) - init = getConstant(cv->getValue()); - - new GlobalVariable(getType(field->getDescriptor()), - field->isFinal(), - (field->isPrivate() & bool(init) ? - GlobalVariable::InternalLinkage : - GlobalVariable::ExternalLinkage), - init, - classfile->getThisClass()->getName()->str() + '/' + field->getName()->str(), - module_); - } - } - } + void emitStaticInitializers(const ClassFile* classfile) { + const Method* method = classfile->getMethod("()V"); + if (!method) + return; + + std::string name = classfile->getThisClass()->getName()->str(); + name += '/'; + name += method->getName()->str(); + name += method->getDescriptor()->str(); + + Function* hook = + module_->getOrInsertFunction("llvm_java_static_init", + Type::VoidTy, 0); + Function* init = + module_->getOrInsertFunction(name, Type::VoidTy, 0); + + // if this is the first time we scheduled this function + // for compilation insert a call to it right before the + // terminator of the only basic block in + // llvm_java_static_init + if (toCompileFunctions_.insert(init)) { + assert(hook->front().getTerminator() && + "llvm_java_static_init should have a terminator!"); + new CallInst(init, "", hook->front().getTerminator()); + // we also create the global variables of this class + const Fields& fields = classfile->getFields(); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + Field* field = fields[i]; + if (field->isStatic()) { + llvm::Constant* init = NULL; + if (ConstantValueAttribute* cv = + field->getConstantValueAttribute()) + init = getConstant(cv->getValue()); + + new GlobalVariable(getType(field->getDescriptor()), + field->isFinal(), + (field->isPrivate() & bool(init) ? + GlobalVariable::InternalLinkage : + GlobalVariable::ExternalLinkage), + init, + classfile->getThisClass()->getName()->str() + '/' + field->getName()->str(), + module_); + } } + } + } - std::pair - findClassAndMethod(const std::string& classMethodDesc) { - unsigned slash = classMethodDesc.find('/'); - std::string className = classMethodDesc.substr(0, slash); - std::string methodNameAndDescr = classMethodDesc.substr(slash+1); - - ClassFile* classfile = ClassFile::getClassFile(className); - emitStaticInitializers(classfile); - Method* method = classfile->getMethod(methodNameAndDescr); - - if (!method) - throw InvocationTargetException( - "Method " + methodNameAndDescr + - " not found in class " + className); + std::pair + findClassAndMethod(const std::string& classMethodDesc) { + unsigned slash = classMethodDesc.find('/'); + std::string className = classMethodDesc.substr(0, slash); + std::string methodNameAndDescr = classMethodDesc.substr(slash+1); + + ClassFile* classfile = ClassFile::getClassFile(className); + emitStaticInitializers(classfile); + Method* method = classfile->getMethod(methodNameAndDescr); + + if (!method) + throw InvocationTargetException( + "Method " + methodNameAndDescr + + " not found in class " + className); - return std::make_pair(classfile, method); - } + return std::make_pair(classfile, method); + } - public: - Function* compileMethod(Module& module, - const std::string& classMethodDesc) { - module_ = &module; - // initialize the static initializer function - Function* staticInit = - module_->getOrInsertFunction("llvm_java_static_init", - Type::VoidTy, 0); - BasicBlock* staticInitBB = new BasicBlock("entry", staticInit); - new ReturnInst(NULL, staticInitBB); - - // compile the method requested - Function* function = compileMethodOnly(classMethodDesc); - // compile all other methods called by this method recursively - for (unsigned i = 0; i != toCompileFunctions_.size(); ++i) { - Function* f = toCompileFunctions_[i]; - compileMethodOnly(f->getName()); - } + public: + Function* compileMethod(Module& module, + const std::string& classMethodDesc) { + module_ = &module; + // initialize the static initializer function + Function* staticInit = + module_->getOrInsertFunction("llvm_java_static_init", + Type::VoidTy, 0); + BasicBlock* staticInitBB = new BasicBlock("entry", staticInit); + new ReturnInst(NULL, staticInitBB); + + // compile the method requested + Function* function = compileMethodOnly(classMethodDesc); + // compile all other methods called by this method recursively + for (unsigned i = 0; i != toCompileFunctions_.size(); ++i) { + Function* f = toCompileFunctions_[i]; + compileMethodOnly(f->getName()); + } - return function; - } + return function; + } - void do_aconst_null(unsigned bcI) { - opStack_.push(llvm::Constant::getNullValue(getType(REFERENCE))); - } + void do_aconst_null(unsigned bcI) { + opStack_.push(llvm::Constant::getNullValue(getType(REFERENCE))); + } - void do_iconst(unsigned bcI, int value) { - opStack_.push(ConstantSInt::get(Type::IntTy, value)); - } + void do_iconst(unsigned bcI, int value) { + opStack_.push(ConstantSInt::get(Type::IntTy, value)); + } - void do_lconst(unsigned bcI, long long value) { - opStack_.push(ConstantSInt::get(Type::LongTy, value)); - } + void do_lconst(unsigned bcI, long long value) { + opStack_.push(ConstantSInt::get(Type::LongTy, value)); + } - void do_fconst(unsigned bcI, float value) { - opStack_.push(ConstantFP::get(Type::FloatTy, value)); - } + void do_fconst(unsigned bcI, float value) { + opStack_.push(ConstantFP::get(Type::FloatTy, value)); + } - void do_dconst(unsigned bcI, double value) { - opStack_.push(ConstantFP::get(Type::DoubleTy, value)); - } + void do_dconst(unsigned bcI, double value) { + opStack_.push(ConstantFP::get(Type::DoubleTy, value)); + } - void do_ldc(unsigned bcI, unsigned index) { - Constant* c = cf_->getConstantPool()[index]; - assert(getConstant(c) && "Java constant not handled!"); - opStack_.push(getConstant(c)); - } + void do_ldc(unsigned bcI, unsigned index) { + Constant* c = cf_->getConstantPool()[index]; + assert(getConstant(c) && "Java constant not handled!"); + opStack_.push(getConstant(c)); + } - void do_load(unsigned bcI, JType type, unsigned index) { - opStack_.push(new LoadInst(getOrCreateLocal(index, getType(type)), - TMP, getBBAt(bcI))); - } + void do_load(unsigned bcI, JType type, unsigned index) { + opStack_.push(new LoadInst(getOrCreateLocal(index, getType(type)), + TMP, getBBAt(bcI))); + } - void do_aload(unsigned bcI, JType type) { - assert(0 && "not implemented"); - } + void do_aload(unsigned bcI, JType type) { + assert(0 && "not implemented"); + } - void do_store(unsigned bcI, JType type, unsigned index) { - Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push( - new StoreInst(v1, getOrCreateLocal(index, getType(type)), - getBBAt(bcI))); - } + void do_store(unsigned bcI, JType type, unsigned index) { + Value* v1 = opStack_.top(); opStack_.pop(); + opStack_.push( + new StoreInst(v1, getOrCreateLocal(index, getType(type)), + getBBAt(bcI))); + } - void do_astore(unsigned bcI, JType type) { - assert(0 && "not implemented"); - } + void do_astore(unsigned bcI, JType type) { + assert(0 && "not implemented"); + } - void do_pop(unsigned bcI) { - opStack_.pop(); - } + void do_pop(unsigned bcI) { + opStack_.pop(); + } - void do_pop2(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v1)) - opStack_.pop(); - } + void do_pop2(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v1)) + opStack_.pop(); + } - void do_dup(unsigned bcI) { - opStack_.push(opStack_.top()); - } + void do_dup(unsigned bcI) { + opStack_.push(opStack_.top()); + } - void do_dup_x1(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - Value* v2 = opStack_.top(); opStack_.pop(); - opStack_.push(v1); - opStack_.push(v2); - opStack_.push(v1); - } + void do_dup_x1(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + Value* v2 = opStack_.top(); opStack_.pop(); + opStack_.push(v1); + opStack_.push(v2); + opStack_.push(v1); + } - void do_dup_x2(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - Value* v2 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v2)) { - Value* v3 = opStack_.top(); opStack_.pop(); - opStack_.push(v1); - opStack_.push(v3); - opStack_.push(v2); - opStack_.push(v1); - } - else { - opStack_.push(v1); - opStack_.push(v2); - opStack_.push(v1); - } - } + void do_dup_x2(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + Value* v2 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v2)) { + Value* v3 = opStack_.top(); opStack_.pop(); + opStack_.push(v1); + opStack_.push(v3); + opStack_.push(v2); + opStack_.push(v1); + } + else { + opStack_.push(v1); + opStack_.push(v2); + opStack_.push(v1); + } + } - void do_dup2(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v1)) { - Value* v2 = opStack_.top(); opStack_.pop(); - opStack_.push(v2); - opStack_.push(v1); - opStack_.push(v2); - opStack_.push(v1); - } - else { - opStack_.push(v1); - opStack_.push(v1); - } - } + void do_dup2(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v1)) { + Value* v2 = opStack_.top(); opStack_.pop(); + opStack_.push(v2); + opStack_.push(v1); + opStack_.push(v2); + opStack_.push(v1); + } + else { + opStack_.push(v1); + opStack_.push(v1); + } + } - void do_dup2_x1(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - Value* v2 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v1)) { - Value* v3 = opStack_.top(); opStack_.pop(); - opStack_.push(v2); - opStack_.push(v1); - opStack_.push(v3); - opStack_.push(v2); - opStack_.push(v1); - } - else { - opStack_.push(v1); - opStack_.push(v2); - opStack_.push(v1); - } - } + void do_dup2_x1(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + Value* v2 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v1)) { + Value* v3 = opStack_.top(); opStack_.pop(); + opStack_.push(v2); + opStack_.push(v1); + opStack_.push(v3); + opStack_.push(v2); + opStack_.push(v1); + } + else { + opStack_.push(v1); + opStack_.push(v2); + opStack_.push(v1); + } + } - void do_dup2_x2(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - Value* v2 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v1)) { - Value* v3 = opStack_.top(); opStack_.pop(); - if (isOneSlotValue(v3)) { - Value* v4 = opStack_.top(); opStack_.pop(); - opStack_.push(v2); - opStack_.push(v1); - opStack_.push(v4); - opStack_.push(v3); - opStack_.push(v2); - opStack_.push(v1); - } - else { - opStack_.push(v2); - opStack_.push(v1); - opStack_.push(v3); - opStack_.push(v2); - opStack_.push(v1); - } - } - else { - if (isOneSlotValue(v2)) { - Value* v3 = opStack_.top(); opStack_.pop(); - opStack_.push(v1); - opStack_.push(v3); - opStack_.push(v2); - opStack_.push(v1); - } - else { - opStack_.push(v1); - opStack_.push(v2); - opStack_.push(v1); - } - } + void do_dup2_x2(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + Value* v2 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v1)) { + Value* v3 = opStack_.top(); opStack_.pop(); + if (isOneSlotValue(v3)) { + Value* v4 = opStack_.top(); opStack_.pop(); + opStack_.push(v2); + opStack_.push(v1); + opStack_.push(v4); + opStack_.push(v3); + opStack_.push(v2); + opStack_.push(v1); + } + else { + opStack_.push(v2); + opStack_.push(v1); + opStack_.push(v3); + opStack_.push(v2); + opStack_.push(v1); + } + } + else { + if (isOneSlotValue(v2)) { + Value* v3 = opStack_.top(); opStack_.pop(); + opStack_.push(v1); + opStack_.push(v3); + opStack_.push(v2); + opStack_.push(v1); + } + else { + opStack_.push(v1); + opStack_.push(v2); + opStack_.push(v1); } + } + } - void do_swap(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - Value* v2 = opStack_.top(); opStack_.pop(); - opStack_.push(v1); - opStack_.push(v2); - } + void do_swap(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + Value* v2 = opStack_.top(); opStack_.pop(); + opStack_.push(v1); + opStack_.push(v2); + } - void do_add(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Add); - } + void do_add(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Add); + } - void do_sub(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Sub); - } + void do_sub(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Sub); + } - void do_mul(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Mul); - } + void do_mul(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Mul); + } - void do_div(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Div); - } + void do_div(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Div); + } - void do_rem(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Rem); - } + void do_rem(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Rem); + } - void do_neg(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push( - BinaryOperator::createNeg(v1, TMP, getBBAt(bcI))); - } + void do_neg(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + opStack_.push( + BinaryOperator::createNeg(v1, TMP, getBBAt(bcI))); + } - void do_shl(unsigned bcI) { - do_shift_common(bcI, Instruction::Shl); - } + void do_shl(unsigned bcI) { + do_shift_common(bcI, Instruction::Shl); + } - void do_shr(unsigned bcI) { - do_shift_common(bcI, Instruction::Shr); - } + void do_shr(unsigned bcI) { + do_shift_common(bcI, Instruction::Shr); + } - void do_ushr(unsigned bcI) { - // cast value to be shifted into its unsigned version - do_swap(bcI); - Value* value = opStack_.top(); opStack_.pop(); - value = new CastInst(value, - value->getType()->getUnsignedVersion(), - TMP, getBBAt(bcI)); - opStack_.push(value); - do_swap(bcI); - - do_shift_common(bcI, Instruction::Shr); - - value = opStack_.top(); opStack_.pop(); - // cast shifted value back to its original signed version - opStack_.push(new CastInst(value, - value->getType()->getSignedVersion(), - TMP, getBBAt(bcI))); - } + void do_ushr(unsigned bcI) { + // cast value to be shifted into its unsigned version + do_swap(bcI); + Value* value = opStack_.top(); opStack_.pop(); + value = new CastInst(value, + value->getType()->getUnsignedVersion(), + TMP, getBBAt(bcI)); + opStack_.push(value); + do_swap(bcI); + + do_shift_common(bcI, Instruction::Shr); + + value = opStack_.top(); opStack_.pop(); + // cast shifted value back to its original signed version + opStack_.push(new CastInst(value, + value->getType()->getSignedVersion(), + TMP, getBBAt(bcI))); + } - void do_shift_common(unsigned bcI, Instruction::OtherOps op) { - Value* amount = opStack_.top(); opStack_.pop(); - Value* value = opStack_.top(); opStack_.pop(); - amount = new CastInst(amount, Type::UByteTy, TMP, getBBAt(bcI)); - opStack_.push(new ShiftInst(op, value, amount, TMP, getBBAt(bcI))); - } + void do_shift_common(unsigned bcI, Instruction::OtherOps op) { + Value* amount = opStack_.top(); opStack_.pop(); + Value* value = opStack_.top(); opStack_.pop(); + amount = new CastInst(amount, Type::UByteTy, TMP, getBBAt(bcI)); + opStack_.push(new ShiftInst(op, value, amount, TMP, getBBAt(bcI))); + } - void do_and(unsigned bcI) { - do_binary_op_common(bcI, Instruction::And); - } + void do_and(unsigned bcI) { + do_binary_op_common(bcI, Instruction::And); + } - void do_or(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Or); - } + void do_or(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Or); + } - void do_xor(unsigned bcI) { - do_binary_op_common(bcI, Instruction::Xor); - } + void do_xor(unsigned bcI) { + do_binary_op_common(bcI, Instruction::Xor); + } - void do_binary_op_common(unsigned bcI, Instruction::BinaryOps op) { - Value* v2 = opStack_.top(); opStack_.pop(); - Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push(BinaryOperator::create(op, v1, v2, TMP,getBBAt(bcI))); - } + void do_binary_op_common(unsigned bcI, Instruction::BinaryOps op) { + Value* v2 = opStack_.top(); opStack_.pop(); + Value* v1 = opStack_.top(); opStack_.pop(); + opStack_.push(BinaryOperator::create(op, v1, v2, TMP,getBBAt(bcI))); + } - void do_iinc(unsigned bcI, unsigned index, int amount) { - Value* v = new LoadInst(getOrCreateLocal(index, Type::IntTy), - TMP, getBBAt(bcI)); - BinaryOperator::createAdd(v, ConstantSInt::get(Type::IntTy, amount), - TMP, getBBAt(bcI)); - new StoreInst(v, getOrCreateLocal(index, Type::IntTy), - getBBAt(bcI)); - } + void do_iinc(unsigned bcI, unsigned index, int amount) { + Value* v = new LoadInst(getOrCreateLocal(index, Type::IntTy), + TMP, getBBAt(bcI)); + BinaryOperator::createAdd(v, ConstantSInt::get(Type::IntTy, amount), + TMP, getBBAt(bcI)); + new StoreInst(v, getOrCreateLocal(index, Type::IntTy), + getBBAt(bcI)); + } - void do_convert(unsigned bcI, JType to) { - Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push(new CastInst(v1, getType(to), TMP, getBBAt(bcI))); - } + void do_convert(unsigned bcI, JType to) { + Value* v1 = opStack_.top(); opStack_.pop(); + opStack_.push(new CastInst(v1, getType(to), TMP, getBBAt(bcI))); + } - void do_lcmp(unsigned bcI) { - Value* v2 = opStack_.top(); opStack_.pop(); - Value* v1 = opStack_.top(); opStack_.pop(); - Value* c = BinaryOperator::createSetGT(v1, v2, TMP, getBBAt(bcI)); - Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), - ConstantSInt::get(Type::IntTy, 0), TMP, - getBBAt(bcI)); - c = BinaryOperator::createSetLT(v1, v2, TMP, getBBAt(bcI)); - r = new SelectInst(c, ConstantSInt::get(Type::IntTy, -1), r, TMP, - getBBAt(bcI)); - opStack_.push(r); - } + void do_lcmp(unsigned bcI) { + Value* v2 = opStack_.top(); opStack_.pop(); + Value* v1 = opStack_.top(); opStack_.pop(); + Value* c = BinaryOperator::createSetGT(v1, v2, TMP, getBBAt(bcI)); + Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), + ConstantSInt::get(Type::IntTy, 0), TMP, + getBBAt(bcI)); + c = BinaryOperator::createSetLT(v1, v2, TMP, getBBAt(bcI)); + r = new SelectInst(c, ConstantSInt::get(Type::IntTy, -1), r, TMP, + getBBAt(bcI)); + opStack_.push(r); + } - void do_cmpl(unsigned bcI) { - do_cmp_common(bcI, -1); - } + void do_cmpl(unsigned bcI) { + do_cmp_common(bcI, -1); + } - void do_cmpg(unsigned bcI) { - do_cmp_common(bcI, 1); - } + void do_cmpg(unsigned bcI) { + do_cmp_common(bcI, 1); + } - void do_cmp_common(unsigned bcI, int valueIfUnordered) { - Value* v2 = opStack_.top(); opStack_.pop(); - Value* v1 = opStack_.top(); opStack_.pop(); - Value* c = BinaryOperator::createSetGT(v1, v2, TMP, getBBAt(bcI)); - Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), - ConstantSInt::get(Type::IntTy, 0), TMP, - getBBAt(bcI)); - c = BinaryOperator::createSetLT(v1, v2, TMP, getBBAt(bcI)); - r = new SelectInst(c, ConstantSInt::get(Type::IntTy, -1), r, TMP, - getBBAt(bcI)); - c = new CallInst(module_->getOrInsertFunction - ("llvm.isunordered", - Type::BoolTy, v1->getType(), v2->getType(), 0), - v1, v2, TMP, getBBAt(bcI)); - r = new SelectInst(c, - ConstantSInt::get(Type::IntTy, valueIfUnordered), - r, TMP, getBBAt(bcI)); - opStack_.push(r); - } + void do_cmp_common(unsigned bcI, int valueIfUnordered) { + Value* v2 = opStack_.top(); opStack_.pop(); + Value* v1 = opStack_.top(); opStack_.pop(); + Value* c = BinaryOperator::createSetGT(v1, v2, TMP, getBBAt(bcI)); + Value* r = new SelectInst(c, ConstantSInt::get(Type::IntTy, 1), + ConstantSInt::get(Type::IntTy, 0), TMP, + getBBAt(bcI)); + c = BinaryOperator::createSetLT(v1, v2, TMP, getBBAt(bcI)); + r = new SelectInst(c, ConstantSInt::get(Type::IntTy, -1), r, TMP, + getBBAt(bcI)); + c = new CallInst(module_->getOrInsertFunction + ("llvm.isunordered", + Type::BoolTy, v1->getType(), v2->getType(), 0), + v1, v2, TMP, getBBAt(bcI)); + r = new SelectInst(c, + ConstantSInt::get(Type::IntTy, valueIfUnordered), + r, TMP, getBBAt(bcI)); + opStack_.push(r); + } - void do_if(unsigned bcI, JSetCC cc, JType type, - unsigned t, unsigned f) { - Value* v2 = llvm::Constant::getNullValue(getType(type)); - Value* v1 = opStack_.top(); opStack_.pop(); - Value* c = new SetCondInst(getSetCC(cc), v1, v2, TMP, getBBAt(bcI)); - new BranchInst(getBBAt(t), getBBAt(f), c, getBBAt(bcI)); - } + void do_if(unsigned bcI, JSetCC cc, JType type, + unsigned t, unsigned f) { + Value* v2 = llvm::Constant::getNullValue(getType(type)); + Value* v1 = opStack_.top(); opStack_.pop(); + Value* c = new SetCondInst(getSetCC(cc), v1, v2, TMP, getBBAt(bcI)); + new BranchInst(getBBAt(t), getBBAt(f), c, getBBAt(bcI)); + } - void do_ifcmp(unsigned bcI, JSetCC cc, - unsigned t, unsigned f) { - Value* v2 = opStack_.top(); opStack_.pop(); - Value* v1 = opStack_.top(); opStack_.pop(); - Value* c = new SetCondInst(getSetCC(cc), v1, v2, TMP, getBBAt(bcI)); - new BranchInst(getBBAt(t), getBBAt(f), c, getBBAt(bcI)); - } + void do_ifcmp(unsigned bcI, JSetCC cc, + unsigned t, unsigned f) { + Value* v2 = opStack_.top(); opStack_.pop(); + Value* v1 = opStack_.top(); opStack_.pop(); + Value* c = new SetCondInst(getSetCC(cc), v1, v2, TMP, getBBAt(bcI)); + new BranchInst(getBBAt(t), getBBAt(f), c, getBBAt(bcI)); + } - void do_goto(unsigned bcI, unsigned target) { - new BranchInst(getBBAt(target), getBBAt(bcI)); - } + void do_goto(unsigned bcI, unsigned target) { + new BranchInst(getBBAt(target), getBBAt(bcI)); + } - void do_jsr(unsigned bcI, unsigned target) { - assert(0 && "not implemented"); - } + void do_jsr(unsigned bcI, unsigned target) { + assert(0 && "not implemented"); + } - void do_ret(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_ret(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_switch(unsigned bcI, - unsigned defTarget, - const SwitchCases& sw) { - Value* v1 = opStack_.top(); opStack_.pop(); - SwitchInst* in = - new SwitchInst(v1, getBBAt(defTarget), getBBAt(bcI)); - for (unsigned i = 0; i < sw.size(); ++i) - in->addCase(ConstantSInt::get(Type::IntTy, sw[i].first), - getBBAt(sw[i].second)); - } + void do_switch(unsigned bcI, + unsigned defTarget, + const SwitchCases& sw) { + Value* v1 = opStack_.top(); opStack_.pop(); + SwitchInst* in = + new SwitchInst(v1, getBBAt(defTarget), getBBAt(bcI)); + for (unsigned i = 0; i < sw.size(); ++i) + in->addCase(ConstantSInt::get(Type::IntTy, sw[i].first), + getBBAt(sw[i].second)); + } - void do_return(unsigned bcI) { - Value* v1 = opStack_.top(); opStack_.pop(); - new ReturnInst(v1, getBBAt(bcI)); - } + void do_return(unsigned bcI) { + Value* v1 = opStack_.top(); opStack_.pop(); + new ReturnInst(v1, getBBAt(bcI)); + } - void do_return_void(unsigned bcI) { - new ReturnInst(NULL, getBBAt(bcI)); - } + void do_return_void(unsigned bcI) { + new ReturnInst(NULL, getBBAt(bcI)); + } - void do_getstatic(unsigned bcI, unsigned index) { - Value* v = new LoadInst(getStaticField(index), TMP, getBBAt(bcI)); - opStack_.push(v); - } + void do_getstatic(unsigned bcI, unsigned index) { + Value* v = new LoadInst(getStaticField(index), TMP, getBBAt(bcI)); + opStack_.push(v); + } - void do_putstatic(unsigned bcI, unsigned index) { - Value* v = opStack_.top(); opStack_.pop(); - new StoreInst(v, getStaticField(index), getBBAt(bcI)); - } + void do_putstatic(unsigned bcI, unsigned index) { + Value* v = opStack_.top(); opStack_.pop(); + new StoreInst(v, getStaticField(index), getBBAt(bcI)); + } - void do_getfield(unsigned bcI, unsigned index) { - Value* p = opStack_.top(); opStack_.pop(); - Value* v = new LoadInst(getField(bcI, index, p), TMP, getBBAt(bcI)); - opStack_.push(v); - } + void do_getfield(unsigned bcI, unsigned index) { + Value* p = opStack_.top(); opStack_.pop(); + Value* v = new LoadInst(getField(bcI, index, p), TMP, getBBAt(bcI)); + opStack_.push(v); + } - void do_putfield(unsigned bcI, unsigned index) { - Value* v = opStack_.top(); opStack_.pop(); - Value* p = opStack_.top(); opStack_.pop(); - new StoreInst(v, getField(bcI, index, p), getBBAt(bcI)); - } + void do_putfield(unsigned bcI, unsigned index) { + Value* v = opStack_.top(); opStack_.pop(); + Value* p = opStack_.top(); opStack_.pop(); + new StoreInst(v, getField(bcI, index, p), getBBAt(bcI)); + } - void do_invokevirtual(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_invokevirtual(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_invokespecial(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_invokespecial(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_invokestatic(unsigned bcI, unsigned index) { - ConstantMethodRef* methodRef = - (ConstantMethodRef*)(cf_->getConstantPool()[index]); - ConstantNameAndType* nameAndType = methodRef->getNameAndType(); - - std::string funcName = - methodRef->getClass()->getName()->str() + '/' + - nameAndType->getName()->str() + - nameAndType->getDescriptor()->str(); - - FunctionType* funcType = - cast(getType(nameAndType->getDescriptor())); - std::vector params(funcType->getNumParams(), NULL); - for (unsigned i = 0, e = funcType->getNumParams(); i != e; ++i) { - Value* p = opStack_.top(); opStack_.pop(); - const Type* paramTy = funcType->getParamType(i); - params[i] = p->getType() == paramTy ? p : - new CastInst(p, paramTy, TMP, getBBAt(bcI)); - } - - Function* function = - module_->getOrInsertFunction(funcName, funcType); - toCompileFunctions_.insert(function); - Value* r = new CallInst(function, params, TMP, getBBAt(bcI)); - opStack_.push(r); - } + void do_invokestatic(unsigned bcI, unsigned index) { + ConstantMethodRef* methodRef = + (ConstantMethodRef*)(cf_->getConstantPool()[index]); + ConstantNameAndType* nameAndType = methodRef->getNameAndType(); + + std::string funcName = + methodRef->getClass()->getName()->str() + '/' + + nameAndType->getName()->str() + + nameAndType->getDescriptor()->str(); + + FunctionType* funcType = + cast(getType(nameAndType->getDescriptor())); + std::vector params(funcType->getNumParams(), NULL); + for (unsigned i = 0, e = funcType->getNumParams(); i != e; ++i) { + Value* p = opStack_.top(); opStack_.pop(); + const Type* paramTy = funcType->getParamType(i); + params[i] = p->getType() == paramTy ? p : + new CastInst(p, paramTy, TMP, getBBAt(bcI)); + } + + Function* function = + module_->getOrInsertFunction(funcName, funcType); + toCompileFunctions_.insert(function); + Value* r = new CallInst(function, params, TMP, getBBAt(bcI)); + opStack_.push(r); + } - void do_invokeinterface(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_invokeinterface(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_new(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_new(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_newarray(unsigned bcI, JType type) { - assert(0 && "not implemented"); - } + void do_newarray(unsigned bcI, JType type) { + assert(0 && "not implemented"); + } - void do_anewarray(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_anewarray(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_arraylength(unsigned bcI) { - assert(0 && "not implemented"); - } + void do_arraylength(unsigned bcI) { + assert(0 && "not implemented"); + } - void do_athrow(unsigned bcI) { - assert(0 && "not implemented"); - } + void do_athrow(unsigned bcI) { + assert(0 && "not implemented"); + } - void do_checkcast(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_checkcast(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_instanceof(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); - } + void do_instanceof(unsigned bcI, unsigned index) { + assert(0 && "not implemented"); + } - void do_monitorenter(unsigned bcI) { - assert(0 && "not implemented"); - } + void do_monitorenter(unsigned bcI) { + assert(0 && "not implemented"); + } - void do_monitorexit(unsigned bcI) { - assert(0 && "not implemented"); - } + void do_monitorexit(unsigned bcI) { + assert(0 && "not implemented"); + } - void do_multianewarray(unsigned bcI, - unsigned index, - unsigned dims) { - assert(0 && "not implemented"); - } - }; + void do_multianewarray(unsigned bcI, + unsigned index, + unsigned dims) { + assert(0 && "not implemented"); + } + }; } } } // namespace llvm::Java:: Compiler::Compiler() - : compilerImpl_(new CompilerImpl()) + : compilerImpl_(new CompilerImpl()) { } Compiler::~Compiler() { - delete compilerImpl_; + delete compilerImpl_; } void Compiler::compile(Module& m, const std::string& className) { - DEBUG(std::cerr << "Compiling class: " << className << '\n'); + DEBUG(std::cerr << "Compiling class: " << className << '\n'); - Function* main = - compilerImpl_->compileMethod(m, - className + "/main([Ljava/lang/String;)V"); - Function* javaMain = m.getOrInsertFunction - ("llvm_java_main", Type::VoidTy, - Type::IntTy, PointerType::get(PointerType::get(Type::SByteTy)), NULL); - - BasicBlock* bb = new BasicBlock("entry", javaMain); - const FunctionType* mainTy = main->getFunctionType(); - new CallInst(main, - // FIXME: Forward correct params from llvm_java_main - llvm::Constant::getNullValue(mainTy->getParamType(0)), - "", - bb); - new ReturnInst(NULL, bb); + Function* main = + compilerImpl_->compileMethod(m, + className + "/main([Ljava/lang/String;)V"); + Function* javaMain = m.getOrInsertFunction + ("llvm_java_main", Type::VoidTy, + Type::IntTy, PointerType::get(PointerType::get(Type::SByteTy)), NULL); + + BasicBlock* bb = new BasicBlock("entry", javaMain); + const FunctionType* mainTy = main->getFunctionType(); + new CallInst(main, + // FIXME: Forward correct params from llvm_java_main + llvm::Constant::getNullValue(mainTy->getParamType(0)), + "", + bb); + new ReturnInst(NULL, bb); } From alkis at cs.uiuc.edu Wed Aug 4 05:02:14 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:02:14 -0500 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/classdump.cpp Message-ID: <200408041002.FAA26642@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: classdump.cpp updated: 1.11 -> 1.12 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+12 -12) Index: llvm-java/tools/classdump/classdump.cpp diff -u llvm-java/tools/classdump/classdump.cpp:1.11 llvm-java/tools/classdump/classdump.cpp:1.12 --- llvm-java/tools/classdump/classdump.cpp:1.11 Thu Jul 8 12:42:34 2004 +++ llvm-java/tools/classdump/classdump.cpp Wed Aug 4 05:02:03 2004 @@ -26,19 +26,19 @@ int main(int argc, char* argv[]) { - PrintStackTraceOnErrorSignal(); - cl::ParseCommandLineOptions(argc, argv, - "class dump utility"); + PrintStackTraceOnErrorSignal(); + cl::ParseCommandLineOptions(argc, argv, + "class dump utility"); - try { - const Java::ClassFile* cf(Java::ClassFile::getClassFile(InputClass)); + try { + const Java::ClassFile* cf(Java::ClassFile::getClassFile(InputClass)); - cf->dump(std::cout); - } - catch (std::exception& e) { - std::cerr << e.what() << '\n'; - return EXIT_FAILURE; - } + cf->dump(std::cout); + } + catch (std::exception& e) { + std::cerr << e.what() << '\n'; + return EXIT_FAILURE; + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } From alkis at cs.uiuc.edu Wed Aug 4 05:02:14 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:02:14 -0500 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/Compiler.h ClassFile.h BytecodeParser.h Bytecode.h Message-ID: <200408041002.FAA26641@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: Compiler.h updated: 1.7 -> 1.8 ClassFile.h updated: 1.17 -> 1.18 BytecodeParser.h updated: 1.5 -> 1.6 Bytecode.h updated: 1.9 -> 1.10 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+1426 -1426) Index: llvm-java/include/llvm/Java/Compiler.h diff -u llvm-java/include/llvm/Java/Compiler.h:1.7 llvm-java/include/llvm/Java/Compiler.h:1.8 --- llvm-java/include/llvm/Java/Compiler.h:1.7 Thu Jul 8 19:06:30 2004 +++ llvm-java/include/llvm/Java/Compiler.h Wed Aug 4 05:02:03 2004 @@ -18,25 +18,25 @@ namespace llvm { namespace Java { - namespace { - class CompilerImpl; - } - - class Compiler { - public: - Compiler(); - ~Compiler(); - - void compile(Module& m, const std::string& className); - - private: - // do not implement - Compiler(const Compiler&); - const Compiler& operator=(const Compiler&); - - private: - CompilerImpl* compilerImpl_; - }; + namespace { + class CompilerImpl; + } + + class Compiler { + public: + Compiler(); + ~Compiler(); + + void compile(Module& m, const std::string& className); + + private: + // do not implement + Compiler(const Compiler&); + const Compiler& operator=(const Compiler&); + + private: + CompilerImpl* compilerImpl_; + }; } } // namespace llvm::Java Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.17 llvm-java/include/llvm/Java/ClassFile.h:1.18 --- llvm-java/include/llvm/Java/ClassFile.h:1.17 Sat Jul 24 15:33:23 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Wed Aug 4 05:02:03 2004 @@ -24,460 +24,460 @@ namespace llvm { namespace Java { - // Forward declarations - class Attribute; - class ConstantValueAttribute; - class CodeAttribute; - class ExceptionsAttribute; - class Constant; - class ConstantClass; - class ConstantNameAndType; - class ConstantUtf8; - class ClassFile; - class Field; - class Method; - - enum AccessFlag { - ACC_PUBLIC = 0x0001, - ACC_PRIVATE = 0x0002, - ACC_PROTECTED = 0x0004, - ACC_STATIC = 0x0008, - ACC_FINAL = 0x0010, - ACC_SUPER = 0x0020, - ACC_SYNCHRONIZED = 0x0020, - ACC_VOLATILE = 0x0040, - ACC_TRANSIENT = 0x0080, - ACC_NATIVE = 0x0100, - ACC_INTERFACE = 0x0200, - ACC_ABSTRACT = 0x0400, - ACC_STRICT = 0x0800, - }; - - typedef std::vector ConstantPool; - typedef std::vector Classes; - typedef std::vector Fields; - typedef std::vector Methods; - typedef std::vector Attributes; - - Attribute* getAttribute(const Attributes& attrs, - const std::string& name); - - class ClassFile { - static ClassFile* readClassFile(std::istream& is); - static std::vector getClassPath(); - static std::string getFileForClass(const std::string& classname); - - typedef std::map Name2MethodMap; - - public: - static ClassFile* getClassFile(const std::string& classname); - - ~ClassFile(); - - uint16_t getMinorVersion() const { return minorV_; } - uint16_t getMajorVersion() const { return majorV_; } - - const ConstantPool& getConstantPool() const { return cPool_; } - - bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } - bool isFinal() const { return accessFlags_ & ACC_FINAL; } - bool isSuper() const { return accessFlags_ & ACC_SUPER; } - bool isInterface() const { return accessFlags_ & ACC_INTERFACE; } - bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } - - ConstantClass* getThisClass() const { return thisClass_; } - ConstantClass* getSuperClass() const { return superClass_; } - - const Classes& getInterfaces() const { return interfaces_; } - - const Fields& getFields() const { return fields_; } - - const Methods& getMethods() const { return methods_; } - - const Attributes& getAttributes() const { return attributes_; } - - Method* getMethod(const std::string& nameAndDescr) const; - - std::ostream& dump(std::ostream& os) const; - - private: - uint16_t majorV_; - uint16_t minorV_; - ConstantPool cPool_; - uint16_t accessFlags_; - ConstantClass* thisClass_; - ConstantClass* superClass_; - Classes interfaces_; - Fields fields_; - Methods methods_; - Attributes attributes_; - Name2MethodMap n2mMap_; - - ClassFile(std::istream& is); - }; - - inline std::ostream& operator<<(std::ostream& os, const ClassFile& c) { - return c.dump(os); + // Forward declarations + class Attribute; + class ConstantValueAttribute; + class CodeAttribute; + class ExceptionsAttribute; + class Constant; + class ConstantClass; + class ConstantNameAndType; + class ConstantUtf8; + class ClassFile; + class Field; + class Method; + + enum AccessFlag { + ACC_PUBLIC = 0x0001, + ACC_PRIVATE = 0x0002, + ACC_PROTECTED = 0x0004, + ACC_STATIC = 0x0008, + ACC_FINAL = 0x0010, + ACC_SUPER = 0x0020, + ACC_SYNCHRONIZED = 0x0020, + ACC_VOLATILE = 0x0040, + ACC_TRANSIENT = 0x0080, + ACC_NATIVE = 0x0100, + ACC_INTERFACE = 0x0200, + ACC_ABSTRACT = 0x0400, + ACC_STRICT = 0x0800, + }; + + typedef std::vector ConstantPool; + typedef std::vector Classes; + typedef std::vector Fields; + typedef std::vector Methods; + typedef std::vector Attributes; + + Attribute* getAttribute(const Attributes& attrs, + const std::string& name); + + class ClassFile { + static ClassFile* readClassFile(std::istream& is); + static std::vector getClassPath(); + static std::string getFileForClass(const std::string& classname); + + typedef std::map Name2MethodMap; + + public: + static ClassFile* getClassFile(const std::string& classname); + + ~ClassFile(); + + uint16_t getMinorVersion() const { return minorV_; } + uint16_t getMajorVersion() const { return majorV_; } + + const ConstantPool& getConstantPool() const { return cPool_; } + + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isSuper() const { return accessFlags_ & ACC_SUPER; } + bool isInterface() const { return accessFlags_ & ACC_INTERFACE; } + bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } + + ConstantClass* getThisClass() const { return thisClass_; } + ConstantClass* getSuperClass() const { return superClass_; } + + const Classes& getInterfaces() const { return interfaces_; } + + const Fields& getFields() const { return fields_; } + + const Methods& getMethods() const { return methods_; } + + const Attributes& getAttributes() const { return attributes_; } + + Method* getMethod(const std::string& nameAndDescr) const; + + std::ostream& dump(std::ostream& os) const; + + private: + uint16_t majorV_; + uint16_t minorV_; + ConstantPool cPool_; + uint16_t accessFlags_; + ConstantClass* thisClass_; + ConstantClass* superClass_; + Classes interfaces_; + Fields fields_; + Methods methods_; + Attributes attributes_; + Name2MethodMap n2mMap_; + + ClassFile(std::istream& is); + }; + + inline std::ostream& operator<<(std::ostream& os, const ClassFile& c) { + return c.dump(os); + } + + class Constant { + protected: + const ConstantPool& cPool_; + + Constant(const ConstantPool& cp) + : cPool_(cp) { } + + public: + enum Tag { + CLASS = 7, + FIELD_REF = 9, + METHOD_REF = 10, + INTERFACE_METHOD_REF = 11, + STRING = 8, + INTEGER = 3, + FLOAT = 4, + LONG = 5, + DOUBLE = 6, + NAME_AND_TYPE = 12, + UTF8 = 1 + }; + + static Constant* readConstant(const ConstantPool& cp, + std::istream& is); + + virtual bool isSingleSlot() { return true; } + bool isDoubleSlot() { return !isSingleSlot(); } + virtual ~Constant(); + + virtual std::ostream& dump(std::ostream& os) const = 0; + }; + + inline std::ostream& operator<<(std::ostream& os, const Constant& c) { + return c.dump(os); + } + + class ConstantClass : public Constant { + uint16_t nameIdx_; + public: + ConstantClass(const ConstantPool& cp, std::istream& is); + ConstantUtf8* getName() const { + return (ConstantUtf8*) cPool_[nameIdx_]; } + std::ostream& dump(std::ostream& os) const; + }; - class Constant { - protected: - const ConstantPool& cPool_; - - Constant(const ConstantPool& cp) - : cPool_(cp) { } - - public: - enum Tag { - CLASS = 7, - FIELD_REF = 9, - METHOD_REF = 10, - INTERFACE_METHOD_REF = 11, - STRING = 8, - INTEGER = 3, - FLOAT = 4, - LONG = 5, - DOUBLE = 6, - NAME_AND_TYPE = 12, - UTF8 = 1 - }; - - static Constant* readConstant(const ConstantPool& cp, - std::istream& is); - - virtual bool isSingleSlot() { return true; } - bool isDoubleSlot() { return !isSingleSlot(); } - virtual ~Constant(); - - virtual std::ostream& dump(std::ostream& os) const = 0; - }; - - inline std::ostream& operator<<(std::ostream& os, const Constant& c) { - return c.dump(os); + class ConstantMemberRef : public Constant { + uint16_t classIdx_; + uint16_t nameAndTypeIdx_; + protected: + ConstantMemberRef(const ConstantPool& cp, std::istream& is); + + public: + ConstantClass* getClass() const { + return (ConstantClass*) cPool_[classIdx_]; } - - class ConstantClass : public Constant { - uint16_t nameIdx_; - public: - ConstantClass(const ConstantPool& cp, std::istream& is); - ConstantUtf8* getName() const { - return (ConstantUtf8*) cPool_[nameIdx_]; - } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantMemberRef : public Constant { - uint16_t classIdx_; - uint16_t nameAndTypeIdx_; - protected: - ConstantMemberRef(const ConstantPool& cp, std::istream& is); - - public: - ConstantClass* getClass() const { - return (ConstantClass*) cPool_[classIdx_]; - } - ConstantNameAndType* getNameAndType() const { - return (ConstantNameAndType*) cPool_[nameAndTypeIdx_]; - } - std::ostream& dump(std::ostream& os) const; - }; - - struct ConstantFieldRef : public ConstantMemberRef { - ConstantFieldRef(const ConstantPool& cp, std::istream& is) - : ConstantMemberRef(cp, is) { } - }; - - struct ConstantMethodRef : public ConstantMemberRef { - ConstantMethodRef(const ConstantPool& cp, std::istream& is) - : ConstantMemberRef(cp, is) { } - }; - - struct ConstantInterfaceMethodRef : public ConstantMemberRef { - ConstantInterfaceMethodRef(const ConstantPool& cp, std::istream& is) - : ConstantMemberRef(cp, is) { } - }; - - class ConstantString : public Constant { - uint16_t stringIdx_; - public: - ConstantString(const ConstantPool& cp, std::istream& is); - ConstantUtf8* getValue() const { - return (ConstantUtf8*) cPool_[stringIdx_]; - } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantInteger : public Constant { - int32_t value_; - public: - ConstantInteger(const ConstantPool& cp, std::istream& is); - int32_t getValue() const { return value_; } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantFloat : public Constant { - float value_; - public: - ConstantFloat(const ConstantPool& cp, std::istream& is); - float getValue() const { return value_; } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantLong : public Constant { - int64_t value_; - public: - ConstantLong(const ConstantPool& cp, std::istream& is); - virtual bool isSingleSlot() { return false; } - int64_t getValue() const { return value_; } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantDouble : public Constant { - double value_; - public: - ConstantDouble(const ConstantPool& cp, std::istream& is); - virtual bool isSingleSlot() { return false; } - double getValue() const { return value_; } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantNameAndType : public Constant { - uint16_t nameIdx_; - uint16_t descriptorIdx_; - public: - ConstantNameAndType(const ConstantPool& cp, std::istream& is); - ConstantUtf8* getName() const { - return (ConstantUtf8*) cPool_[nameIdx_]; - } - ConstantUtf8* getDescriptor() const { - return (ConstantUtf8*) cPool_[descriptorIdx_]; - } - std::ostream& dump(std::ostream& os) const; - }; - - class ConstantUtf8 : public Constant { - std::string utf8_; - public: - ConstantUtf8(const ConstantPool& cp, std::istream& is); - const std::string& str() const { return utf8_; } - - std::ostream& dump(std::ostream& os) const; - }; - - class Field { - private: - uint16_t accessFlags_; - ConstantUtf8* name_; - ConstantUtf8* descriptor_; - Attributes attributes_; - - Field(const ConstantPool& cp, std::istream& is); - - public: - static Field* readField(const ConstantPool& cp, std::istream& is) { - return new Field(cp, is); - } - - ~Field(); - - bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } - bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } - bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } - bool isStatic() const { return accessFlags_ & ACC_STATIC; } - bool isFinal() const { return accessFlags_ & ACC_FINAL; } - bool isVolatile() const { return accessFlags_ & ACC_VOLATILE; } - bool isTransient() const { return accessFlags_ & ACC_TRANSIENT; } - - ConstantUtf8* getName() const { return name_; } - ConstantUtf8* getDescriptor() const { return descriptor_; } - const Attributes& getAttributes() const { return attributes_; } - ConstantValueAttribute* getConstantValueAttribute() const; - - std::ostream& dump(std::ostream& os) const; - }; - - inline std::ostream& operator<<(std::ostream& os, const Field& f) { - return f.dump(os); + ConstantNameAndType* getNameAndType() const { + return (ConstantNameAndType*) cPool_[nameAndTypeIdx_]; } + std::ostream& dump(std::ostream& os) const; + }; - class Method { - uint16_t accessFlags_; - ConstantUtf8* name_; - ConstantUtf8* descriptor_; - Attributes attributes_; - - Method(const ConstantPool& cp, std::istream& is); - - public: - static Method* readMethod(const ConstantPool& cp, std::istream& is) { - return new Method(cp, is); - } - - ~Method(); - - bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } - bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } - bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } - bool isStatic() const { return accessFlags_ & ACC_STATIC; } - bool isFinal() const { return accessFlags_ & ACC_FINAL; } - bool isSynchronized() const { return accessFlags_ & ACC_SYNCHRONIZED; } - bool isNative() const { return accessFlags_ & ACC_NATIVE; } - bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } - bool isStrict() const { return accessFlags_ & ACC_STRICT; } - - ConstantUtf8* getName() const { return name_; } - ConstantUtf8* getDescriptor() const { return descriptor_; } - const Attributes& getAttributes() const { return attributes_; } - CodeAttribute* getCodeAttribute() const; - ExceptionsAttribute* getExceptionsAttribute() const; - - std::ostream& dump(std::ostream& os) const; - }; - - inline std::ostream& operator<<(std::ostream& os, const Method& m) { - return m.dump(os); + struct ConstantFieldRef : public ConstantMemberRef { + ConstantFieldRef(const ConstantPool& cp, std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + struct ConstantMethodRef : public ConstantMemberRef { + ConstantMethodRef(const ConstantPool& cp, std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + struct ConstantInterfaceMethodRef : public ConstantMemberRef { + ConstantInterfaceMethodRef(const ConstantPool& cp, std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + class ConstantString : public Constant { + uint16_t stringIdx_; + public: + ConstantString(const ConstantPool& cp, std::istream& is); + ConstantUtf8* getValue() const { + return (ConstantUtf8*) cPool_[stringIdx_]; } + std::ostream& dump(std::ostream& os) const; + }; - class Attribute { - ConstantUtf8* name_; - - protected: - Attribute(ConstantUtf8* name, - const ConstantPool& cp, - std::istream& is); - - public: - static Attribute* readAttribute(const ConstantPool& cp, - std::istream& is); - - virtual ~Attribute(); - - ConstantUtf8* getName() const { return name_; } - - virtual std::ostream& dump(std::ostream& os) const; - - static const std::string CONSTANT_VALUE; - static const std::string CODE; - static const std::string EXCEPTIONS; - static const std::string INNER_CLASSES; - static const std::string SYNTHETIC; - static const std::string SOURCE_FILE; - static const std::string LINE_NUMBER_TABLE; - static const std::string LOCAL_VARIABLE_TABLE; - static const std::string DEPRECATED; - }; - - inline std::ostream& operator<<(std::ostream& os, const Attribute& a) { - return a.dump(os); + class ConstantInteger : public Constant { + int32_t value_; + public: + ConstantInteger(const ConstantPool& cp, std::istream& is); + int32_t getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; + }; + + class ConstantFloat : public Constant { + float value_; + public: + ConstantFloat(const ConstantPool& cp, std::istream& is); + float getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; + }; + + class ConstantLong : public Constant { + int64_t value_; + public: + ConstantLong(const ConstantPool& cp, std::istream& is); + virtual bool isSingleSlot() { return false; } + int64_t getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; + }; + + class ConstantDouble : public Constant { + double value_; + public: + ConstantDouble(const ConstantPool& cp, std::istream& is); + virtual bool isSingleSlot() { return false; } + double getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; + }; + + class ConstantNameAndType : public Constant { + uint16_t nameIdx_; + uint16_t descriptorIdx_; + public: + ConstantNameAndType(const ConstantPool& cp, std::istream& is); + ConstantUtf8* getName() const { + return (ConstantUtf8*) cPool_[nameIdx_]; } - - class ConstantValueAttribute : public Attribute { - Constant* value_; - public: - ConstantValueAttribute(ConstantUtf8* name, - const ConstantPool& cp, - std::istream& is); - - Constant* getValue() const { return value_; } - - std::ostream& dump(std::ostream& os) const; - }; - - class CodeAttribute : public Attribute { - public: - class Exception { - uint16_t startPc_; - uint16_t endPc_; - uint16_t handlerPc_; - ConstantClass* catchType_; - - public: - Exception(const ConstantPool& cp, std::istream& is); - - uint16_t getStartPc() const { return startPc_; } - uint16_t getEndPc() const { return endPc_; } - uint16_t getHandlerPc() const { return handlerPc_; } - ConstantClass* getCatchType() const { return catchType_; } - - std::ostream& dump(std::ostream& os) const; - }; - - typedef std::vector Exceptions; - - private: - uint16_t maxStack_; - uint16_t maxLocals_; - uint32_t codeSize_; - uint8_t* code_; - Exceptions exceptions_; - Attributes attributes_; - - public: - CodeAttribute(ConstantUtf8* name, - const ConstantPool& cp, - std::istream& is); - ~CodeAttribute(); - uint16_t getMaxStack() const { return maxStack_; } - uint16_t getMaxLocals() const { return maxLocals_; } - const uint8_t* getCode() const { return code_; } - uint32_t getCodeSize() const { return codeSize_; } - const Exceptions& getExceptions() const { return exceptions_; } - const Attributes& getAttributes() const { return attributes_; } - - std::ostream& dump(std::ostream& os) const; - }; - - inline std::ostream& operator<<(std::ostream& os, - const CodeAttribute::Exception& e) { - return e.dump(os); + ConstantUtf8* getDescriptor() const { + return (ConstantUtf8*) cPool_[descriptorIdx_]; } + std::ostream& dump(std::ostream& os) const; + }; - class ExceptionsAttribute : public Attribute { - private: - ConstantUtf8* name_; - Classes exceptions_; - - public: - ExceptionsAttribute(ConstantUtf8* name, - const ConstantPool& cp, - std::istream& is); - - const Classes& getExceptions() const { return exceptions_; } + class ConstantUtf8 : public Constant { + std::string utf8_; + public: + ConstantUtf8(const ConstantPool& cp, std::istream& is); + const std::string& str() const { return utf8_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class Field { + private: + uint16_t accessFlags_; + ConstantUtf8* name_; + ConstantUtf8* descriptor_; + Attributes attributes_; + + Field(const ConstantPool& cp, std::istream& is); + + public: + static Field* readField(const ConstantPool& cp, std::istream& is) { + return new Field(cp, is); + } - std::ostream& dump(std::ostream& os) const; - }; + ~Field(); - class ClassFileParseError : public std::exception { - std::string msg_; - public: - explicit ClassFileParseError(const std::string& msg) : msg_(msg) { } - virtual ~ClassFileParseError() throw(); - virtual const char* what() const throw() { return msg_.c_str(); } - }; + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } + bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } + bool isStatic() const { return accessFlags_ & ACC_STATIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isVolatile() const { return accessFlags_ & ACC_VOLATILE; } + bool isTransient() const { return accessFlags_ & ACC_TRANSIENT; } + + ConstantUtf8* getName() const { return name_; } + ConstantUtf8* getDescriptor() const { return descriptor_; } + const Attributes& getAttributes() const { return attributes_; } + ConstantValueAttribute* getConstantValueAttribute() const; + + std::ostream& dump(std::ostream& os) const; + }; + + inline std::ostream& operator<<(std::ostream& os, const Field& f) { + return f.dump(os); + } + + class Method { + uint16_t accessFlags_; + ConstantUtf8* name_; + ConstantUtf8* descriptor_; + Attributes attributes_; + + Method(const ConstantPool& cp, std::istream& is); + + public: + static Method* readMethod(const ConstantPool& cp, std::istream& is) { + return new Method(cp, is); + } - class ClassFileSemanticError : public std::exception { - std::string msg_; - public: - explicit ClassFileSemanticError(const std::string& msg) : msg_(msg) { } - virtual ~ClassFileSemanticError() throw(); - virtual const char* what() const throw() { return msg_.c_str(); } - }; + ~Method(); - class ClassNotFoundException : public std::exception { - std::string msg_; - public: - explicit ClassNotFoundException(const std::string& msg) : msg_(msg) { } - virtual ~ClassNotFoundException() throw(); - virtual const char* what() const throw() { return msg_.c_str(); } - }; + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } + bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } + bool isStatic() const { return accessFlags_ & ACC_STATIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isSynchronized() const { return accessFlags_ & ACC_SYNCHRONIZED; } + bool isNative() const { return accessFlags_ & ACC_NATIVE; } + bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } + bool isStrict() const { return accessFlags_ & ACC_STRICT; } + + ConstantUtf8* getName() const { return name_; } + ConstantUtf8* getDescriptor() const { return descriptor_; } + const Attributes& getAttributes() const { return attributes_; } + CodeAttribute* getCodeAttribute() const; + ExceptionsAttribute* getExceptionsAttribute() const; + + std::ostream& dump(std::ostream& os) const; + }; + + inline std::ostream& operator<<(std::ostream& os, const Method& m) { + return m.dump(os); + } + + class Attribute { + ConstantUtf8* name_; + + protected: + Attribute(ConstantUtf8* name, + const ConstantPool& cp, + std::istream& is); + + public: + static Attribute* readAttribute(const ConstantPool& cp, + std::istream& is); + + virtual ~Attribute(); + + ConstantUtf8* getName() const { return name_; } + + virtual std::ostream& dump(std::ostream& os) const; + + static const std::string CONSTANT_VALUE; + static const std::string CODE; + static const std::string EXCEPTIONS; + static const std::string INNER_CLASSES; + static const std::string SYNTHETIC; + static const std::string SOURCE_FILE; + static const std::string LINE_NUMBER_TABLE; + static const std::string LOCAL_VARIABLE_TABLE; + static const std::string DEPRECATED; + }; + + inline std::ostream& operator<<(std::ostream& os, const Attribute& a) { + return a.dump(os); + } + + class ConstantValueAttribute : public Attribute { + Constant* value_; + public: + ConstantValueAttribute(ConstantUtf8* name, + const ConstantPool& cp, + std::istream& is); + + Constant* getValue() const { return value_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class CodeAttribute : public Attribute { + public: + class Exception { + uint16_t startPc_; + uint16_t endPc_; + uint16_t handlerPc_; + ConstantClass* catchType_; + + public: + Exception(const ConstantPool& cp, std::istream& is); + + uint16_t getStartPc() const { return startPc_; } + uint16_t getEndPc() const { return endPc_; } + uint16_t getHandlerPc() const { return handlerPc_; } + ConstantClass* getCatchType() const { return catchType_; } + + std::ostream& dump(std::ostream& os) const; + }; + + typedef std::vector Exceptions; + + private: + uint16_t maxStack_; + uint16_t maxLocals_; + uint32_t codeSize_; + uint8_t* code_; + Exceptions exceptions_; + Attributes attributes_; - class InvocationTargetException : public std::exception { - std::string msg_; - public: - explicit InvocationTargetException(const std::string& msg) : msg_(msg) { } - virtual ~InvocationTargetException() throw(); - virtual const char* what() const throw() { return msg_.c_str(); } - }; + public: + CodeAttribute(ConstantUtf8* name, + const ConstantPool& cp, + std::istream& is); + ~CodeAttribute(); + uint16_t getMaxStack() const { return maxStack_; } + uint16_t getMaxLocals() const { return maxLocals_; } + const uint8_t* getCode() const { return code_; } + uint32_t getCodeSize() const { return codeSize_; } + const Exceptions& getExceptions() const { return exceptions_; } + const Attributes& getAttributes() const { return attributes_; } + + std::ostream& dump(std::ostream& os) const; + }; + + inline std::ostream& operator<<(std::ostream& os, + const CodeAttribute::Exception& e) { + return e.dump(os); + } + + class ExceptionsAttribute : public Attribute { + private: + ConstantUtf8* name_; + Classes exceptions_; + + public: + ExceptionsAttribute(ConstantUtf8* name, + const ConstantPool& cp, + std::istream& is); + + const Classes& getExceptions() const { return exceptions_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class ClassFileParseError : public std::exception { + std::string msg_; + public: + explicit ClassFileParseError(const std::string& msg) : msg_(msg) { } + virtual ~ClassFileParseError() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; + + class ClassFileSemanticError : public std::exception { + std::string msg_; + public: + explicit ClassFileSemanticError(const std::string& msg) : msg_(msg) { } + virtual ~ClassFileSemanticError() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; + + class ClassNotFoundException : public std::exception { + std::string msg_; + public: + explicit ClassNotFoundException(const std::string& msg) : msg_(msg) { } + virtual ~ClassNotFoundException() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; + + class InvocationTargetException : public std::exception { + std::string msg_; + public: + explicit InvocationTargetException(const std::string& msg) : msg_(msg) { } + virtual ~InvocationTargetException() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; } } // namespace llvm::Java Index: llvm-java/include/llvm/Java/BytecodeParser.h diff -u llvm-java/include/llvm/Java/BytecodeParser.h:1.5 llvm-java/include/llvm/Java/BytecodeParser.h:1.6 --- llvm-java/include/llvm/Java/BytecodeParser.h:1.5 Thu May 27 15:51:38 2004 +++ llvm-java/include/llvm/Java/BytecodeParser.h Wed Aug 4 05:02:03 2004 @@ -19,745 +19,745 @@ namespace llvm { namespace Java { - /// @brief This class provides a base class that eases bytecode - /// parsing. - /// - /// By default all the do_* methods do nothing. A subclass can - /// override at will to provide specific behaviour. - template - class BytecodeParser { - protected: - typedef std::vector > SwitchCases; + /// @brief This class provides a base class that eases bytecode + /// parsing. + /// + /// By default all the do_* methods do nothing. A subclass can + /// override at will to provide specific behaviour. + template + class BytecodeParser { + protected: + typedef std::vector > SwitchCases; - enum JSetCC { EQ, NE, LT, GE, GT, LE }; + enum JSetCC { EQ, NE, LT, GE, GT, LE }; - enum JType { - REFERENCE = 0, // this is not defined in the java spec - BOOLEAN = 4, - CHAR = 5, - FLOAT = 6, - DOUBLE = 7, - BYTE = 8, - SHORT = 9, - INT = 10, - LONG = 11, - }; + enum JType { + REFERENCE = 0, // this is not defined in the java spec + BOOLEAN = 4, + CHAR = 5, + FLOAT = 6, + DOUBLE = 7, + BYTE = 8, + SHORT = 9, + INT = 10, + LONG = 11, + }; - private: - SwitchCases switchCases_; + private: + SwitchCases switchCases_; - protected: + protected: #define THIS ((SubClass*)this) - /// @brief parse code pointed to by \c code of size \c size - /// - /// This function parses the code pointed to by \c code and - /// calls the subclass's do_ method - /// appropriately. When this function returns all code up to - /// \c size is parsed. - void parse(const uint8_t* code, unsigned size) { - using namespace Opcode; + /// @brief parse code pointed to by \c code of size \c size + /// + /// This function parses the code pointed to by \c code and + /// calls the subclass's do_ method + /// appropriately. When this function returns all code up to + /// \c size is parsed. + void parse(const uint8_t* code, unsigned size) { + using namespace Opcode; - for (unsigned i = 0; i < size; ++i) { - unsigned curBC = i; - bool wide = code[i] == WIDE; - i += wide; - switch (code[i]) { - case ACONST_NULL: - THIS->do_aconst_null(curBC); - break; - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - THIS->do_iconst(curBC, code[i]-ICONST_0); - break; - case LCONST_0: - case LCONST_1: - THIS->do_lconst(curBC, code[i]-LCONST_0); - break; - case FCONST_0: - case FCONST_1: - case FCONST_2: - THIS->do_fconst(curBC, code[i]-FCONST_0); - break; - case DCONST_0: - case DCONST_1: - THIS->do_dconst(curBC, code[i]-DCONST_0); - break; - case BIPUSH: - THIS->do_iconst(curBC, readSByte(code, i)); - break; - case SIPUSH: - THIS->do_iconst(curBC, readSShort(code, i)); - break; - case LDC: - THIS->do_ldc(curBC, readUByte(code, i)); - break; - case LDC_W: - THIS->do_ldc(curBC, readUShort(code, i)); - break; - case LDC2_W: - THIS->do_ldc(curBC, readUShort(code, i)); - break; - case ILOAD: - THIS->do_load( - curBC, INT, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case LLOAD: - THIS->do_load( - curBC, LONG, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case FLOAD: - THIS->do_load( - curBC, FLOAT, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case DLOAD: - THIS->do_load( - curBC, DOUBLE, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case ALOAD: - THIS->do_load( - curBC, REFERENCE, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case ILOAD_0: - case ILOAD_1: - case ILOAD_2: - case ILOAD_3: - THIS->do_load(curBC, INT, code[i]-ILOAD_0); - break; - case LLOAD_0: - case LLOAD_1: - case LLOAD_2: - case LLOAD_3: - THIS->do_load(curBC, LONG, code[i]-LLOAD_0); - break; - case FLOAD_0: - case FLOAD_1: - case FLOAD_2: - case FLOAD_3: - THIS->do_load(curBC, FLOAT, code[i]-FLOAD_0); - break; - case DLOAD_0: - case DLOAD_1: - case DLOAD_2: - case DLOAD_3: - THIS->do_load(curBC, DOUBLE, code[i]-DLOAD_0); - break; - case ALOAD_0: - case ALOAD_1: - case ALOAD_2: - case ALOAD_3: - THIS->do_load(curBC, REFERENCE, code[i]-ALOAD_0); - break; - case IALOAD: - THIS->do_aload(curBC, INT); - break; - case LALOAD: - THIS->do_aload(curBC, LONG); - break; - case FALOAD: - THIS->do_aload(curBC, FLOAT); - break; - case DALOAD: - THIS->do_aload(curBC, DOUBLE); - break; - case AALOAD: - THIS->do_aload(curBC, REFERENCE); - break; - case BALOAD: - THIS->do_aload(curBC, BYTE); - break; - case CALOAD: - THIS->do_aload(curBC, CHAR); - break; - case SALOAD: - THIS->do_aload(curBC, SHORT); - break; - case ISTORE: - THIS->do_store( - curBC, INT, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case LSTORE: - THIS->do_store( - curBC, LONG, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case FSTORE: - THIS->do_store( - curBC, FLOAT, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case DSTORE: - THIS->do_store( - curBC, DOUBLE, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case ASTORE: - THIS->do_store( - curBC, REFERENCE, - wide ? readUShort(code, i) : readUByte(code, i)); - break; - case ISTORE_0: - case ISTORE_1: - case ISTORE_2: - case ISTORE_3: - THIS->do_store(curBC, INT, code[i]-ISTORE_0); - break; - case LSTORE_0: - case LSTORE_1: - case LSTORE_2: - case LSTORE_3: - THIS->do_store(curBC, LONG, code[i]-LSTORE_0); - break; - case FSTORE_0: - case FSTORE_1: - case FSTORE_2: - case FSTORE_3: - THIS->do_store(curBC, FLOAT, code[i]-FSTORE_0); - break; - case DSTORE_0: - case DSTORE_1: - case DSTORE_2: - case DSTORE_3: - THIS->do_store(curBC, DOUBLE, code[i]-DSTORE_0); - break; - case ASTORE_0: - case ASTORE_1: - case ASTORE_2: - case ASTORE_3: - THIS->do_store(curBC, REFERENCE, code[i]-ASTORE_0); - break; - case IASTORE: - THIS->do_astore(curBC, INT); - break; - case LASTORE: - THIS->do_astore(curBC, LONG); - break; - case FASTORE: - THIS->do_astore(curBC, FLOAT); - break; - case DASTORE: - THIS->do_astore(curBC, DOUBLE); - break; - case AASTORE: - THIS->do_astore(curBC, REFERENCE); - break; - case BASTORE: - THIS->do_astore(curBC, BYTE); - break; - case CASTORE: - THIS->do_astore(curBC, CHAR); - break; - case SASTORE: - THIS->do_astore(curBC, SHORT); - break; - case POP: - THIS->do_pop(curBC); - break; - case POP2: - THIS->do_pop2(curBC); - break; - case DUP: - THIS->do_dup(curBC); - break; - case DUP_X1: - THIS->do_dup_x1(curBC); - break; - case DUP_X2: - THIS->do_dup_x2(curBC); - break; - case DUP2: - THIS->do_dup2(curBC); - break; - case DUP2_X1: - THIS->do_dup2_x1(curBC); - break; - case DUP2_X2: - THIS->do_dup2_x2(curBC); - break; - case SWAP: - THIS->do_swap(curBC); - break; - case IADD: - case LADD: - case FADD: - case DADD: - THIS->do_add(curBC); - break; - case ISUB: - case LSUB: - case FSUB: - case DSUB: - THIS->do_sub(curBC); - break; - case IMUL: - case LMUL: - case FMUL: - case DMUL: - THIS->do_mul(curBC); - break; - case IDIV: - case LDIV: - case FDIV: - case DDIV: - THIS->do_div(curBC); - break; - case IREM: - case LREM: - case FREM: - case DREM: - THIS->do_rem(curBC); - break; - case INEG: - case LNEG: - case FNEG: - case DNEG: - THIS->do_neg(curBC); - break; - case ISHL: - case LSHL: - THIS->do_shl(curBC); - break; - case ISHR: - case LSHR: - THIS->do_shr(curBC); - break; - case IUSHR: - case LUSHR: - THIS->do_ushr(curBC); - break; - case IAND: - case LAND: - THIS->do_and(curBC); - break; - case IOR: - case LOR: - THIS->do_or(curBC); - break; - case IXOR: - case LXOR: - THIS->do_xor(curBC); - break; - case IINC: - THIS->do_iinc( - curBC, readUByte(code, i), readSByte(code, i)); - break; - case I2L: - THIS->do_convert(curBC, LONG); - break; - case I2F: - THIS->do_convert(curBC, FLOAT); - break; - case I2D: - THIS->do_convert(curBC, DOUBLE); - break; - case L2I: - THIS->do_convert(curBC, INT); - break; - case L2F: - THIS->do_convert(curBC, FLOAT); - break; - case L2D: - THIS->do_convert(curBC, DOUBLE); - break; - case F2I: - THIS->do_convert(curBC, INT); - break; - case F2L: - THIS->do_convert(curBC, LONG); - break; - case F2D: - THIS->do_convert(curBC, DOUBLE); - break; - case D2I: - THIS->do_convert(curBC, INT); - break; - case D2L: - THIS->do_convert(curBC, LONG); - break; - case D2F: - THIS->do_convert(curBC, FLOAT); - break; - case I2B: - THIS->do_convert(curBC, BYTE); - break; - case I2C: - THIS->do_convert(curBC, CHAR); - break; - case I2S: - THIS->do_convert(curBC, SHORT); - break; - case LCMP: - THIS->do_lcmp(curBC); - break; - case FCMPL: - THIS->do_cmpl(curBC); - break; - case FCMPG: - THIS->do_cmpg(curBC); - break; - case DCMPL: - THIS->do_cmpl(curBC); - break; - case DCMPG: - THIS->do_cmpg(curBC); - break; - case IFEQ: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, EQ, INT, t, i + 1); - break; - } - case IFNE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, NE, INT, t, i + 1); - break; - } - case IFLT: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, LT, INT, t, i + 1); - break; - } - case IFGE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, GE, INT, t, i + 1); - break; - } - case IFGT: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, GT, INT, t, i + 1); - break; - } - case IFLE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_if(curBC, LE, INT, t, i + 1); - break; - } - case IF_ICMPEQ: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, EQ, t, i + 1); - break; - } - case IF_ICMPNE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, NE, t, i + 1); - break; - } - case IF_ICMPLT: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, LT, t, i + 1); - break; - } - case IF_ICMPGE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, GE, t, i + 1); - break; - } - case IF_ICMPGT: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, GT, t, i + 1); - break; - } - case IF_ICMPLE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, LE, t, i + 1); - break; - } - case IF_IACMPEQ: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, EQ, t, i + 1); - break; - } - case IF_IACMPNE: { - unsigned t = curBC + readSShort(code, i); - THIS->do_ifcmp(curBC, NE, t, i + 1); - break; - } - case GOTO: - THIS->do_goto(curBC, curBC + readSShort(code, i)); - break; - case JSR: - THIS->do_jsr(curBC, curBC + readSShort(code, i)); - break; - case RET: - THIS->do_ret(curBC, readUByte(code, i)); - break; - case TABLESWITCH: { - switchCases_.clear(); - skipPadBytes(i); - int def = readSInt(code, i); - int low = readSInt(code, i); - int high = readSInt(code, i); - switchCases_.reserve(high - low + 1); - while (low <= high) - switchCases_.push_back( - std::make_pair(low++, curBC + readSInt(code, i))); - THIS->do_switch(curBC, curBC + def, switchCases_); - break; - } - case LOOKUPSWITCH: { - switchCases_.clear(); - skipPadBytes(i); - int def = readSInt(code, i); - int pairCount = readSInt(code, i); - switchCases_.reserve(pairCount); - while (pairCount--) { - int value = readSInt(code, i); - switchCases_.push_back( - std::make_pair(value, curBC + readSInt(code, i))); - } - THIS->do_switch(curBC, curBC + def, switchCases_); - break; - } - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - THIS->do_return(curBC); - break; - case RETURN: - THIS->do_return_void(curBC); - break; - case GETSTATIC: - THIS->do_getstatic(curBC, readUShort(code, i)); - break; - case PUTSTATIC: - THIS->do_putstatic(curBC, readUShort(code, i)); - break; - case GETFIELD: - THIS->do_getfield(curBC, readUShort(code, i)); - break; - case PUTFIELD: - THIS->do_putfield(curBC, readUShort(code, i)); - break; - case INVOKEVIRTUAL: - THIS->do_invokevirtual(curBC, readUShort(code, i)); - break; - case INVOKESPECIAL: - THIS->do_invokespecial(curBC, readUShort(code, i)); - break; - case INVOKESTATIC: - THIS->do_invokestatic(curBC, readUShort(code, i)); - break; - case INVOKEINTERFACE: { - THIS->do_invokeinterface(curBC, readUShort(code, i)); - unsigned count = readUByte(code, i); - unsigned zero = readUByte(code, i); - break; - } - case XXXUNUSEDXXX: - // FIXME: must throw something - break; - case NEW: - THIS->do_new(curBC, readUShort(code, i)); - break; - case NEWARRAY: - THIS->do_newarray(curBC, - static_cast(readUByte(code, i))); - break; - case ANEWARRAY: - THIS->do_anewarray(curBC, readUShort(code, i)); - break; - case ARRAYLENGTH: - THIS->do_arraylength(curBC); - break; - case ATHROW: - THIS->do_athrow(curBC); - break; - case CHECKCAST: - THIS->do_checkcast(curBC, readUShort(code, i)); - break; - case INSTANCEOF: - THIS->do_instanceof(curBC, readUShort(code, i)); - break; - case MONITORENTER: - THIS->do_monitorenter(curBC); - break; - case MONITOREXIT: - THIS->do_monitorexit(curBC); - break; - case WIDE: - // FIXME: must throw something - break; - case MULTIANEWARRAY: - THIS->do_multianewarray( - curBC, readUShort(code, i), readUByte(code, i)); - break; - case IFNULL: { - unsigned t = curBC + readUShort(code, i); - THIS->do_if(curBC, EQ, REFERENCE, t, i + 1); - break; - } - case IFNONNULL: { - unsigned t = curBC + readUShort(code, i); - THIS->do_if(curBC, NE, REFERENCE, t, i + 1); - break; - } - case GOTO_W: - THIS->do_goto(curBC, curBC + readSInt(code, i)); - break; - case JSR_W: - THIS->do_jsr(curBC, curBC + readSInt(code, i)); - break; - case BREAKPOINT: - case IMPDEP1: - case IMPDEP2: - case NOP: - break; - } - } + for (unsigned i = 0; i < size; ++i) { + unsigned curBC = i; + bool wide = code[i] == WIDE; + i += wide; + switch (code[i]) { + case ACONST_NULL: + THIS->do_aconst_null(curBC); + break; + case ICONST_M1: + case ICONST_0: + case ICONST_1: + case ICONST_2: + case ICONST_3: + case ICONST_4: + case ICONST_5: + THIS->do_iconst(curBC, code[i]-ICONST_0); + break; + case LCONST_0: + case LCONST_1: + THIS->do_lconst(curBC, code[i]-LCONST_0); + break; + case FCONST_0: + case FCONST_1: + case FCONST_2: + THIS->do_fconst(curBC, code[i]-FCONST_0); + break; + case DCONST_0: + case DCONST_1: + THIS->do_dconst(curBC, code[i]-DCONST_0); + break; + case BIPUSH: + THIS->do_iconst(curBC, readSByte(code, i)); + break; + case SIPUSH: + THIS->do_iconst(curBC, readSShort(code, i)); + break; + case LDC: + THIS->do_ldc(curBC, readUByte(code, i)); + break; + case LDC_W: + THIS->do_ldc(curBC, readUShort(code, i)); + break; + case LDC2_W: + THIS->do_ldc(curBC, readUShort(code, i)); + break; + case ILOAD: + THIS->do_load( + curBC, INT, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case LLOAD: + THIS->do_load( + curBC, LONG, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case FLOAD: + THIS->do_load( + curBC, FLOAT, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case DLOAD: + THIS->do_load( + curBC, DOUBLE, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case ALOAD: + THIS->do_load( + curBC, REFERENCE, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case ILOAD_0: + case ILOAD_1: + case ILOAD_2: + case ILOAD_3: + THIS->do_load(curBC, INT, code[i]-ILOAD_0); + break; + case LLOAD_0: + case LLOAD_1: + case LLOAD_2: + case LLOAD_3: + THIS->do_load(curBC, LONG, code[i]-LLOAD_0); + break; + case FLOAD_0: + case FLOAD_1: + case FLOAD_2: + case FLOAD_3: + THIS->do_load(curBC, FLOAT, code[i]-FLOAD_0); + break; + case DLOAD_0: + case DLOAD_1: + case DLOAD_2: + case DLOAD_3: + THIS->do_load(curBC, DOUBLE, code[i]-DLOAD_0); + break; + case ALOAD_0: + case ALOAD_1: + case ALOAD_2: + case ALOAD_3: + THIS->do_load(curBC, REFERENCE, code[i]-ALOAD_0); + break; + case IALOAD: + THIS->do_aload(curBC, INT); + break; + case LALOAD: + THIS->do_aload(curBC, LONG); + break; + case FALOAD: + THIS->do_aload(curBC, FLOAT); + break; + case DALOAD: + THIS->do_aload(curBC, DOUBLE); + break; + case AALOAD: + THIS->do_aload(curBC, REFERENCE); + break; + case BALOAD: + THIS->do_aload(curBC, BYTE); + break; + case CALOAD: + THIS->do_aload(curBC, CHAR); + break; + case SALOAD: + THIS->do_aload(curBC, SHORT); + break; + case ISTORE: + THIS->do_store( + curBC, INT, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case LSTORE: + THIS->do_store( + curBC, LONG, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case FSTORE: + THIS->do_store( + curBC, FLOAT, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case DSTORE: + THIS->do_store( + curBC, DOUBLE, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case ASTORE: + THIS->do_store( + curBC, REFERENCE, + wide ? readUShort(code, i) : readUByte(code, i)); + break; + case ISTORE_0: + case ISTORE_1: + case ISTORE_2: + case ISTORE_3: + THIS->do_store(curBC, INT, code[i]-ISTORE_0); + break; + case LSTORE_0: + case LSTORE_1: + case LSTORE_2: + case LSTORE_3: + THIS->do_store(curBC, LONG, code[i]-LSTORE_0); + break; + case FSTORE_0: + case FSTORE_1: + case FSTORE_2: + case FSTORE_3: + THIS->do_store(curBC, FLOAT, code[i]-FSTORE_0); + break; + case DSTORE_0: + case DSTORE_1: + case DSTORE_2: + case DSTORE_3: + THIS->do_store(curBC, DOUBLE, code[i]-DSTORE_0); + break; + case ASTORE_0: + case ASTORE_1: + case ASTORE_2: + case ASTORE_3: + THIS->do_store(curBC, REFERENCE, code[i]-ASTORE_0); + break; + case IASTORE: + THIS->do_astore(curBC, INT); + break; + case LASTORE: + THIS->do_astore(curBC, LONG); + break; + case FASTORE: + THIS->do_astore(curBC, FLOAT); + break; + case DASTORE: + THIS->do_astore(curBC, DOUBLE); + break; + case AASTORE: + THIS->do_astore(curBC, REFERENCE); + break; + case BASTORE: + THIS->do_astore(curBC, BYTE); + break; + case CASTORE: + THIS->do_astore(curBC, CHAR); + break; + case SASTORE: + THIS->do_astore(curBC, SHORT); + break; + case POP: + THIS->do_pop(curBC); + break; + case POP2: + THIS->do_pop2(curBC); + break; + case DUP: + THIS->do_dup(curBC); + break; + case DUP_X1: + THIS->do_dup_x1(curBC); + break; + case DUP_X2: + THIS->do_dup_x2(curBC); + break; + case DUP2: + THIS->do_dup2(curBC); + break; + case DUP2_X1: + THIS->do_dup2_x1(curBC); + break; + case DUP2_X2: + THIS->do_dup2_x2(curBC); + break; + case SWAP: + THIS->do_swap(curBC); + break; + case IADD: + case LADD: + case FADD: + case DADD: + THIS->do_add(curBC); + break; + case ISUB: + case LSUB: + case FSUB: + case DSUB: + THIS->do_sub(curBC); + break; + case IMUL: + case LMUL: + case FMUL: + case DMUL: + THIS->do_mul(curBC); + break; + case IDIV: + case LDIV: + case FDIV: + case DDIV: + THIS->do_div(curBC); + break; + case IREM: + case LREM: + case FREM: + case DREM: + THIS->do_rem(curBC); + break; + case INEG: + case LNEG: + case FNEG: + case DNEG: + THIS->do_neg(curBC); + break; + case ISHL: + case LSHL: + THIS->do_shl(curBC); + break; + case ISHR: + case LSHR: + THIS->do_shr(curBC); + break; + case IUSHR: + case LUSHR: + THIS->do_ushr(curBC); + break; + case IAND: + case LAND: + THIS->do_and(curBC); + break; + case IOR: + case LOR: + THIS->do_or(curBC); + break; + case IXOR: + case LXOR: + THIS->do_xor(curBC); + break; + case IINC: + THIS->do_iinc( + curBC, readUByte(code, i), readSByte(code, i)); + break; + case I2L: + THIS->do_convert(curBC, LONG); + break; + case I2F: + THIS->do_convert(curBC, FLOAT); + break; + case I2D: + THIS->do_convert(curBC, DOUBLE); + break; + case L2I: + THIS->do_convert(curBC, INT); + break; + case L2F: + THIS->do_convert(curBC, FLOAT); + break; + case L2D: + THIS->do_convert(curBC, DOUBLE); + break; + case F2I: + THIS->do_convert(curBC, INT); + break; + case F2L: + THIS->do_convert(curBC, LONG); + break; + case F2D: + THIS->do_convert(curBC, DOUBLE); + break; + case D2I: + THIS->do_convert(curBC, INT); + break; + case D2L: + THIS->do_convert(curBC, LONG); + break; + case D2F: + THIS->do_convert(curBC, FLOAT); + break; + case I2B: + THIS->do_convert(curBC, BYTE); + break; + case I2C: + THIS->do_convert(curBC, CHAR); + break; + case I2S: + THIS->do_convert(curBC, SHORT); + break; + case LCMP: + THIS->do_lcmp(curBC); + break; + case FCMPL: + THIS->do_cmpl(curBC); + break; + case FCMPG: + THIS->do_cmpg(curBC); + break; + case DCMPL: + THIS->do_cmpl(curBC); + break; + case DCMPG: + THIS->do_cmpg(curBC); + break; + case IFEQ: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, EQ, INT, t, i + 1); + break; + } + case IFNE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, NE, INT, t, i + 1); + break; + } + case IFLT: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, LT, INT, t, i + 1); + break; + } + case IFGE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, GE, INT, t, i + 1); + break; + } + case IFGT: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, GT, INT, t, i + 1); + break; + } + case IFLE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_if(curBC, LE, INT, t, i + 1); + break; + } + case IF_ICMPEQ: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, EQ, t, i + 1); + break; + } + case IF_ICMPNE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, NE, t, i + 1); + break; + } + case IF_ICMPLT: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, LT, t, i + 1); + break; + } + case IF_ICMPGE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, GE, t, i + 1); + break; } + case IF_ICMPGT: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, GT, t, i + 1); + break; + } + case IF_ICMPLE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, LE, t, i + 1); + break; + } + case IF_IACMPEQ: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, EQ, t, i + 1); + break; + } + case IF_IACMPNE: { + unsigned t = curBC + readSShort(code, i); + THIS->do_ifcmp(curBC, NE, t, i + 1); + break; + } + case GOTO: + THIS->do_goto(curBC, curBC + readSShort(code, i)); + break; + case JSR: + THIS->do_jsr(curBC, curBC + readSShort(code, i)); + break; + case RET: + THIS->do_ret(curBC, readUByte(code, i)); + break; + case TABLESWITCH: { + switchCases_.clear(); + skipPadBytes(i); + int def = readSInt(code, i); + int low = readSInt(code, i); + int high = readSInt(code, i); + switchCases_.reserve(high - low + 1); + while (low <= high) + switchCases_.push_back( + std::make_pair(low++, curBC + readSInt(code, i))); + THIS->do_switch(curBC, curBC + def, switchCases_); + break; + } + case LOOKUPSWITCH: { + switchCases_.clear(); + skipPadBytes(i); + int def = readSInt(code, i); + int pairCount = readSInt(code, i); + switchCases_.reserve(pairCount); + while (pairCount--) { + int value = readSInt(code, i); + switchCases_.push_back( + std::make_pair(value, curBC + readSInt(code, i))); + } + THIS->do_switch(curBC, curBC + def, switchCases_); + break; + } + case IRETURN: + case LRETURN: + case FRETURN: + case DRETURN: + case ARETURN: + THIS->do_return(curBC); + break; + case RETURN: + THIS->do_return_void(curBC); + break; + case GETSTATIC: + THIS->do_getstatic(curBC, readUShort(code, i)); + break; + case PUTSTATIC: + THIS->do_putstatic(curBC, readUShort(code, i)); + break; + case GETFIELD: + THIS->do_getfield(curBC, readUShort(code, i)); + break; + case PUTFIELD: + THIS->do_putfield(curBC, readUShort(code, i)); + break; + case INVOKEVIRTUAL: + THIS->do_invokevirtual(curBC, readUShort(code, i)); + break; + case INVOKESPECIAL: + THIS->do_invokespecial(curBC, readUShort(code, i)); + break; + case INVOKESTATIC: + THIS->do_invokestatic(curBC, readUShort(code, i)); + break; + case INVOKEINTERFACE: { + THIS->do_invokeinterface(curBC, readUShort(code, i)); + unsigned count = readUByte(code, i); + unsigned zero = readUByte(code, i); + break; + } + case XXXUNUSEDXXX: + // FIXME: must throw something + break; + case NEW: + THIS->do_new(curBC, readUShort(code, i)); + break; + case NEWARRAY: + THIS->do_newarray(curBC, + static_cast(readUByte(code, i))); + break; + case ANEWARRAY: + THIS->do_anewarray(curBC, readUShort(code, i)); + break; + case ARRAYLENGTH: + THIS->do_arraylength(curBC); + break; + case ATHROW: + THIS->do_athrow(curBC); + break; + case CHECKCAST: + THIS->do_checkcast(curBC, readUShort(code, i)); + break; + case INSTANCEOF: + THIS->do_instanceof(curBC, readUShort(code, i)); + break; + case MONITORENTER: + THIS->do_monitorenter(curBC); + break; + case MONITOREXIT: + THIS->do_monitorexit(curBC); + break; + case WIDE: + // FIXME: must throw something + break; + case MULTIANEWARRAY: + THIS->do_multianewarray( + curBC, readUShort(code, i), readUByte(code, i)); + break; + case IFNULL: { + unsigned t = curBC + readUShort(code, i); + THIS->do_if(curBC, EQ, REFERENCE, t, i + 1); + break; + } + case IFNONNULL: { + unsigned t = curBC + readUShort(code, i); + THIS->do_if(curBC, NE, REFERENCE, t, i + 1); + break; + } + case GOTO_W: + THIS->do_goto(curBC, curBC + readSInt(code, i)); + break; + case JSR_W: + THIS->do_jsr(curBC, curBC + readSInt(code, i)); + break; + case BREAKPOINT: + case IMPDEP1: + case IMPDEP2: + case NOP: + break; + } + } + } #undef THIS - /// @brief called on ACONST_NULL - void do_aconst_null(unsigned bcI) { } - /// @brief called on ICONST_, SIPUSH and BIPUSH - void do_iconst(unsigned bcI, int value) { } - /// @brief called on LCONST_ - void do_lconst(unsigned bcI, long long value) { } - /// @brief called on FCONST_ - void do_fconst(unsigned bcI, float value) { } - /// @brief called on DCONST_ - void do_dconst(unsigned bcI, double value) { } - /// @brief called on LDC, LDC_W and LDC2_W - void do_ldc(unsigned bcI, unsigned index) { } - /// @brief called on ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, - /// ILOAD_, LLOAD_, FLOAD_, DLOAD_, and ALOAD_ - void do_load(unsigned bcI, JType type, unsigned index) { } - /// @brief called on IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, - /// BALOAD, CALOAD, and SALOAD - void do_aload(unsigned bcI, JType type) { } - /// @brief called on ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, - /// ISTORE_, LSTORE_, FSTORE_, DSTORE_, and - /// ASTORE_ - void do_store(unsigned bcI, JType type, unsigned index) { } - /// @brief called on IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, - /// BASTORE, CASTORE, and SASTORE - void do_astore(unsigned bcI, JType type) { } - /// @brief called on POP - void do_pop(unsigned bcI) { } - /// @brief called on POP2 - void do_pop2(unsigned bcI) { } - /// @brief called on DUP - void do_dup(unsigned bcI) { } - /// @brief called on DUP_X1 - void do_dup_x1(unsigned bcI) { } - /// @brief called on DUP_X2 - void do_dup_x2(unsigned bcI) { } - /// @brief called on DUP2 - void do_dup2(unsigned bcI) { } - /// @brief called on DUP2_X1 - void do_dup2_x1(unsigned bcI) { } - /// @brief called on DUP2_X2 - void do_dup2_x2(unsigned bcI) { } - /// @brief called on SWAP - void do_swap(unsigned bcI) { } - /// @brief called on IADD, LADD, FADD, and DADD - void do_add(unsigned bcI) { } - /// @brief called on ISUB, LSUB, FSUB, and DSUB - void do_sub(unsigned bcI) { } - /// @brief called on IMUL, LMUL, FMUL, and DMUL - void do_mul(unsigned bcI) { } - /// @brief called on IDIV, LDIV, FDIV, and DDIV - void do_div(unsigned bcI) { } - /// @brief called on IREM, LREM, FREM, and DREM - void do_rem(unsigned bcI) { } - /// @brief called on INEG, LNEG, FNEG, and DNEG - void do_neg(unsigned bcI) { } - /// @brief called on ISHL and LSHL - void do_shl(unsigned bcI) { } - /// @brief called on ISHR and LSHR - void do_shr(unsigned bcI) { } - /// @brief called on IUSHR and LUSHR - void do_ushr(unsigned bcI) { } - /// @brief called on IAND and LAND - void do_and(unsigned bcI) { } - /// @brief called on IOR or LOR - void do_or(unsigned bcI) { } - /// @brief called on IXOR and LXOR - void do_xor(unsigned bcI) { } - /// @brief called on IINC - void do_iinc(unsigned bcI, unsigned index, int amount) { } - /// @brief called on I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, - /// F2D, D2I, D2L, D2F, I2B, I2C, and I2S - void do_convert(unsigned bcI, JType to) { } - /// @brief called on LCMP - void do_lcmp(unsigned bcI) { } - /// @brief called on FCMPL and DCMPL - void do_cmpl(unsigned bcI) { } - /// @brief called on FCMPG and DCMPG - void do_cmpg(unsigned bcI) { } - /// @brief called on IF, IFNULL, and IFNONNULL - void do_if(unsigned bcI, JSetCC cc, JType type, - unsigned t, unsigned f) { } - /// @brief called on IFCMP and IFACMP - void do_ifcmp(unsigned bcI, JSetCC cc, - unsigned t, unsigned f) { } - /// @brief called on GOTO and GOTO_W - void do_goto(unsigned bcI, unsigned target) { } - /// @brief called on JSR and JSR_W - void do_jsr(unsigned bcI, unsigned target) { } - /// @brief called on RET - void do_ret(unsigned bcI, unsigned index) { } - /// @brief called on TABLESWITCH and LOOKUPSWITCH - void do_switch(unsigned bcI, - unsigned defTarget, - const SwitchCases& sw) { } - /// @brief called on IRETURN, LRETURN, FRETURN, DRETURN and - /// ARETURN - void do_return(unsigned bcI) { } - /// @brief called on RETURN - void do_return_void(unsigned bcI) { } - /// @brief called on GETSTATIC - void do_getstatic(unsigned bcI, unsigned index) { } - /// @brief called on PUTSTATIC - void do_putstatic(unsigned bcI, unsigned index) { } - /// @brief called on GETFIELD - void do_getfield(unsigned bcI, unsigned index) { } - /// @brief called on PUTFIELD - void do_putfield(unsigned bcI, unsigned index) { } - /// @brief called on INVOKEVIRTUAL - void do_invokevirtual(unsigned bcI, unsigned index) { } - /// @brief called on INVOKESPECIAL - void do_invokespecial(unsigned bcI, unsigned index) { } - /// @brief called on INVOKESTATIC - void do_invokestatic(unsigned bcI, unsigned index) { } - /// @brief called on INVOKEINTERFACE - void do_invokeinterface(unsigned bcI, unsigned index) { } - /// @brief called on NEW - void do_new(unsigned bcI, unsigned index) { } - /// @brief called on NEWARRAY - void do_newarray(unsigned bcI, JType type) { } - /// @brief called on ANEWARRAY - void do_anewarray(unsigned bcI, unsigned index) { } - /// @brief called on ARRAYLENGTH - void do_arraylength(unsigned bcI) { } - /// @brief called on ATHROW - void do_athrow(unsigned bcI) { } - /// @brief called on CHECKCAST - void do_checkcast(unsigned bcI, unsigned index) { } - /// @brief called on INSTANCEOF - void do_instanceof(unsigned bcI, unsigned index) { } - /// @brief called on MONITORENTER - void do_monitorenter(unsigned bcI) { } - /// @brief called on MONITOREXIT - void do_monitorexit(unsigned bcI) { } - /// @brief called on MULTIANEWARRAY - void do_multianewarray(unsigned bcI, - unsigned index, - unsigned dims) { } - }; + /// @brief called on ACONST_NULL + void do_aconst_null(unsigned bcI) { } + /// @brief called on ICONST_, SIPUSH and BIPUSH + void do_iconst(unsigned bcI, int value) { } + /// @brief called on LCONST_ + void do_lconst(unsigned bcI, long long value) { } + /// @brief called on FCONST_ + void do_fconst(unsigned bcI, float value) { } + /// @brief called on DCONST_ + void do_dconst(unsigned bcI, double value) { } + /// @brief called on LDC, LDC_W and LDC2_W + void do_ldc(unsigned bcI, unsigned index) { } + /// @brief called on ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, + /// ILOAD_, LLOAD_, FLOAD_, DLOAD_, and ALOAD_ + void do_load(unsigned bcI, JType type, unsigned index) { } + /// @brief called on IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, + /// BALOAD, CALOAD, and SALOAD + void do_aload(unsigned bcI, JType type) { } + /// @brief called on ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, + /// ISTORE_, LSTORE_, FSTORE_, DSTORE_, and + /// ASTORE_ + void do_store(unsigned bcI, JType type, unsigned index) { } + /// @brief called on IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, + /// BASTORE, CASTORE, and SASTORE + void do_astore(unsigned bcI, JType type) { } + /// @brief called on POP + void do_pop(unsigned bcI) { } + /// @brief called on POP2 + void do_pop2(unsigned bcI) { } + /// @brief called on DUP + void do_dup(unsigned bcI) { } + /// @brief called on DUP_X1 + void do_dup_x1(unsigned bcI) { } + /// @brief called on DUP_X2 + void do_dup_x2(unsigned bcI) { } + /// @brief called on DUP2 + void do_dup2(unsigned bcI) { } + /// @brief called on DUP2_X1 + void do_dup2_x1(unsigned bcI) { } + /// @brief called on DUP2_X2 + void do_dup2_x2(unsigned bcI) { } + /// @brief called on SWAP + void do_swap(unsigned bcI) { } + /// @brief called on IADD, LADD, FADD, and DADD + void do_add(unsigned bcI) { } + /// @brief called on ISUB, LSUB, FSUB, and DSUB + void do_sub(unsigned bcI) { } + /// @brief called on IMUL, LMUL, FMUL, and DMUL + void do_mul(unsigned bcI) { } + /// @brief called on IDIV, LDIV, FDIV, and DDIV + void do_div(unsigned bcI) { } + /// @brief called on IREM, LREM, FREM, and DREM + void do_rem(unsigned bcI) { } + /// @brief called on INEG, LNEG, FNEG, and DNEG + void do_neg(unsigned bcI) { } + /// @brief called on ISHL and LSHL + void do_shl(unsigned bcI) { } + /// @brief called on ISHR and LSHR + void do_shr(unsigned bcI) { } + /// @brief called on IUSHR and LUSHR + void do_ushr(unsigned bcI) { } + /// @brief called on IAND and LAND + void do_and(unsigned bcI) { } + /// @brief called on IOR or LOR + void do_or(unsigned bcI) { } + /// @brief called on IXOR and LXOR + void do_xor(unsigned bcI) { } + /// @brief called on IINC + void do_iinc(unsigned bcI, unsigned index, int amount) { } + /// @brief called on I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, + /// F2D, D2I, D2L, D2F, I2B, I2C, and I2S + void do_convert(unsigned bcI, JType to) { } + /// @brief called on LCMP + void do_lcmp(unsigned bcI) { } + /// @brief called on FCMPL and DCMPL + void do_cmpl(unsigned bcI) { } + /// @brief called on FCMPG and DCMPG + void do_cmpg(unsigned bcI) { } + /// @brief called on IF, IFNULL, and IFNONNULL + void do_if(unsigned bcI, JSetCC cc, JType type, + unsigned t, unsigned f) { } + /// @brief called on IFCMP and IFACMP + void do_ifcmp(unsigned bcI, JSetCC cc, + unsigned t, unsigned f) { } + /// @brief called on GOTO and GOTO_W + void do_goto(unsigned bcI, unsigned target) { } + /// @brief called on JSR and JSR_W + void do_jsr(unsigned bcI, unsigned target) { } + /// @brief called on RET + void do_ret(unsigned bcI, unsigned index) { } + /// @brief called on TABLESWITCH and LOOKUPSWITCH + void do_switch(unsigned bcI, + unsigned defTarget, + const SwitchCases& sw) { } + /// @brief called on IRETURN, LRETURN, FRETURN, DRETURN and + /// ARETURN + void do_return(unsigned bcI) { } + /// @brief called on RETURN + void do_return_void(unsigned bcI) { } + /// @brief called on GETSTATIC + void do_getstatic(unsigned bcI, unsigned index) { } + /// @brief called on PUTSTATIC + void do_putstatic(unsigned bcI, unsigned index) { } + /// @brief called on GETFIELD + void do_getfield(unsigned bcI, unsigned index) { } + /// @brief called on PUTFIELD + void do_putfield(unsigned bcI, unsigned index) { } + /// @brief called on INVOKEVIRTUAL + void do_invokevirtual(unsigned bcI, unsigned index) { } + /// @brief called on INVOKESPECIAL + void do_invokespecial(unsigned bcI, unsigned index) { } + /// @brief called on INVOKESTATIC + void do_invokestatic(unsigned bcI, unsigned index) { } + /// @brief called on INVOKEINTERFACE + void do_invokeinterface(unsigned bcI, unsigned index) { } + /// @brief called on NEW + void do_new(unsigned bcI, unsigned index) { } + /// @brief called on NEWARRAY + void do_newarray(unsigned bcI, JType type) { } + /// @brief called on ANEWARRAY + void do_anewarray(unsigned bcI, unsigned index) { } + /// @brief called on ARRAYLENGTH + void do_arraylength(unsigned bcI) { } + /// @brief called on ATHROW + void do_athrow(unsigned bcI) { } + /// @brief called on CHECKCAST + void do_checkcast(unsigned bcI, unsigned index) { } + /// @brief called on INSTANCEOF + void do_instanceof(unsigned bcI, unsigned index) { } + /// @brief called on MONITORENTER + void do_monitorenter(unsigned bcI) { } + /// @brief called on MONITOREXIT + void do_monitorexit(unsigned bcI) { } + /// @brief called on MULTIANEWARRAY + void do_multianewarray(unsigned bcI, + unsigned index, + unsigned dims) { } + }; } } // namespace llvm::Java Index: llvm-java/include/llvm/Java/Bytecode.h diff -u llvm-java/include/llvm/Java/Bytecode.h:1.9 llvm-java/include/llvm/Java/Bytecode.h:1.10 --- llvm-java/include/llvm/Java/Bytecode.h:1.9 Tue May 25 20:28:49 2004 +++ llvm-java/include/llvm/Java/Bytecode.h Wed Aug 4 05:02:03 2004 @@ -21,247 +21,247 @@ namespace llvm { namespace Java { - namespace Opcode { + namespace Opcode { - enum { - NOP = 0x00, - ACONST_NULL = 0x01, - ICONST_M1 = 0x02, - ICONST_0 = 0x03, - ICONST_1 = 0x04, - ICONST_2 = 0x05, - ICONST_3 = 0x06, - ICONST_4 = 0x07, - ICONST_5 = 0x08, - LCONST_0 = 0x09, - LCONST_1 = 0x0A, - FCONST_0 = 0x0B, - FCONST_1 = 0x0C, - FCONST_2 = 0x0D, - DCONST_0 = 0x0E, - DCONST_1 = 0x0F, - BIPUSH = 0x10, - SIPUSH = 0x11, - LDC = 0x12, - LDC_W = 0x13, - LDC2_W = 0x14, - ILOAD = 0x15, - LLOAD = 0x16, - FLOAD = 0x17, - DLOAD = 0x18, - ALOAD = 0x19, - ILOAD_0 = 0x1A, - ILOAD_1 = 0x1B, - ILOAD_2 = 0x1C, - ILOAD_3 = 0x1D, - LLOAD_0 = 0x1E, - LLOAD_1 = 0x1F, - LLOAD_2 = 0x20, - LLOAD_3 = 0x21, - FLOAD_0 = 0x22, - FLOAD_1 = 0x23, - FLOAD_2 = 0x24, - FLOAD_3 = 0x25, - DLOAD_0 = 0x26, - DLOAD_1 = 0x27, - DLOAD_2 = 0x28, - DLOAD_3 = 0x29, - ALOAD_0 = 0x2A, - ALOAD_1 = 0x2B, - ALOAD_2 = 0x2C, - ALOAD_3 = 0x2D, - IALOAD = 0x2E, - LALOAD = 0x2F, - FALOAD = 0x30, - DALOAD = 0x31, - AALOAD = 0x32, - BALOAD = 0x33, - CALOAD = 0x34, - SALOAD = 0x35, - ISTORE = 0x36, - LSTORE = 0x37, - FSTORE = 0x38, - DSTORE = 0x39, - ASTORE = 0x3A, - ISTORE_0 = 0x3B, - ISTORE_1 = 0x3C, - ISTORE_2 = 0x3D, - ISTORE_3 = 0x3E, - LSTORE_0 = 0x3F, - LSTORE_1 = 0x40, - LSTORE_2 = 0x41, - LSTORE_3 = 0x42, - FSTORE_0 = 0x43, - FSTORE_1 = 0x44, - FSTORE_2 = 0x45, - FSTORE_3 = 0x46, - DSTORE_0 = 0x47, - DSTORE_1 = 0x48, - DSTORE_2 = 0x49, - DSTORE_3 = 0x4A, - ASTORE_0 = 0x4B, - ASTORE_1 = 0x4C, - ASTORE_2 = 0x4D, - ASTORE_3 = 0x4E, - IASTORE = 0x4F, - LASTORE = 0x50, - FASTORE = 0x51, - DASTORE = 0x52, - AASTORE = 0x53, - BASTORE = 0x54, - CASTORE = 0x55, - SASTORE = 0x56, - POP = 0x57, - POP2 = 0x58, - DUP = 0x59, - DUP_X1 = 0x5A, - DUP_X2 = 0x5B, - DUP2 = 0x5C, - DUP2_X1 = 0x5D, - DUP2_X2 = 0x5E, - SWAP = 0x5F, - IADD = 0x60, - LADD = 0x61, - FADD = 0x62, - DADD = 0x63, - ISUB = 0x64, - LSUB = 0x65, - FSUB = 0x66, - DSUB = 0x67, - IMUL = 0x68, - LMUL = 0x69, - FMUL = 0x6A, - DMUL = 0x6B, - IDIV = 0x6C, - LDIV = 0x6D, - FDIV = 0x6E, - DDIV = 0x6F, - IREM = 0x70, - LREM = 0x71, - FREM = 0x72, - DREM = 0x73, - INEG = 0x74, - LNEG = 0x75, - FNEG = 0x76, - DNEG = 0x77, - ISHL = 0x78, - LSHL = 0x79, - ISHR = 0x7A, - LSHR = 0x7B, - IUSHR = 0x7C, - LUSHR = 0x7D, - IAND = 0x7E, - LAND = 0x7F, - IOR = 0x80, - LOR = 0x81, - IXOR = 0x82, - LXOR = 0x83, - IINC = 0x84, - I2L = 0x85, - I2F = 0x86, - I2D = 0x87, - L2I = 0x88, - L2F = 0x89, - L2D = 0x8A, - F2I = 0x8B, - F2L = 0x8C, - F2D = 0x8D, - D2I = 0x8E, - D2L = 0x8F, - D2F = 0x90, - I2B = 0x91, - I2C = 0x92, - I2S = 0x93, - LCMP = 0x94, - FCMPL = 0x95, - FCMPG = 0x96, - DCMPL = 0x97, - DCMPG = 0x98, - IFEQ = 0x99, - IFNE = 0x9A, - IFLT = 0x9B, - IFGE = 0x9C, - IFGT = 0x9D, - IFLE = 0x9E, - IF_ICMPEQ = 0x9F, - IF_ICMPNE = 0xA0, - IF_ICMPLT = 0xA1, - IF_ICMPGE = 0xA2, - IF_ICMPGT = 0xA3, - IF_ICMPLE = 0xA4, - IF_IACMPEQ = 0xA5, - IF_IACMPNE = 0xA6, - GOTO = 0xA7, - JSR = 0xA8, - RET = 0xA9, - TABLESWITCH = 0xAA, - LOOKUPSWITCH = 0xAB, - IRETURN = 0xAC, - LRETURN = 0xAD, - FRETURN = 0xAE, - DRETURN = 0xAF, - ARETURN = 0xB0, - RETURN = 0xB1, - GETSTATIC = 0xB2, - PUTSTATIC = 0xB3, - GETFIELD = 0xB4, - PUTFIELD = 0xB5, - INVOKEVIRTUAL = 0xB6, - INVOKESPECIAL = 0xB7, - INVOKESTATIC = 0xB8, - INVOKEINTERFACE = 0xB9, - XXXUNUSEDXXX = 0xBA, - NEW = 0xBB, - NEWARRAY = 0xBC, - ANEWARRAY = 0xBD, - ARRAYLENGTH = 0xBE, - ATHROW = 0xBF, - CHECKCAST = 0xC0, - INSTANCEOF = 0xC1, - MONITORENTER = 0xC2, - MONITOREXIT = 0xC3, - WIDE = 0xC4, - MULTIANEWARRAY = 0xC5, - IFNULL = 0xC6, - IFNONNULL = 0xC7, - GOTO_W = 0xC8, - JSR_W = 0xC9, - BREAKPOINT = 0xCA, - IMPDEP1 = 0xFE, - IMPDEP2 = 0xFF, - }; - - } // namespace Opcode - - inline int readSByte(const uint8_t* code, unsigned& i) { - return ((int8_t*)code)[++i]; - } - - inline unsigned readUByte(const uint8_t* code, unsigned& i) { - return code[++i]; - } - - inline int readSShort(const uint8_t* code, unsigned& i) { - return (readSByte(code, i) << 8) | readUByte(code, i); - } - - inline unsigned readUShort(const uint8_t* code, unsigned& i) { - return (readUByte(code, i) << 8) | readUByte(code, i); - } - - inline int readSInt(const uint8_t* code, unsigned& i) { - return (readUShort(code, i) << 16) | readUShort(code, i); - } - - inline unsigned readUInt(const uint8_t* code, unsigned& i) { - return readSInt(code, i); - } - - inline void skipPadBytes(unsigned& i) { - unsigned lastTwoBits = i & 0x3; - i += (4 - lastTwoBits) & 0x3; - --i; - } + enum { + NOP = 0x00, + ACONST_NULL = 0x01, + ICONST_M1 = 0x02, + ICONST_0 = 0x03, + ICONST_1 = 0x04, + ICONST_2 = 0x05, + ICONST_3 = 0x06, + ICONST_4 = 0x07, + ICONST_5 = 0x08, + LCONST_0 = 0x09, + LCONST_1 = 0x0A, + FCONST_0 = 0x0B, + FCONST_1 = 0x0C, + FCONST_2 = 0x0D, + DCONST_0 = 0x0E, + DCONST_1 = 0x0F, + BIPUSH = 0x10, + SIPUSH = 0x11, + LDC = 0x12, + LDC_W = 0x13, + LDC2_W = 0x14, + ILOAD = 0x15, + LLOAD = 0x16, + FLOAD = 0x17, + DLOAD = 0x18, + ALOAD = 0x19, + ILOAD_0 = 0x1A, + ILOAD_1 = 0x1B, + ILOAD_2 = 0x1C, + ILOAD_3 = 0x1D, + LLOAD_0 = 0x1E, + LLOAD_1 = 0x1F, + LLOAD_2 = 0x20, + LLOAD_3 = 0x21, + FLOAD_0 = 0x22, + FLOAD_1 = 0x23, + FLOAD_2 = 0x24, + FLOAD_3 = 0x25, + DLOAD_0 = 0x26, + DLOAD_1 = 0x27, + DLOAD_2 = 0x28, + DLOAD_3 = 0x29, + ALOAD_0 = 0x2A, + ALOAD_1 = 0x2B, + ALOAD_2 = 0x2C, + ALOAD_3 = 0x2D, + IALOAD = 0x2E, + LALOAD = 0x2F, + FALOAD = 0x30, + DALOAD = 0x31, + AALOAD = 0x32, + BALOAD = 0x33, + CALOAD = 0x34, + SALOAD = 0x35, + ISTORE = 0x36, + LSTORE = 0x37, + FSTORE = 0x38, + DSTORE = 0x39, + ASTORE = 0x3A, + ISTORE_0 = 0x3B, + ISTORE_1 = 0x3C, + ISTORE_2 = 0x3D, + ISTORE_3 = 0x3E, + LSTORE_0 = 0x3F, + LSTORE_1 = 0x40, + LSTORE_2 = 0x41, + LSTORE_3 = 0x42, + FSTORE_0 = 0x43, + FSTORE_1 = 0x44, + FSTORE_2 = 0x45, + FSTORE_3 = 0x46, + DSTORE_0 = 0x47, + DSTORE_1 = 0x48, + DSTORE_2 = 0x49, + DSTORE_3 = 0x4A, + ASTORE_0 = 0x4B, + ASTORE_1 = 0x4C, + ASTORE_2 = 0x4D, + ASTORE_3 = 0x4E, + IASTORE = 0x4F, + LASTORE = 0x50, + FASTORE = 0x51, + DASTORE = 0x52, + AASTORE = 0x53, + BASTORE = 0x54, + CASTORE = 0x55, + SASTORE = 0x56, + POP = 0x57, + POP2 = 0x58, + DUP = 0x59, + DUP_X1 = 0x5A, + DUP_X2 = 0x5B, + DUP2 = 0x5C, + DUP2_X1 = 0x5D, + DUP2_X2 = 0x5E, + SWAP = 0x5F, + IADD = 0x60, + LADD = 0x61, + FADD = 0x62, + DADD = 0x63, + ISUB = 0x64, + LSUB = 0x65, + FSUB = 0x66, + DSUB = 0x67, + IMUL = 0x68, + LMUL = 0x69, + FMUL = 0x6A, + DMUL = 0x6B, + IDIV = 0x6C, + LDIV = 0x6D, + FDIV = 0x6E, + DDIV = 0x6F, + IREM = 0x70, + LREM = 0x71, + FREM = 0x72, + DREM = 0x73, + INEG = 0x74, + LNEG = 0x75, + FNEG = 0x76, + DNEG = 0x77, + ISHL = 0x78, + LSHL = 0x79, + ISHR = 0x7A, + LSHR = 0x7B, + IUSHR = 0x7C, + LUSHR = 0x7D, + IAND = 0x7E, + LAND = 0x7F, + IOR = 0x80, + LOR = 0x81, + IXOR = 0x82, + LXOR = 0x83, + IINC = 0x84, + I2L = 0x85, + I2F = 0x86, + I2D = 0x87, + L2I = 0x88, + L2F = 0x89, + L2D = 0x8A, + F2I = 0x8B, + F2L = 0x8C, + F2D = 0x8D, + D2I = 0x8E, + D2L = 0x8F, + D2F = 0x90, + I2B = 0x91, + I2C = 0x92, + I2S = 0x93, + LCMP = 0x94, + FCMPL = 0x95, + FCMPG = 0x96, + DCMPL = 0x97, + DCMPG = 0x98, + IFEQ = 0x99, + IFNE = 0x9A, + IFLT = 0x9B, + IFGE = 0x9C, + IFGT = 0x9D, + IFLE = 0x9E, + IF_ICMPEQ = 0x9F, + IF_ICMPNE = 0xA0, + IF_ICMPLT = 0xA1, + IF_ICMPGE = 0xA2, + IF_ICMPGT = 0xA3, + IF_ICMPLE = 0xA4, + IF_IACMPEQ = 0xA5, + IF_IACMPNE = 0xA6, + GOTO = 0xA7, + JSR = 0xA8, + RET = 0xA9, + TABLESWITCH = 0xAA, + LOOKUPSWITCH = 0xAB, + IRETURN = 0xAC, + LRETURN = 0xAD, + FRETURN = 0xAE, + DRETURN = 0xAF, + ARETURN = 0xB0, + RETURN = 0xB1, + GETSTATIC = 0xB2, + PUTSTATIC = 0xB3, + GETFIELD = 0xB4, + PUTFIELD = 0xB5, + INVOKEVIRTUAL = 0xB6, + INVOKESPECIAL = 0xB7, + INVOKESTATIC = 0xB8, + INVOKEINTERFACE = 0xB9, + XXXUNUSEDXXX = 0xBA, + NEW = 0xBB, + NEWARRAY = 0xBC, + ANEWARRAY = 0xBD, + ARRAYLENGTH = 0xBE, + ATHROW = 0xBF, + CHECKCAST = 0xC0, + INSTANCEOF = 0xC1, + MONITORENTER = 0xC2, + MONITOREXIT = 0xC3, + WIDE = 0xC4, + MULTIANEWARRAY = 0xC5, + IFNULL = 0xC6, + IFNONNULL = 0xC7, + GOTO_W = 0xC8, + JSR_W = 0xC9, + BREAKPOINT = 0xCA, + IMPDEP1 = 0xFE, + IMPDEP2 = 0xFF, + }; + + } // namespace Opcode + + inline int readSByte(const uint8_t* code, unsigned& i) { + return ((int8_t*)code)[++i]; + } + + inline unsigned readUByte(const uint8_t* code, unsigned& i) { + return code[++i]; + } + + inline int readSShort(const uint8_t* code, unsigned& i) { + return (readSByte(code, i) << 8) | readUByte(code, i); + } + + inline unsigned readUShort(const uint8_t* code, unsigned& i) { + return (readUByte(code, i) << 8) | readUByte(code, i); + } + + inline int readSInt(const uint8_t* code, unsigned& i) { + return (readUShort(code, i) << 16) | readUShort(code, i); + } + + inline unsigned readUInt(const uint8_t* code, unsigned& i) { + return readSInt(code, i); + } + + inline void skipPadBytes(unsigned& i) { + unsigned lastTwoBits = i & 0x3; + i += (4 - lastTwoBits) & 0x3; + --i; + } } } // namespace llvm::Java From alkis at cs.uiuc.edu Wed Aug 4 05:02:14 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:02:14 -0500 Subject: [llvm-commits] CVS: llvm-java/tools/class2llvm/class2llvm.cpp Message-ID: <200408041002.FAA26643@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/class2llvm: class2llvm.cpp updated: 1.12 -> 1.13 --- Log message: Convert indentation to 2 spaces. --- Diffs of the changes: (+17 -17) Index: llvm-java/tools/class2llvm/class2llvm.cpp diff -u llvm-java/tools/class2llvm/class2llvm.cpp:1.12 llvm-java/tools/class2llvm/class2llvm.cpp:1.13 --- llvm-java/tools/class2llvm/class2llvm.cpp:1.12 Tue Aug 3 07:10:33 2004 +++ llvm-java/tools/class2llvm/class2llvm.cpp Wed Aug 4 05:02:03 2004 @@ -30,25 +30,25 @@ int main(int argc, char* argv[]) { - PrintStackTraceOnErrorSignal(); - cl::ParseCommandLineOptions(argc, argv, - "classfile to llvm utility"); + PrintStackTraceOnErrorSignal(); + cl::ParseCommandLineOptions(argc, argv, + "classfile to llvm utility"); - try { - Java::Compiler compiler; + try { + Java::Compiler compiler; - Module module(InputClass); - compiler.compile(module, InputClass); + Module module(InputClass); + compiler.compile(module, InputClass); - PassManager passes; - passes.add(createVerifierPass()); - passes.add(new WriteBytecodePass(&std::cout)); - passes.run(module); - } - catch (std::exception& e) { - std::cerr << e.what() << '\n'; - return EXIT_FAILURE; - } + PassManager passes; + passes.add(createVerifierPass()); + passes.add(new WriteBytecodePass(&std::cout)); + passes.run(module); + } + catch (std::exception& e) { + std::cerr << e.what() << '\n'; + return EXIT_FAILURE; + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } From alkis at cs.uiuc.edu Wed Aug 4 05:20:38 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 4 Aug 2004 05:20:38 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408041020.FAA26762@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.74 -> 1.75 --- Log message: Unwrap some lines. --- Diffs of the changes: (+23 -45) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.74 llvm-java/lib/Compiler/Compiler.cpp:1.75 --- llvm-java/lib/Compiler/Compiler.cpp:1.74 Wed Aug 4 05:02:03 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Wed Aug 4 05:20:28 2004 @@ -52,8 +52,7 @@ llvm::Constant* getConstant(Constant* c) { if (dynamic_cast(c)) assert(0 && "not implemented"); - else if (ConstantInteger* i = - dynamic_cast(c)) + else if (ConstantInteger* i = dynamic_cast(c)) return ConstantSInt::get(Type::IntTy, i->getValue()); else if (ConstantFloat* f = dynamic_cast(c)) return ConstantFP::get(Type::FloatTy, f->getValue()); @@ -94,21 +93,17 @@ void do_if(unsigned bcI, JSetCC cc, JType type, unsigned t, unsigned f) { if (!bc2bbMap_[t]) - bc2bbMap_[t] = - new BasicBlock("bc" + utostr(t), &function_); + bc2bbMap_[t] = new BasicBlock("bc" + utostr(t), &function_); if (!bc2bbMap_[f]) - bc2bbMap_[f] = - new BasicBlock("bc" + utostr(f), &function_); + bc2bbMap_[f] = new BasicBlock("bc" + utostr(f), &function_); } void do_ifcmp(unsigned bcI, JSetCC cc, unsigned t, unsigned f) { if (!bc2bbMap_[t]) - bc2bbMap_[t] = - new BasicBlock("bc" + utostr(t), &function_); + bc2bbMap_[t] = new BasicBlock("bc" + utostr(t), &function_); if (!bc2bbMap_[f]) - bc2bbMap_[f] = - new BasicBlock("bc" + utostr(f), &function_); + bc2bbMap_[f] = new BasicBlock("bc" + utostr(f), &function_); } void do_switch(unsigned bcI, @@ -117,8 +112,7 @@ for (unsigned i = 0; i < sw.size(); ++i) { unsigned target = sw[i].second; if (!bc2bbMap_[target]) - bc2bbMap_[target] = - new BasicBlock("bc" + utostr(target), &function_); + bc2bbMap_[target] = new BasicBlock("bc" + utostr(target), &function_); } if (!bc2bbMap_[defTarget]) bc2bbMap_[defTarget] = @@ -234,8 +228,7 @@ params.push_back(PointerType::get(self)); while (descr[i] != ')') params.push_back(getTypeHelper(descr, i, NULL)); - return FunctionType::get(getTypeHelper(descr, ++i, NULL), - params, false); + return FunctionType::get(getTypeHelper(descr, ++i, NULL),params, false); } // FIXME: Throw something default: return NULL; @@ -278,8 +271,7 @@ } } PATypeHolder holder = ci.type; - cast(ci.type)->refineAbstractTypeTo - (StructType::get(elements)); + cast(ci.type)->refineAbstractTypeTo(StructType::get(elements)); ci.type = holder.get(); DEBUG(std::cerr << "Adding " << className << " = " << *ci.type << " to type map\n"); @@ -323,8 +315,7 @@ // Cast ptr to correct type std::string className = fieldRef->getClass()->getName()->str(); - ptr = new CastInst(ptr, - PointerType::get(getClassInfo(className).type), + ptr = new CastInst(ptr, PointerType::get(getClassInfo(className).type), TMP, getBBAt(bcI)); ClassFile* classfile = ClassFile::getClassFile(className); std::string fieldName = nameAndType->getName()->str(); @@ -341,8 +332,7 @@ indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); } else { - indices.push_back(ConstantUInt::get(Type::UIntTy, - it->second)); + indices.push_back(ConstantUInt::get(Type::UIntTy, it->second)); break; } } @@ -404,11 +394,9 @@ name += method->getName()->str(); name += method->getDescriptor()->str(); - Function* hook = - module_->getOrInsertFunction("llvm_java_static_init", - Type::VoidTy, 0); - Function* init = - module_->getOrInsertFunction(name, Type::VoidTy, 0); + Function* hook = module_->getOrInsertFunction("llvm_java_static_init", + Type::VoidTy, 0); + Function* init = module_->getOrInsertFunction(name, Type::VoidTy, 0); // if this is the first time we scheduled this function // for compilation insert a call to it right before the @@ -452,10 +440,8 @@ Method* method = classfile->getMethod(methodNameAndDescr); if (!method) - throw InvocationTargetException( - "Method " + methodNameAndDescr + - " not found in class " + className); - + throw InvocationTargetException("Method " + methodNameAndDescr + + " not found in class " + className); return std::make_pair(classfile, method); } @@ -668,8 +654,7 @@ void do_neg(unsigned bcI) { Value* v1 = opStack_.top(); opStack_.pop(); - opStack_.push( - BinaryOperator::createNeg(v1, TMP, getBBAt(bcI))); + opStack_.push(BinaryOperator::createNeg(v1, TMP, getBBAt(bcI))); } void do_shl(unsigned bcI) { @@ -684,8 +669,7 @@ // cast value to be shifted into its unsigned version do_swap(bcI); Value* value = opStack_.top(); opStack_.pop(); - value = new CastInst(value, - value->getType()->getUnsignedVersion(), + value = new CastInst(value, value->getType()->getUnsignedVersion(), TMP, getBBAt(bcI)); opStack_.push(value); do_swap(bcI); @@ -694,8 +678,7 @@ value = opStack_.top(); opStack_.pop(); // cast shifted value back to its original signed version - opStack_.push(new CastInst(value, - value->getType()->getSignedVersion(), + opStack_.push(new CastInst(value, value->getType()->getSignedVersion(), TMP, getBBAt(bcI))); } @@ -730,8 +713,7 @@ TMP, getBBAt(bcI)); BinaryOperator::createAdd(v, ConstantSInt::get(Type::IntTy, amount), TMP, getBBAt(bcI)); - new StoreInst(v, getOrCreateLocal(index, Type::IntTy), - getBBAt(bcI)); + new StoreInst(v, getOrCreateLocal(index, Type::IntTy), getBBAt(bcI)); } void do_convert(unsigned bcI, JType to) { @@ -774,8 +756,7 @@ ("llvm.isunordered", Type::BoolTy, v1->getType(), v2->getType(), 0), v1, v2, TMP, getBBAt(bcI)); - r = new SelectInst(c, - ConstantSInt::get(Type::IntTy, valueIfUnordered), + r = new SelectInst(c, ConstantSInt::get(Type::IntTy, valueIfUnordered), r, TMP, getBBAt(bcI)); opStack_.push(r); } @@ -812,8 +793,7 @@ unsigned defTarget, const SwitchCases& sw) { Value* v1 = opStack_.top(); opStack_.pop(); - SwitchInst* in = - new SwitchInst(v1, getBBAt(defTarget), getBBAt(bcI)); + SwitchInst* in = new SwitchInst(v1, getBBAt(defTarget), getBBAt(bcI)); for (unsigned i = 0; i < sw.size(); ++i) in->addCase(ConstantSInt::get(Type::IntTy, sw[i].first), getBBAt(sw[i].second)); @@ -878,8 +858,7 @@ new CastInst(p, paramTy, TMP, getBBAt(bcI)); } - Function* function = - module_->getOrInsertFunction(funcName, funcType); + Function* function = module_->getOrInsertFunction(funcName, funcType); toCompileFunctions_.insert(function); Value* r = new CallInst(function, params, TMP, getBBAt(bcI)); opStack_.push(r); @@ -950,8 +929,7 @@ DEBUG(std::cerr << "Compiling class: " << className << '\n'); Function* main = - compilerImpl_->compileMethod(m, - className + "/main([Ljava/lang/String;)V"); + compilerImpl_->compileMethod(m, className + "/main([Ljava/lang/String;)V"); Function* javaMain = m.getOrInsertFunction ("llvm_java_main", Type::VoidTy, Type::IntTy, PointerType::get(PointerType::get(Type::SByteTy)), NULL); From lattner at cs.uiuc.edu Wed Aug 4 13:14:36 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 13:14:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/Signals.cpp Message-ID: <200408041814.NAA26934@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: Signals.cpp updated: 1.18 -> 1.19 --- Log message: It is not possible to catch SIGKILL, don't bother trying. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Support/Signals.cpp diff -u llvm/lib/Support/Signals.cpp:1.18 llvm/lib/Support/Signals.cpp:1.19 --- llvm/lib/Support/Signals.cpp:1.18 Thu May 27 00:31:24 2004 +++ llvm/lib/Support/Signals.cpp Wed Aug 4 13:14:24 2004 @@ -31,7 +31,7 @@ // IntSigs - Signals that may interrupt the program at any time. static const int IntSigs[] = { - SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 + SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 }; static const int *IntSigsEnd = IntSigs + sizeof(IntSigs)/sizeof(IntSigs[0]); From lattner at cs.uiuc.edu Wed Aug 4 13:50:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 13:50:05 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200408041850.NAA15528@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.54 -> 1.55 --- Log message: Move method out of line --- Diffs of the changes: (+1 -3) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.54 llvm/include/llvm/Constants.h:1.55 --- llvm/include/llvm/Constants.h:1.54 Wed Aug 4 03:47:21 2004 +++ llvm/include/llvm/Constants.h Wed Aug 4 13:49:52 2004 @@ -518,9 +518,7 @@ /// ConstantExpr::get - Return a binary or shift operator constant expression, /// folding if possible. /// - static Constant *get(unsigned Opcode, Constant *C1, Constant *C2) { - return getTy(C1->getType(), Opcode, C1, C2); - } + static Constant *get(unsigned Opcode, Constant *C1, Constant *C2); /// ConstantExpr::get* - Return some common constants without having to /// specify the full Instruction::OPCODE identifier. From lattner at cs.uiuc.edu Wed Aug 4 13:50:19 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 13:50:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200408041850.NAA15608@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.99 -> 1.100 --- Log message: Fix a latent bug exposed by my recent changes --- Diffs of the changes: (+9 -1) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.99 llvm/lib/VMCore/Constants.cpp:1.100 --- llvm/lib/VMCore/Constants.cpp:1.99 Wed Aug 4 03:02:59 2004 +++ llvm/lib/VMCore/Constants.cpp Wed Aug 4 13:50:09 2004 @@ -1109,7 +1109,8 @@ assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); - if (ReqTy == C1->getType()) + if (ReqTy == C1->getType() || (Instruction::isRelational(Opcode) && + ReqTy == Type::BoolTy)) if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) return FC; // Fold a few common cases... @@ -1118,6 +1119,13 @@ return ExprConstants.getOrCreate(ReqTy, Key); } +Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { + if (Instruction::isRelational(Opcode)) + return getTy(Type::BoolTy, Opcode, C1, C2); + else + return getTy(C1->getType(), Opcode, C1, C2); +} + Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, Constant *V1, Constant *V2) { assert(C->getType() == Type::BoolTy && "Select condition must be bool!"); From criswell at cs.uiuc.edu Wed Aug 4 16:07:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed, 4 Aug 2004 16:07:05 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/fixinc/fixincl.x inclhack.def Message-ID: <200408042107.QAA17277@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc/fixinc: fixincl.x updated: 1.3 -> 1.4 inclhack.def updated: 1.3 -> 1.4 --- Log message: Added the llvm_inline_asm_linux_htonl hack for Fedora Core 1. Basically, the Linux header file for htonl() changed the #include guards so that the __GNUC__ macro checks are now two distinct checks. --- Diffs of the changes: (+65 -5) Index: llvm-gcc/gcc/fixinc/fixincl.x diff -u llvm-gcc/gcc/fixinc/fixincl.x:1.3 llvm-gcc/gcc/fixinc/fixincl.x:1.4 --- llvm-gcc/gcc/fixinc/fixincl.x:1.3 Thu Feb 5 10:05:47 2004 +++ llvm-gcc/gcc/fixinc/fixincl.x Wed Aug 4 16:06:55 2004 @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed Friday August 29, 2003 at 01:36:38 PM EDT + * It has been AutoGen-ed Wednesday August 4, 2004 at 03:55:34 PM CDT * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT CVS-MERGE THIS FILE, EITHER Fri Aug 29 13:36:38 EDT 2003 +/* DO NOT CVS-MERGE THIS FILE, EITHER Wed Aug 4 15:55:34 CDT 2004 * * You must regenerate it. Use the ./genfixes script. * @@ -15,7 +15,7 @@ * certain ANSI-incompatible system header files which are fixed to work * correctly with ANSI C and placed in a directory that GNU C will search. * - * This file contains 159 fixup descriptions. + * This file contains 160 fixup descriptions. * * See README for more information. * @@ -80,6 +80,44 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * + * Description of Llvm_Inline_Asm_Linux_Htonl fix + */ +tSCC zLlvm_Inline_Asm_Linux_HtonlName[] = + "llvm_inline_asm_linux_htonl"; + +/* + * File name selection pattern + */ +tSCC zLlvm_Inline_Asm_Linux_HtonlList[] = + "|bits/byteswap.h|"; +/* + * Machine/OS name selection pattern + */ +tSCC* apzLlvm_Inline_Asm_Linux_HtonlMachs[] = { + "i[34567]86-*-linux*", + (const char*)NULL }; + +/* + * content selection pattern - do fix if pattern found + */ +tSCC zLlvm_Inline_Asm_Linux_HtonlSelect0[] = + "^# if __GNUC__ >= 2"; + +#define LLVM_INLINE_ASM_LINUX_HTONL_TEST_CT 1 +static tTestDesc aLlvm_Inline_Asm_Linux_HtonlTests[] = { + { TT_EGREP, zLlvm_Inline_Asm_Linux_HtonlSelect0, (regex_t*)NULL }, }; + +/* + * Fix Command Arguments for Llvm_Inline_Asm_Linux_Htonl + */ +static const char* apzLlvm_Inline_Asm_Linux_HtonlPatch[] = { + "format", + "%0 && !defined __NO_MATH_INLINES", + "^# if __GNUC__ >= 2$", + (char*)NULL }; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * + * * Description of Aab_Fd_Zero_Asm_Posix_Types_H fix */ tSCC zAab_Fd_Zero_Asm_Posix_Types_HName[] = @@ -6307,15 +6345,16 @@ * * List of all fixes */ -#define REGEX_COUNT 179 +#define REGEX_COUNT 180 #define MACH_LIST_SIZE_LIMIT 261 -#define FIX_COUNT 159 +#define FIX_COUNT 160 /* * Enumerate the fixes */ typedef enum { LLVM_INLINE_ASM_LINUX_FIXIDX, + LLVM_INLINE_ASM_LINUX_HTONL_FIXIDX, AAB_FD_ZERO_ASM_POSIX_TYPES_H_FIXIDX, AAB_FD_ZERO_GNU_TYPES_H_FIXIDX, AAB_FD_ZERO_SELECTBITS_H_FIXIDX, @@ -6482,6 +6521,11 @@ LLVM_INLINE_ASM_LINUX_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE, aLlvm_Inline_Asm_LinuxTests, apzLlvm_Inline_Asm_LinuxPatch, 0 }, + { zLlvm_Inline_Asm_Linux_HtonlName, zLlvm_Inline_Asm_Linux_HtonlList, + apzLlvm_Inline_Asm_Linux_HtonlMachs, + LLVM_INLINE_ASM_LINUX_HTONL_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE, + aLlvm_Inline_Asm_Linux_HtonlTests, apzLlvm_Inline_Asm_Linux_HtonlPatch, 0 }, + { zAab_Fd_Zero_Asm_Posix_Types_HName, zAab_Fd_Zero_Asm_Posix_Types_HList, apzAab_Fd_Zero_Asm_Posix_Types_HMachs, AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT, Index: llvm-gcc/gcc/fixinc/inclhack.def diff -u llvm-gcc/gcc/fixinc/inclhack.def:1.3 llvm-gcc/gcc/fixinc/inclhack.def:1.4 --- llvm-gcc/gcc/fixinc/inclhack.def:1.3 Thu Feb 5 10:05:47 2004 +++ llvm-gcc/gcc/fixinc/inclhack.def Wed Aug 4 16:06:55 2004 @@ -38,6 +38,22 @@ }; /* + * This fixes the Fedora Core 1 ntohl inline assembly on i386. + */ +fix = { + hackname = llvm_inline_asm_linux_htonl; + files = "bits/byteswap.h"; + mach = 'i[34567]86-*-linux*'; + select = "^# if __GNUC__ >= 2"; + + c_fix = format; + c_fix_arg = "%0 && !defined __NO_MATH_INLINES"; + c_fix_arg = "^# if __GNUC__ >= 2$"; + + test_text = "# if __GNUC__ >= 2"; +}; + +/* * This fixes __FD_ZERO bug for linux 2.x.y (x <= 2 && y <= some n) */ fix = { From criswell at cs.uiuc.edu Wed Aug 4 16:08:41 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed, 4 Aug 2004 16:08:41 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp Message-ID: <200408042108.QAA17397@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++: echo.cpp updated: 1.3 -> 1.4 --- Log message: Reverted the change as llvm-gcc has a new fixincludes hack for htonl() on Fedora Core 1. --- Diffs of the changes: (+1 -9) Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.3 llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.4 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp:1.3 Tue Aug 3 14:44:53 2004 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout-C++/echo.cpp Wed Aug 4 16:08:31 2004 @@ -1,5 +1,5 @@ // -*- mode: c++ -*- -// $Id: echo.cpp,v 1.3 2004/08/03 19:44:53 criswell Exp $ +// $Id: echo.cpp,v 1.4 2004/08/04 21:08:31 criswell Exp $ // http://www.bagley.org/~doug/shootout/ #include @@ -33,11 +33,7 @@ sysabort("server/setsockopt"); memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; -#if 0 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -#else - sin.sin_addr.s_addr = 0x0100007f; -#endif sin.sin_port = 0; if (bind(ss, (sockaddr *)&sin, sizeof(sin)) == -1) sysabort("server/bind"); @@ -63,11 +59,7 @@ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) sysabort("client/socket"); sin.sin_family = AF_INET; -#if 0 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -#else - sin.sin_addr.s_addr = 0x0100007f; -#endif sin.sin_port = port; if (connect(sock, (sockaddr *)&sin, sizeof(sin)) == -1) sysabort("client/connect"); From brukman at cs.uiuc.edu Wed Aug 4 16:19:59 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 16:19:59 -0500 Subject: [llvm-commits] CVS: llvm/tools/llee/ExecveHandler.c OSInterface.h SysUtils.c SysUtils.h Message-ID: <200408042119.QAA19347@zion.cs.uiuc.edu> Changes in directory llvm/tools/llee: ExecveHandler.c updated: 1.7 -> 1.8 OSInterface.h updated: 1.2 -> 1.3 SysUtils.c updated: 1.5 -> 1.6 SysUtils.h updated: 1.4 -> 1.5 --- Log message: * Convert C++ comments to C * Add UIUC copyright notice headers --- Diffs of the changes: (+51 -37) Index: llvm/tools/llee/ExecveHandler.c diff -u llvm/tools/llee/ExecveHandler.c:1.7 llvm/tools/llee/ExecveHandler.c:1.8 --- llvm/tools/llee/ExecveHandler.c:1.7 Sat Jan 10 13:12:09 2004 +++ llvm/tools/llee/ExecveHandler.c Wed Aug 4 16:19:49 2004 @@ -1,9 +1,16 @@ -//===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===// -// -// This file implements a replacement execve() to spawn off LLVM programs to run -// transparently, without needing to be (JIT-)compiled manually by the user. -// -//===----------------------------------------------------------------------===// +/*===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===*\ + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * This file implements a replacement execve() to spawn off LLVM programs to run + * transparently, without needing to be (JIT-)compiled manually by the user. + * +\*===----------------------------------------------------------------------===*/ #include "SysUtils.h" #include "Config/unistd.h" Index: llvm/tools/llee/OSInterface.h diff -u llvm/tools/llee/OSInterface.h:1.2 llvm/tools/llee/OSInterface.h:1.3 --- llvm/tools/llee/OSInterface.h:1.2 Mon Oct 20 12:47:13 2003 +++ llvm/tools/llee/OSInterface.h Wed Aug 4 16:19:49 2004 @@ -1,16 +1,16 @@ /*===- OSInterface.h - Interface to query OS for functionality ---*- C -*--===*\ -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// - * * - * This file defines the prototype interface that we will expect operating * - * systems to implement if they wish to support offline cachine. * - * * + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * + * This file defines the prototype interface that we will expect operating + * systems to implement if they wish to support offline cachine. + * \*===----------------------------------------------------------------------===*/ #ifndef OS_INTERFACE_H Index: llvm/tools/llee/SysUtils.c diff -u llvm/tools/llee/SysUtils.c:1.5 llvm/tools/llee/SysUtils.c:1.6 --- llvm/tools/llee/SysUtils.c:1.5 Sat Jan 10 13:15:38 2004 +++ llvm/tools/llee/SysUtils.c Wed Aug 4 16:19:49 2004 @@ -1,9 +1,16 @@ -//===- SystemUtils.h - Utilities to do low-level system stuff --*- C++ -*--===// -// -// This file contains functions used to do a variety of low-level, often -// system-specific, tasks. -// -//===----------------------------------------------------------------------===// +/*===- SystemUtils.h - Utilities to do low-level system stuff -------------===*\ + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * This file contains functions used to do a variety of low-level, often + * system-specific, tasks. + * +\*===----------------------------------------------------------------------===*/ #include "SysUtils.h" #include "Config/dlfcn.h" Index: llvm/tools/llee/SysUtils.h diff -u llvm/tools/llee/SysUtils.h:1.4 llvm/tools/llee/SysUtils.h:1.5 --- llvm/tools/llee/SysUtils.h:1.4 Mon Oct 20 12:47:13 2003 +++ llvm/tools/llee/SysUtils.h Wed Aug 4 16:19:49 2004 @@ -1,16 +1,16 @@ -/*===- SysUtils.h - Utilities to do low-level system stuff -------*- C -*--===*\ -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// - * * - * This file contains functions used to do a variety of low-level, often * - * system-specific, tasks. * - * * +/*===- SysUtils.h - Utilities to do low-level system stuff ----------------===*\ + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * + * This file contains functions used to do a variety of low-level, often + * system-specific, tasks. + * \*===----------------------------------------------------------------------===*/ #ifndef SYSUTILS_H From brukman at cs.uiuc.edu Wed Aug 4 16:20:08 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 16:20:08 -0500 Subject: [llvm-commits] CVS: llvm/tools/llee/Makefile Message-ID: <200408042120.QAA19356@zion.cs.uiuc.edu> Changes in directory llvm/tools/llee: Makefile updated: 1.5 -> 1.6 --- Log message: Shared libraries are usually prepended with `lib' --- Diffs of the changes: (+1 -1) Index: llvm/tools/llee/Makefile diff -u llvm/tools/llee/Makefile:1.5 llvm/tools/llee/Makefile:1.6 --- llvm/tools/llee/Makefile:1.5 Mon Jan 26 14:59:41 2004 +++ llvm/tools/llee/Makefile Wed Aug 4 16:19:27 2004 @@ -16,7 +16,7 @@ llee: $(DESTTOOLCURRENT)/llee $(DESTTOOLCURRENT)/llee: Makefile - echo exec env LD_PRELOAD=$(DESTLIBCURRENT)/execve$(SHLIBEXT) $$\* > $@ + echo exec env LD_PRELOAD=$(DESTLIBCURRENT)/libexecve$(SHLIBEXT) $$\* > $@ chmod u+x $@ clean:: From brukman at cs.uiuc.edu Wed Aug 4 16:48:10 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 16:48:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp Message-ID: <200408042148.QAA22405@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9CodeEmitter.cpp updated: 1.68 -> 1.69 --- Log message: * Remove unnecessary comment * Fix alignment of code * Tabs to spaces --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp diff -u llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp:1.68 llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp:1.69 --- llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp:1.68 Tue Jul 27 14:37:37 2004 +++ llvm/lib/Target/SparcV9/SparcV9CodeEmitter.cpp Wed Aug 4 16:48:00 2004 @@ -49,9 +49,9 @@ } bool SparcV9TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE) { + MachineCodeEmitter &MCE) { PM.add(new SparcV9CodeEmitter(*this, MCE)); - PM.add(createSparcV9MachineCodeDestructionPass()); //Free stuff no longer needed + PM.add(createSparcV9MachineCodeDestructionPass()); return false; } @@ -586,7 +586,7 @@ void SparcV9JITInfo::replaceMachineCodeForFunction (void *Old, void *New) { assert (TheJITResolver && - "Can only call replaceMachineCodeForFunction from within JIT"); + "Can only call replaceMachineCodeForFunction from within JIT"); uint64_t Target = (uint64_t)(intptr_t)New; uint64_t CodeBegin = (uint64_t)(intptr_t)Old; TheJITResolver->insertJumpAtAddr(Target, CodeBegin); From brukman at cs.uiuc.edu Wed Aug 4 16:48:56 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 16:48:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/Makefile Message-ID: <200408042148.QAA22428@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: Makefile updated: 1.43 -> 1.44 --- Log message: Hand-propagate the constant TARGET_NAME which was making lines wrap anyway --- Diffs of the changes: (+4 -6) Index: llvm/lib/Target/SparcV9/Makefile diff -u llvm/lib/Target/SparcV9/Makefile:1.43 llvm/lib/Target/SparcV9/Makefile:1.44 --- llvm/lib/Target/SparcV9/Makefile:1.43 Wed Aug 4 02:28:51 2004 +++ llvm/lib/Target/SparcV9/Makefile Wed Aug 4 16:48:45 2004 @@ -42,19 +42,17 @@ $(BUILD_OBJ_DIR)/Depend/SparcV9.burm.d: $(BUILD_OBJ_DIR)/Depend/.dir touch $@ -TARGET_NAME := SparcV9 - TABLEGEN_FILES := $(notdir $(wildcard $(SourceDir)/*.td)) # Make sure that tblgen is run, first thing. -$(SourceDepend): $(TARGET_NAME)CodeEmitter.inc +$(SourceDepend): SparcV9CodeEmitter.inc -$(TARGET_NAME)CodeEmitter.cpp:: $(TARGET_NAME)CodeEmitter.inc +SparcV9CodeEmitter.cpp:: SparcV9CodeEmitter.inc -$(TARGET_NAME)CodeEmitter.inc:: $(SourceDir)/$(TARGET_NAME).td $(TABLEGEN_FILES) $(TBLGEN) +SparcV9CodeEmitter.inc:: $(SourceDir)/SparcV9.td $(TABLEGEN_FILES) $(TBLGEN) @echo "Tblgen'ing `basename $<`" $(TBLGEN) -I $(SourceDir) $< -gen-emitter -o $@ clean:: - $(RM) -f $(TARGET_NAME)CodeEmitter.inc SparcV9.burg.in1 SparcV9.burm SparcV9.burm.cpp + $(RM) -f SparcV9CodeEmitter.inc SparcV9.burg.in1 SparcV9.burm SparcV9.burm.cpp From brukman at cs.uiuc.edu Wed Aug 4 17:00:15 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 17:00:15 -0500 Subject: [llvm-commits] CVS: llvm/docs/TableGenFundamentals.html Message-ID: <200408042200.RAA23009@zion.cs.uiuc.edu> Changes in directory llvm/docs: TableGenFundamentals.html updated: 1.11 -> 1.12 --- Log message: Surround code element with tags --- Diffs of the changes: (+3 -3) Index: llvm/docs/TableGenFundamentals.html diff -u llvm/docs/TableGenFundamentals.html:1.11 llvm/docs/TableGenFundamentals.html:1.12 --- llvm/docs/TableGenFundamentals.html:1.11 Wed Jul 28 17:09:29 2004 +++ llvm/docs/TableGenFundamentals.html Wed Aug 4 17:00:05 2004 @@ -310,8 +310,8 @@
    • value{15-17} - access to multiple bits of a value
    • DEF - reference to a record definition
    • X.Y - reference to the subfield of a value
    • -
    • list[4-7,17,2-3] - A slice of the 'list' list, including elements - 4,5,6,7,17,2, and 3 from it. Elements may be included multiple times.
    • +
    • list[4-7,17,2-3] - A slice of the 'list' list, including elements +4,5,6,7,17,2, and 3 from it. Elements may be included multiple times.
    • (DEF a, b) - a dag value. The first element is required to be a record definition, the remaining elements in the list may be arbitrary other values, including nested `dag' values.
    • @@ -558,7 +558,7 @@ Chris Lattner
      LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/07/28 22:09:29 $ + Last modified: $Date: 2004/08/04 22:00:05 $ From brukman at cs.uiuc.edu Wed Aug 4 17:08:04 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 4 Aug 2004 17:08:04 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp Message-ID: <200408042208.RAA23266@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.30 -> 1.31 --- Log message: * Added documentation in the file header * Shorten assert() text to make it fit within 80 cols --- Diffs of the changes: (+4 -2) Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.30 llvm/utils/TableGen/CodeEmitterGen.cpp:1.31 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.30 Sat Jul 31 22:55:38 2004 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Wed Aug 4 17:07:54 2004 @@ -7,7 +7,9 @@ // //===----------------------------------------------------------------------===// // -// FIXME: Document. +// CodeEmitterGen uses the descriptions of instructions and their fields to +// construct an automated code emitter: a function that, given a MachineInstr, +// returns the (currently, 32-bit unsigned) value of the instruction. // //===----------------------------------------------------------------------===// @@ -152,7 +154,7 @@ << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; // Shift the value to the correct place (according to place in inst) - assert(endBitInInst >= 0 && "Negative shift amount in inst position!"); + assert(endBitInInst >= 0 && "Negative shift amount!"); if (endBitInInst != 0) o << " op" << OpOrder[Vals[i].getName()] << " <<= " << endBitInInst << ";\n"; From lattner at cs.uiuc.edu Wed Aug 4 17:26:26 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 17:26:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200408042226.RAA17017@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.100 -> 1.101 --- Log message: Add a hack to work around a problem my changes exposed --- Diffs of the changes: (+7 -0) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.100 llvm/lib/VMCore/Constants.cpp:1.101 --- llvm/lib/VMCore/Constants.cpp:1.100 Wed Aug 4 13:50:09 2004 +++ llvm/lib/VMCore/Constants.cpp Wed Aug 4 17:26:13 2004 @@ -608,6 +608,13 @@ void remove(ConstantClass *CP) { MapIterator I = Map.find(MapKey((TypeClass*)CP->getRawType(), getValType(CP))); + if (I == Map.end() || I->second != CP) { + // FIXME: This should not use a linear scan. If this gets to be a + // performance problem, someone should look at this. + for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) + /* empty */; + } + assert(I != Map.end() && "Constant not found in constant table!"); assert(I->second == CP && "Didn't find correct element?"); From lattner at cs.uiuc.edu Wed Aug 4 17:29:17 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 17:29:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408042229.RAA19264@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.81 -> 1.82 --- Log message: Fix a typeo --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.81 llvm/lib/VMCore/Linker.cpp:1.82 --- llvm/lib/VMCore/Linker.cpp:1.81 Wed Aug 4 03:30:43 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 17:29:05 2004 @@ -605,7 +605,7 @@ // visible symbol, DF must be an existing function with internal linkage. // Rename it. if (NewDF->getName() != SF->getName() && !NewDF->hasInternalLinkage()) - ForceRenaming(DF, SF->getName()); + ForceRenaming(NewDF, SF->getName()); // ... and remember this mapping... ValueMap.insert(std::make_pair(SF, NewDF)); From lattner at cs.uiuc.edu Wed Aug 4 17:40:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 17:40:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Linker.cpp Message-ID: <200408042240.RAA20249@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Linker.cpp updated: 1.82 -> 1.83 --- Log message: Fix another minor problem that exists if you ahve multiple functions with nonunifiable types but the same name. Down with PR411: http://llvm.cs.uiuc.edu/PR411 ! --- Diffs of the changes: (+18 -15) Index: llvm/lib/VMCore/Linker.cpp diff -u llvm/lib/VMCore/Linker.cpp:1.82 llvm/lib/VMCore/Linker.cpp:1.83 --- llvm/lib/VMCore/Linker.cpp:1.82 Wed Aug 4 17:29:05 2004 +++ llvm/lib/VMCore/Linker.cpp Wed Aug 4 17:39:54 2004 @@ -24,7 +24,6 @@ #include "llvm/Instructions.h" #include "llvm/Assembly/Writer.h" #include - using namespace llvm; // Error - Simple wrapper function to conditionally assign to E and return true. @@ -406,14 +405,16 @@ const GlobalVariable *SGV = I; GlobalVariable *DGV = 0; // Check to see if may have to link the global. - if (SGV->hasName() && !SGV->hasInternalLinkage()) { - std::map::iterator EGV = - GlobalsByName.find(SGV->getName()); - if (EGV != GlobalsByName.end()) - DGV = dyn_cast(EGV->second); - if (DGV && RecursiveResolveTypes(SGV->getType(), DGV->getType(), ST, "")) - DGV = 0; // FIXME: gross. - } + if (SGV->hasName() && !SGV->hasInternalLinkage()) + if (!(DGV = Dest->getGlobalVariable(SGV->getName(), + SGV->getType()->getElementType()))) { + std::map::iterator EGV = + GlobalsByName.find(SGV->getName()); + if (EGV != GlobalsByName.end()) + DGV = dyn_cast(EGV->second); + if (DGV && RecursiveResolveTypes(SGV->getType(), DGV->getType(), ST, "")) + DGV = 0; // FIXME: gross. + } assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && "Global must either be external or have an initializer!"); @@ -587,12 +588,14 @@ Function *DF = 0; if (SF->hasName() && !SF->hasInternalLinkage()) { // Check to see if may have to link the function. - std::map::iterator EF = - GlobalsByName.find(SF->getName()); - if (EF != GlobalsByName.end()) - DF = dyn_cast(EF->second); - if (DF && RecursiveResolveTypes(SF->getType(), DF->getType(), ST, "")) - DF = 0; // FIXME: gross. + if (!(DF = Dest->getFunction(SF->getName(), SF->getFunctionType()))) { + std::map::iterator EF = + GlobalsByName.find(SF->getName()); + if (EF != GlobalsByName.end()) + DF = dyn_cast(EF->second); + if (DF && RecursiveResolveTypes(SF->getType(), DF->getType(), ST, "")) + DF = 0; // FIXME: gross. + } } if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { From reid at x10sys.com Wed Aug 4 17:56:56 2004 From: reid at x10sys.com (Reid Spencer) Date: Wed, 4 Aug 2004 17:56:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp ReaderWrappers.cpp Message-ID: <200408042256.RAA26031@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.122 -> 1.123 ReaderWrappers.cpp updated: 1.25 -> 1.26 --- Log message: Turn a use of intptr_t into a reinterpret_cast instead to get rid of compilation warnings on some platforms. --- Diffs of the changes: (+3 -2) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.122 llvm/lib/Bytecode/Reader/Reader.cpp:1.123 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.122 Tue Aug 3 19:19:23 2004 +++ llvm/lib/Bytecode/Reader/Reader.cpp Wed Aug 4 17:56:46 2004 @@ -462,7 +462,8 @@ error("Corrupt compaction table entry!" + utostr(TyID) + ", " + utostr(SlotNo) + ": " + utostr(ModuleValues.size()) + ", " - + utohexstr(intptr_t((void*)ModuleValues[TyID])) + ", " + + utohexstr(reinterpret_cast(((void*)ModuleValues[TyID]))) + + ", " + utostr(ModuleValues[TyID]->size())); } return ModuleValues[TyID]->getOperand(SlotNo); Index: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp diff -u llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.25 llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.26 --- llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.25 Sun Jul 4 19:57:50 2004 +++ llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Wed Aug 4 17:56:46 2004 @@ -102,7 +102,7 @@ { // If not aligned, allocate a new buffer to hold the bytecode... const unsigned char *ParseBegin = 0; - if ((intptr_t)Buf & 3) { + if (reinterpret_cast(Buf) & 3) { Buffer = new unsigned char[Length+4]; unsigned Offset = 4 - ((intptr_t)Buffer & 3); // Make sure it's aligned ParseBegin = Buffer + Offset; From lattner at cs.uiuc.edu Wed Aug 4 19:21:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 19:21:03 -0500 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp SJLJ-Exception.h crtend.c Message-ID: <200408050021.TAA23032@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: SJLJ-Exception.cpp updated: 1.3 -> 1.4 SJLJ-Exception.h updated: 1.3 -> 1.4 crtend.c updated: 1.4 -> 1.5 --- Log message: Add missing copyrights --- Diffs of the changes: (+21 -0) Index: llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp diff -u llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp:1.3 llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp:1.4 --- llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp:1.3 Sat Nov 8 18:29:51 2003 +++ llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp Wed Aug 4 19:20:50 2004 @@ -1,4 +1,11 @@ //===- SJLJ-Exception.cpp - SetJmp/LongJmp Exception Handling -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file implements the API used by the Setjmp/Longjmp exception handling // runtime library. Index: llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.h diff -u llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.h:1.3 llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.h:1.4 --- llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.h:1.3 Sat Aug 30 18:18:07 2003 +++ llvm/runtime/GCCLibraries/crtend/SJLJ-Exception.h Wed Aug 4 19:20:50 2004 @@ -1,4 +1,11 @@ //===- SJLJ-Exception.h - SetJmp/LongJmp Exception Handling -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines the data structures and API used by the Setjmp/Longjmp // exception handling runtime library. Index: llvm/runtime/GCCLibraries/crtend/crtend.c diff -u llvm/runtime/GCCLibraries/crtend/crtend.c:1.4 llvm/runtime/GCCLibraries/crtend/crtend.c:1.5 --- llvm/runtime/GCCLibraries/crtend/crtend.c:1.4 Tue Feb 17 12:45:06 2004 +++ llvm/runtime/GCCLibraries/crtend/crtend.c Wed Aug 4 19:20:51 2004 @@ -1,4 +1,11 @@ /*===- crtend.c - Initialization code for programs ------------------------===*\ + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===* * * This file defines the __main function, which is used to run static * constructors and destructors in C++ programs, or with C programs that use GCC From lattner at cs.uiuc.edu Wed Aug 4 21:26:46 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 21:26:46 -0500 Subject: [llvm-commits] CVS: llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.cc C++-Exception.h Exception.h Makefile.am Makefile.in Message-ID: <200408050226.VAA09908@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/libstdc++-v3/libsupc++: C++-Exception.cc added (r1.1) C++-Exception.h added (r1.1) Exception.h added (r1.1) Makefile.am updated: 1.1.1.2 -> 1.2 Makefile.in updated: 1.3 -> 1.4 --- Log message: Fix the problems that people are having when llvmgcc is configured with -disable-shared. This just moves the file in question from crtend.a to libstdc++. Since this REALLY IS part of the C++ runtime, this makes plenty of sense, though it's kinda nasty from the code duplication perspective. I would appreciate it if people could test this out. --- Diffs of the changes: (+528 -4) Index: llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.cc diff -c /dev/null llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.cc:1.1 *** /dev/null Wed Aug 4 21:26:44 2004 --- llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.cc Wed Aug 4 21:26:33 2004 *************** *** 0 **** --- 1,365 ---- + //===- C++-Exception.cc - Exception handling support for C++ exceptions ---===// + // + // This file defines the methods used to implement C++ exception handling in + // terms of the invoke and %llvm.unwind intrinsic. These primitives implement + // an exception handling ABI similar (but simpler and more efficient than) the + // Itanium C++ ABI exception handling standard. + // + // NOTE NOTE NOTE: A copy of this file lives in llvm/runtime/GCCLibraries/crtend + // Any modifications to this file must keep it in sync! + // + //===----------------------------------------------------------------------===// + + #include "C++-Exception.h" + #include + #include + + //#define DEBUG + + #ifdef DEBUG + #include + #endif + + // LastCaughtException - The last exception caught by this handler. This is for + // implementation of _rethrow and _get_last_caught. + // + // FIXME: This should be thread-local! + // + static llvm_exception *LastCaughtException = 0; + + + using namespace __cxxabiv1; + + // __llvm_cxxeh_allocate_exception - This function allocates space for the + // specified number of bytes, plus a C++ exception object header. + // + void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) throw() { + // FIXME: This should eventually have back-up buffers for out-of-memory + // situations. + // + llvm_cxx_exception *E = + (llvm_cxx_exception *)malloc(NumBytes+sizeof(llvm_cxx_exception)); + E->BaseException.ExceptionType = 0; // initialize to invalid + + return E+1; // return the pointer after the header + } + + // __llvm_cxxeh_free_exception - Low-level function to free an exception. This + // is called directly from generated C++ code if evaluating the exception value + // into the exception location throws. Otherwise it is called from the C++ + // exception object destructor. + // + void __llvm_cxxeh_free_exception(void *ObjectPtr) throw() { + llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + free(E); + } + + // cxx_destructor - This function is called through the generic + // exception->ExceptionDestructor function pointer to destroy a caught + // exception. + // + static void cxx_destructor(llvm_exception *LE) /* might throw */{ + assert(LE->Next == 0 && "On the uncaught stack??"); + llvm_cxx_exception *E = get_cxx_exception(LE); + + struct ExceptionFreer { + void *Ptr; + ExceptionFreer(void *P) : Ptr(P) {} + ~ExceptionFreer() { + // Free the memory for the exception, when the function is left, even if + // the exception object dtor throws its own exception! + __llvm_cxxeh_free_exception(Ptr); + } + } EF(E+1); + + // Run the exception object dtor if it exists. */ + if (E->ExceptionObjectDestructor) + E->ExceptionObjectDestructor(E+1); + } + + // __llvm_cxxeh_throw - Given a pointer to memory which has an exception object + // evaluated into it, this sets up all of the fields of the exception allowing + // it to be thrown. After calling this, the code should call %llvm.unwind + // + void __llvm_cxxeh_throw(void *ObjectPtr, void *TypeInfoPtr, + void (*DtorPtr)(void*)) throw() { + llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + E->BaseException.ExceptionDestructor = cxx_destructor; + E->BaseException.ExceptionType = CXXException; + E->BaseException.HandlerCount = 0; + E->BaseException.isRethrown = 0; + + E->TypeInfo = (const std::type_info*)TypeInfoPtr; + E->ExceptionObjectDestructor = DtorPtr; + E->UnexpectedHandler = __unexpected_handler; + E->TerminateHandler = __terminate_handler; + + __llvm_eh_add_uncaught_exception(&E->BaseException); + } + + + // CXXExceptionISA - use the type info object stored in the exception to see if + // TypeID matches and, if so, to adjust the exception object pointer. + // + static void *CXXExceptionISA(llvm_cxx_exception *E, + const std::type_info *Type) throw() { + // ThrownPtr is a pointer to the object being thrown... + void *ThrownPtr = E+1; + const std::type_info *ThrownType = E->TypeInfo; + + #if 0 + // FIXME: this code exists in the GCC exception handling library: I haven't + // thought about this yet, so it should be verified at some point! + + // Pointer types need to adjust the actual pointer, not + // the pointer to pointer that is the exception object. + // This also has the effect of passing pointer types + // "by value" through the __cxa_begin_catch return value. + if (ThrownType->__is_pointer_p()) + ThrownPtr = *(void **)ThrownPtr; + #endif + + if (Type->__do_catch(ThrownType, &ThrownPtr, 1)) { + #ifdef DEBUG + printf("isa<%s>(%s): 0x%p -> 0x%p\n", Type->name(), ThrownType->name(), + E+1, ThrownPtr); + #endif + return ThrownPtr; + } + + return 0; + } + + // __llvm_cxxeh_current_uncaught_exception_isa - This function checks to see if + // the current uncaught exception is a C++ exception, and if it is of the + // specified type id. If so, it returns a pointer to the object adjusted as + // appropriate, otherwise it returns null. + // + void *__llvm_cxxeh_current_uncaught_exception_isa(void *CatchType) throw() { + void *EPtr = __llvm_eh_current_uncaught_exception_type(CXXException); + if (EPtr == 0) return 0; // If it's not a c++ exception, it doesn't match! + + // If it is a C++ exception, use the type info object stored in the exception + // to see if TypeID matches and, if so, to adjust the exception object + // pointer. + // + const std::type_info *Info = (const std::type_info *)CatchType; + return CXXExceptionISA((llvm_cxx_exception*)EPtr - 1, Info); + } + + + // __llvm_cxxeh_begin_catch - This function is called by "exception handlers", + // which transition an exception from being uncaught to being caught. It + // returns a pointer to the exception object portion of the exception. This + // function must work with foreign exceptions. + // + void *__llvm_cxxeh_begin_catch() throw() { + llvm_exception *E = __llvm_eh_pop_from_uncaught_stack(); + + // The exception is now caught. + LastCaughtException = E; + E->Next = 0; + E->isRethrown = 0; + + // Increment the handler count for this exception. + E->HandlerCount++; + + #ifdef DEBUG + printf("Exiting begin_catch Ex=0x%p HandlerCount=%d!\n", E+1, + E->HandlerCount); + #endif + + // Return a pointer to the raw exception object. + return E+1; + } + + // __llvm_cxxeh_begin_catch_if_isa - This function checks to see if the current + // uncaught exception is of the specified type. If not, it returns a null + // pointer, otherwise it 'catches' the exception and returns a pointer to the + // object of the specified type. This function does never succeeds with foreign + // exceptions (because they can never be of type CatchType). + // + void *__llvm_cxxeh_begin_catch_if_isa(void *CatchType) throw() { + void *ObjPtr = __llvm_cxxeh_current_uncaught_exception_isa(CatchType); + if (!ObjPtr) return 0; + + // begin_catch, meaning that the object is now "caught", not "uncaught" + __llvm_cxxeh_begin_catch(); + return ObjPtr; + } + + // __llvm_cxxeh_get_last_caught - Return the last exception that was caught by + // ...begin_catch. + // + void *__llvm_cxxeh_get_last_caught() throw() { + assert(LastCaughtException && "No exception caught!!"); + return LastCaughtException+1; + } + + // __llvm_cxxeh_end_catch - This function decrements the HandlerCount of the + // top-level caught exception, destroying it if this is the last handler for the + // exception. + // + void __llvm_cxxeh_end_catch(void *Ex) /* might throw */ { + llvm_exception *E = (llvm_exception*)Ex - 1; + assert(E && "There are no caught exceptions!"); + + // If this is the last handler using the exception, destroy it now! + if (--E->HandlerCount == 0 && !E->isRethrown) { + #ifdef DEBUG + printf("Destroying exception!\n"); + #endif + E->ExceptionDestructor(E); // Release memory for the exception + } + #ifdef DEBUG + printf("Exiting end_catch Ex=0x%p HandlerCount=%d!\n", Ex, E->HandlerCount); + #endif + } + + // __llvm_cxxeh_call_terminate - This function is called when the dtor for an + // object being destroyed due to an exception throw throws an exception. This + // is illegal because it would cause multiple exceptions to be active at one + // time. + void __llvm_cxxeh_call_terminate() throw() { + void (*Handler)(void) = __terminate_handler; + if (__llvm_eh_has_uncaught_exception()) + if (void *EPtr = __llvm_eh_current_uncaught_exception_type(CXXException)) + Handler = ((llvm_cxx_exception*)EPtr - 1)->TerminateHandler; + __terminate(Handler); + } + + + // __llvm_cxxeh_rethrow - This function turns the top-level caught exception + // into an uncaught exception, in preparation for an llvm.unwind, which should + // follow immediately after the call to this function. This function must be + // prepared to deal with foreign exceptions. + // + void __llvm_cxxeh_rethrow() throw() { + llvm_exception *E = LastCaughtException; + if (E == 0) + // 15.1.8 - If there are no exceptions being thrown, 'throw;' should call + // terminate. + // + __terminate(__terminate_handler); + + // Otherwise we have an exception to rethrow. Mark the exception as such. + E->isRethrown = 1; + + // Add the exception to the top of the uncaught stack, to preserve the + // invariant that the top of the uncaught stack is the current exception. + __llvm_eh_add_uncaught_exception(E); + + // Return to the caller, which should perform the unwind now. + } + + static bool ExceptionSpecificationPermitsException(llvm_exception *E, + const std::type_info *Info, + va_list Args) { + // The only way it could match one of the types is if it is a C++ exception. + if (E->ExceptionType != CXXException) return false; + + llvm_cxx_exception *Ex = get_cxx_exception(E); + + // Scan the list of accepted types, checking to see if the uncaught + // exception is any of them. + do { + // Check to see if the exception matches one of the types allowed by the + // exception specification. If so, return to the caller to have the + // exception rethrown. + if (CXXExceptionISA(Ex, Info)) + return true; + + Info = va_arg(Args, std::type_info *); + } while (Info); + return false; + } + + + // __llvm_cxxeh_check_eh_spec - If a function with an exception specification is + // throwing an exception, this function gets called with the list of type_info + // objects that it is allowing to propagate. Check to see if the current + // uncaught exception is one of these types, and if so, allow it to be thrown by + // returning to the caller, which should immediately follow this call with + // llvm.unwind. + // + // Note that this function does not throw any exceptions, but we can't put an + // exception specification on it or else we'll get infinite loops! + // + void __llvm_cxxeh_check_eh_spec(void *Info, ...) { + const std::type_info *TypeInfo = (const std::type_info *)Info; + + if (TypeInfo == 0) { // Empty exception specification + // Whatever exception this is, it is not allowed by the (empty) spec, call + // unexpected, according to 15.4.8. + try { + void *Ex = __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(Ex); // Free the exception + __unexpected(__unexpected_handler); + } catch (...) { + // Any exception thrown by unexpected cannot match the ehspec. Call + // terminate, according to 15.4.9. + __terminate(__terminate_handler); + } + } + + llvm_exception *E = __llvm_eh_get_uncaught_exception(); + assert(E && "No uncaught exceptions!"); + + // Check to see if the exception matches one of the types allowed by the + // exception specification. If so, return to the caller to have the + // exception rethrown. + + va_list Args; + va_start(Args, Info); + bool Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Ok, now we know that the exception is either not a C++ exception (thus not + // permitted to pass through) or not a C++ exception that is allowed. Kill + // the exception and call the unexpected handler. + try { + void *Ex = __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(Ex); // Free the exception + } catch (...) { + __terminate(__terminate_handler); // Exception dtor threw + } + + try { + __unexpected(__unexpected_handler); + } catch (...) { + // If the unexpected handler threw an exception, we will get here. Since + // entering the try block calls ..._begin_catch, we need to "rethrow" the + // exception to make it uncaught again. Exiting the catch will then leave + // it in the uncaught state. + __llvm_cxxeh_rethrow(); + } + + // Grab the newly caught exception. If this exception is permitted by the + // specification, allow it to be thrown. + E = __llvm_eh_get_uncaught_exception(); + + va_start(Args, Info); + Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Final case, check to see if we can throw an std::bad_exception. + try { + throw std::bad_exception(); + } catch (...) { + __llvm_cxxeh_rethrow(); + } + + // Grab the new bad_exception... + E = __llvm_eh_get_uncaught_exception(); + + // If it's permitted, allow it to be thrown instead. + va_start(Args, Info); + Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Otherwise, we are out of options, terminate, according to 15.5.2.2. + __terminate(__terminate_handler); + } Index: llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.h diff -c /dev/null llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.h:1.1 *** /dev/null Wed Aug 4 21:26:46 2004 --- llvm-gcc/libstdc++-v3/libsupc++/C++-Exception.h Wed Aug 4 21:26:33 2004 *************** *** 0 **** --- 1,92 ---- + //===- C++-Exception.h - C++ Specific Exception Handling --------*- C++ -*-===// + // + // This file defines the data structures and API used by the C++ exception + // handling runtime library. + // + // NOTE NOTE NOTE: A copy of this file lives in llvm/runtime/GCCLibraries/crtend + // Any modifications to this file must keep it in sync! + // + //===----------------------------------------------------------------------===// + + #ifndef CXX_EXCEPTION_H + #define CXX_EXCEPTION_H + + #include "Exception.h" + #include + #include + + // Assert should only be used for debugging the runtime library. Enabling it in + // CVS will break some platforms! + #undef assert + #define assert(X) + + struct llvm_cxx_exception { + // TypeInfo - A pointer to the C++ std::type_info object for this exception + // class. This is required because the class may not be polymorphic. + // + const std::type_info *TypeInfo; + + // ExceptionObjectDestructor - A pointer to the function which destroys the + // object represented by this exception. This is required because the class + // may not be polymorphic. This may be null if there is no cleanup required. + // + void (*ExceptionObjectDestructor)(void *); + + // UnexpectedHandler - This contains a pointer to the "unexpected" handler + // which may be registered by the user program with set_unexpected. Calls to + // unexpected which are a result of an exception throw are supposed to use the + // value of the handler at the time of the throw, not the currently set value. + // + void (*UnexpectedHandler)(); + + // TerminateHandler - This contains a pointer to the "terminate" handler which + // may be registered by the user program with set_terminate. Calls to + // unexpected which are a result of an exception throw are supposed to use the + // value of the handler at the time of the throw, not the currently set value. + // + void (*TerminateHandler)(); + + // BaseException - The language independent portion of the exception state. + // This is at the end of the record so that we can add additional members to + // this structure without breaking binary compatibility. + // + llvm_exception BaseException; + }; + + inline llvm_cxx_exception *get_cxx_exception(llvm_exception *E) throw() { + assert(E->ExceptionType == CXXException && "Not a C++ exception?"); + return (llvm_cxx_exception*)(E+1)-1; + } + + // Interface to the C++ standard library to get to the terminate and unexpected + // handler stuff. + namespace __cxxabiv1 { + // Invokes given handler, dying appropriately if the user handler was + // so inconsiderate as to return. + extern void __terminate(std::terminate_handler) throw() __attribute__((noreturn)); + extern void __unexpected(std::unexpected_handler) __attribute__((noreturn)); + + // The current installed user handlers. + extern std::terminate_handler __terminate_handler; + extern std::unexpected_handler __unexpected_handler; + } + + extern "C" { + void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) throw(); + void __llvm_cxxeh_free_exception(void *ObjectPtr) throw(); + void __llvm_cxxeh_throw(void *ObjectPtr, void *TypeInfoPtr, + void (*DtorPtr)(void*)) throw(); + + void __llvm_cxxeh_call_terminate() throw() __attribute__((noreturn)); + void * __llvm_cxxeh_current_uncaught_exception_isa(void *Ty) + throw(); + void *__llvm_cxxeh_begin_catch() throw(); + void *__llvm_cxxeh_begin_catch_if_isa(void *CatchType) throw(); + void __llvm_cxxeh_end_catch(void *Exception) /* might throw */; + void __llvm_cxxeh_rethrow() throw(); + void *__llvm_cxxeh_get_last_caught() throw(); + + void __llvm_cxxeh_check_eh_spec(void *Info, ...); + } + + #endif Index: llvm-gcc/libstdc++-v3/libsupc++/Exception.h diff -c /dev/null llvm-gcc/libstdc++-v3/libsupc++/Exception.h:1.1 *** /dev/null Wed Aug 4 21:26:46 2004 --- llvm-gcc/libstdc++-v3/libsupc++/Exception.h Wed Aug 4 21:26:33 2004 *************** *** 0 **** --- 1,64 ---- + //===- Exception.h - Generic language-independent exceptions ----*- C++ -*-===// + // + // This file defines the the shared data structures used by all language + // specific exception handling runtime libraries. + // + // NOTE NOTE NOTE: A copy of this file lives in llvm/runtime/GCCLibraries/crtend + // Any modifications to this file must keep it in sync! + // + //===----------------------------------------------------------------------===// + + #ifndef EXCEPTION_H + #define EXCEPTION_H + + struct llvm_exception { + // ExceptionDestructor - This call-back function is used to destroy the + // current exception, without requiring the caller to know what the concrete + // exception type is. + // + void (*ExceptionDestructor)(llvm_exception *); + + // ExceptionType - This field identifies what runtime library this exception + // came from. Currently defined values are: + // 0 - Error + // 1 - longjmp exception (see longjmp-exception.c) + // 2 - C++ exception (see c++-exception.c) + // + unsigned ExceptionType; + + // Next - This points to the next exception in the current stack. + llvm_exception *Next; + + // HandlerCount - This is a count of the number of handlers which have + // currently caught this exception. If the handler is caught and this number + // falls to zero, the exception is destroyed. + // + unsigned HandlerCount; + + // isRethrown - This field is set on an exception if it has been 'throw;'n. + // This is needed because the exception might exit through a number of the + // end_catch statements matching the number of begin_catch statements that + // have been processed. When this happens, the exception should become + // uncaught, not dead. + // + int isRethrown; + }; + + enum { + ErrorException = 0, + SJLJException = 1, + CXXException = 2, + }; + + // Language independent exception handling API... + // + extern "C" { + bool __llvm_eh_has_uncaught_exception() throw(); + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw(); + void __llvm_eh_add_uncaught_exception(llvm_exception *E) throw(); + + llvm_exception *__llvm_eh_get_uncaught_exception() throw(); + llvm_exception *__llvm_eh_pop_from_uncaught_stack() throw(); + } + + #endif Index: llvm-gcc/libstdc++-v3/libsupc++/Makefile.am diff -u llvm-gcc/libstdc++-v3/libsupc++/Makefile.am:1.1.1.2 llvm-gcc/libstdc++-v3/libsupc++/Makefile.am:1.2 --- llvm-gcc/libstdc++-v3/libsupc++/Makefile.am:1.1.1.2 Tue Jan 13 10:52:34 2004 +++ llvm-gcc/libstdc++-v3/libsupc++/Makefile.am Wed Aug 4 21:26:33 2004 @@ -32,9 +32,11 @@ headers = \ - exception new typeinfo cxxabi.h exception_defines.h + exception new typeinfo cxxabi.h exception_defines.h \ + C++-Exception.h Exception.h sources = \ + C++-Exception.cc \ del_op.cc \ del_opnt.cc \ del_opv.cc \ Index: llvm-gcc/libstdc++-v3/libsupc++/Makefile.in diff -u llvm-gcc/libstdc++-v3/libsupc++/Makefile.in:1.3 llvm-gcc/libstdc++-v3/libsupc++/Makefile.in:1.4 --- llvm-gcc/libstdc++-v3/libsupc++/Makefile.in:1.3 Thu Feb 5 10:05:49 2004 +++ llvm-gcc/libstdc++-v3/libsupc++/Makefile.in Wed Aug 4 21:26:33 2004 @@ -227,10 +227,11 @@ noinst_LTLIBRARIES = libsupc++convenience.la headers = \ - exception new typeinfo cxxabi.h exception_defines.h - + exception new typeinfo cxxabi.h exception_defines.h \ + C++-Exception.h Exception.h sources = \ + C++-Exception.cc \ del_op.cc \ del_opnt.cc \ del_opv.cc \ @@ -326,7 +327,7 @@ libsupc___la_LDFLAGS = libsupc___la_LIBADD = -am__objects_1 = del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \ +am__objects_1 = C++-Exception.lo del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \ eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo \ eh_globals.lo eh_personality.lo eh_term_handler.lo \ eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \ From lattner at cs.uiuc.edu Wed Aug 4 21:27:40 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 21:27:40 -0500 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Exception.h C++-Exception.cpp C++-Exception.h Message-ID: <200408050227.VAA09948@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Exception.h updated: 1.7 -> 1.8 C++-Exception.cpp (r1.11) removed C++-Exception.h (r1.9) removed --- Log message: Two files are moved to libstdc++, and a NOTE gets added --- Diffs of the changes: (+10 -0) Index: llvm/runtime/GCCLibraries/crtend/Exception.h diff -u llvm/runtime/GCCLibraries/crtend/Exception.h:1.7 llvm/runtime/GCCLibraries/crtend/Exception.h:1.8 --- llvm/runtime/GCCLibraries/crtend/Exception.h:1.7 Sat Aug 30 18:29:08 2003 +++ llvm/runtime/GCCLibraries/crtend/Exception.h Wed Aug 4 21:27:28 2004 @@ -1,8 +1,18 @@ //===- Exception.h - Generic language-independent exceptions ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines the the shared data structures used by all language // specific exception handling runtime libraries. // +// NOTE NOTE NOTE: A copy of this file lives in llvmgcc/libstdc++-v3/libsupc++/ +// Any modifications to this file must keep it in sync! +// //===----------------------------------------------------------------------===// #ifndef EXCEPTION_H From lattner at cs.uiuc.edu Wed Aug 4 21:28:29 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Aug 2004 21:28:29 -0500 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Makefile Message-ID: <200408050228.VAA10200@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Makefile updated: 1.14 -> 1.15 --- Log message: C++ support does not live in the C runtime any longer --- Diffs of the changes: (+1 -6) Index: llvm/runtime/GCCLibraries/crtend/Makefile diff -u llvm/runtime/GCCLibraries/crtend/Makefile:1.14 llvm/runtime/GCCLibraries/crtend/Makefile:1.15 --- llvm/runtime/GCCLibraries/crtend/Makefile:1.14 Thu Mar 11 14:55:23 2004 +++ llvm/runtime/GCCLibraries/crtend/Makefile Wed Aug 4 21:28:17 2004 @@ -39,7 +39,7 @@ # The four components described in the README -Components := main genericeh sjljeh cxxeh +Components := main genericeh sjljeh ComponentLibs := $(Components:%=$(BUILD_OBJ_DIR)/BytecodeObj/comp_%.bc) @@ -69,9 +69,4 @@ @echo Linking $(notdir $@) component... $(VERB) $(LGCCLDPROG) -link-as-library -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_sjljeh.lst $(SJLJEHObj) -o $@ -# C++ exception handling support runtime. -$(BUILD_OBJ_DIR)/BytecodeObj/comp_cxxeh.bc: $(CXXEHObj) - @echo Linking $(notdir $@) component... - $(VERB) $(LGCCLDPROG) -link-as-library -internalize-public-api-file=$(BUILD_SRC_DIR)/comp_cxxeh.lst $(CXXEHObj) -o $@ - From gaeke at cs.uiuc.edu Thu Aug 5 00:17:33 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu, 5 Aug 2004 00:17:33 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/tools/llvm-db/Makefile Message-ID: <200408050517.AAA05024@kain.cs.uiuc.edu> Changes in directory llvm/tools/llvm-db: Makefile updated: 1.2 -> 1.3 --- Log message: sparcv9select is history. --- Diffs of the changes: (+1 -1) Index: llvm/tools/llvm-db/Makefile diff -u llvm/tools/llvm-db/Makefile:1.2 llvm/tools/llvm-db/Makefile:1.3 --- llvm/tools/llvm-db/Makefile:1.2 Wed Feb 25 13:08:12 2004 +++ llvm/tools/llvm-db/Makefile Thu Aug 5 00:17:19 2004 @@ -44,7 +44,7 @@ JITLIBS += sparcv9 ARCHLIBS += sched sparcv9livevar instrument.a profpaths \ bcwriter transforms.a ipo.a ipa.a datastructure.a \ - sparcv9regalloc sparcv9select + sparcv9regalloc endif USEDLIBS = lli-interpreter $(JITLIBS) $(ARCHLIBS) scalaropts analysis.a \ From gaeke at cs.uiuc.edu Thu Aug 5 01:11:22 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu, 5 Aug 2004 01:11:22 -0500 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200408050611.BAA01716@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.106 -> 1.107 --- Log message: Include-file shuffle --- Diffs of the changes: (+2 -2) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.106 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.107 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.106 Thu Jul 29 23:04:44 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Thu Aug 5 01:11:11 2004 @@ -16,7 +16,6 @@ #include "reopt/UnpackTraceFunction.h" #include "reopt/TraceToFunction.h" #include "reopt/MappingInfo.h" // for getBasicBlockInfo() -#include "llvm/CodeGen/InstrSelection.h" // for TmpInstruction #include "llvm/CodeGen/MachineFunctionInfo.h" // for getStaticStackSize() #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/Support/CFG.h" @@ -28,7 +27,8 @@ #include "../../../../lib/Target/SparcV9/RegAlloc/AllocInfo.h" #include "../../../../lib/Target/SparcV9/SparcV9RegInfo.h" #include "../../../../lib/Target/SparcV9/SparcV9TargetMachine.h" -#include "../../../../lib/Target/SparcV9/SparcV9InstrSelectionSupport.h" +#include "../../../../lib/Target/SparcV9/SparcV9TmpInstr.h" +#include "../../../../lib/Target/SparcV9/SparcV9BurgISel.h" namespace llvm { From gaeke at cs.uiuc.edu Thu Aug 5 01:44:14 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu, 5 Aug 2004 01:44:14 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/lib/TraceToFunction/TraceToFunction.cpp Message-ID: <200408050644.BAA29048@seraph.cs.uiuc.edu> Changes in directory reopt/lib/TraceToFunction: TraceToFunction.cpp updated: 1.83 -> 1.84 --- Log message: This old dominates() function can go, now that we have a DominatorSet. --- Diffs of the changes: (+3 -31) Index: reopt/lib/TraceToFunction/TraceToFunction.cpp diff -u reopt/lib/TraceToFunction/TraceToFunction.cpp:1.83 reopt/lib/TraceToFunction/TraceToFunction.cpp:1.84 --- reopt/lib/TraceToFunction/TraceToFunction.cpp:1.83 Wed Aug 4 00:28:02 2004 +++ reopt/lib/TraceToFunction/TraceToFunction.cpp Thu Aug 5 01:44:02 2004 @@ -114,28 +114,6 @@ virtual bool runOnFunction (Function &F); }; -static bool dominates (Trace &T, const BasicBlock *B1, - const BasicBlock *B2, const BasicBlock *start = 0) { - if (!start) - start = T.getEntryBasicBlock (); - if (start == B1) { - return true; // Seen B1 on this path, if we see B2 later it's OK. - } else if (start == B2) { - return false; // Seen B2, w/o seeing B1 earlier on this path. Not OK. - } else { - // If any successors are on the trace, AND not the entry BB, check them too. - // (Stop at entry BB because we don't want to loop if the CFG loops.) - for (succ_const_iterator i = succ_begin (start), e = succ_end (start); - i != e; ++i) { - const BasicBlock *succ = *i; - if (T.contains (succ) && (T.getEntryBasicBlock () != succ) - && (!dominates (T, B1, B2, succ))) - return false; - } - return true; // Dominates on all successors ==> dominates here too - } -} - static bool DefinedInTraceBeforeUse (Value *V, Trace &T, Trace::iterator Start, bool ignoreOffTraceUsers) { Instruction *Inst = dyn_cast (V); if (!Inst) { @@ -186,14 +164,6 @@ } else { DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " is off-trace, but we don't care\n"); } - } else { - // If UBlock appears BEFORE Block on some path from the first - // basic block of the trace to an exit BB of the trace, return - // false. - if (!dominates (T, Block, UBlock, *Start)) { - DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " not dominated by Def!\n"); - return false; - } } } } @@ -284,6 +254,8 @@ // Find the position of the block in the trace. Trace::iterator StartingFrom = std::find (T.begin (), T.end (), *i); assert (StartingFrom != T.end () && "AlternateEntryPoint not on trace?!"); + DEBUG (std::cerr << "TLV: adding trace live-ins starting from alt. entry " + << (*i)->getName () << " as live-out\n"); addTraceLiveInsToSet (S, LVV, T, StartingFrom); } } @@ -799,7 +771,7 @@ Value *V = *SI; bool storeIt = true; if (Instruction *Inst = dyn_cast (V)) - storeIt = dominates (T, Inst->getParent (), BI->getParent ()); + storeIt = DS->dominates (Inst, BI); else // it's an Argument, so it must dominate the store. assert (isa (V) && "not instruction, not argument??"); if (storeIt) From gaeke at cs.uiuc.edu Thu Aug 5 02:13:00 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu, 5 Aug 2004 02:13:00 -0500 (CDT) Subject: [llvm-commits] CVS: reopt/test/TEST.reopt.Makefile Message-ID: <200408050713.CAA17617@kain.cs.uiuc.edu> Changes in directory reopt/test: TEST.reopt.Makefile updated: 1.19 -> 1.20 --- Log message: sparcv9select.o is history. --- Diffs of the changes: (+1 -1) Index: reopt/test/TEST.reopt.Makefile diff -u reopt/test/TEST.reopt.Makefile:1.19 reopt/test/TEST.reopt.Makefile:1.20 --- reopt/test/TEST.reopt.Makefile:1.19 Tue Jul 6 13:15:40 2004 +++ reopt/test/TEST.reopt.Makefile Thu Aug 5 02:12:50 2004 @@ -34,7 +34,7 @@ # Object files that contain common LLVM code the Reoptimizer depends on REOPTIMIZER_LLVMOBJS = $(DESTLIBCURRENT)/vmcore.o \ $(DESTLIBCURRENT)/bcreader.o $(DESTLIBCURRENT)/bcwriter.o \ - $(DESTLIBCURRENT)/sparcv9.o $(DESTLIBCURRENT)/sparcv9select.o \ + $(DESTLIBCURRENT)/sparcv9.o \ $(DESTLIBCURRENT)/sparcv9livevar.o $(DESTLIBCURRENT)/sched.o \ $(DESTLIBCURRENT)/codegen.o $(DESTLIBCURRENT)/executionengine.o \ $(DESTLIBCURRENT)/lli-jit.o $(DESTLIBCURRENT)/lli-interpreter.o From reid at x10sys.com Thu Aug 5 02:23:58 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 5 Aug 2004 02:23:58 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c Message-ID: <200408050723.CAA17213@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main: object.c updated: 1.3 -> 1.4 --- Log message: Use an epsilon test when comparing floating point values so that points that are "really close" will be counted as the same point. This fixes a problem with this test that caused the CBE to insert extra points that the other test modes did not. --- Diffs of the changes: (+10 -3) Index: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c diff -u llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.3 llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.4 --- llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.3 Wed Aug 13 15:42:47 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c Thu Aug 5 02:23:48 2004 @@ -50,6 +50,11 @@ o->Origin.z = 0; return (ObjPtr)o; } + +int FPEqual(double d1, double d2) { + return fabs(d1-d2) < 0.000001L; +} + ObjPointPtr InsertPoint(ObjPtr o, double x, double y, double z) { @@ -82,7 +87,9 @@ tmp = o->Points; /*Iterative search through the pointlist, as long as p==NULL point not found*/ while( ((tmp) != NULL) && (p == NULL) ){ - if( (tmp->P->x == x) && (tmp->P->y == y) && (tmp->P->z == z) ) + if( FPEqual(tmp->P->x,x) && + FPEqual(tmp->P->y,y) && + FPEqual(tmp->P->z,z) ) { /* We found the point in the list */ #ifdef DEBUG_OSYS printf("Found (%2.2f,%2.2f,%2.2f,)\n",x,y,z); @@ -248,8 +255,8 @@ if(o->Points != NULL) tmp = o->Points; while(tmp != NULL) { - printf("Point[%i] = (%.2f, %.2f, %.2f)",i,tmp->P->x,tmp->P->y,tmp->P->z); - printf(" -> (%.2f, %.2f, %.2f)\n",tmp->P->tx,tmp->P->ty,tmp->P->tz); + printf("Point[%i] = (%.2lf, %.2lf, %.2lf)",i,tmp->P->x,tmp->P->y,tmp->P->z); + printf(" -> (%.2lf, %.2lf, %.2lf)\n",tmp->P->tx,tmp->P->ty,tmp->P->tz); ++i; tmp = tmp->NextPoint; }return; From reid at x10sys.com Thu Aug 5 02:29:27 2004 From: reid at x10sys.com (Reid Spencer) Date: Thu, 5 Aug 2004 02:29:27 -0500 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c Message-ID: <200408050729.CAA17806@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main: object.c updated: 1.4 -> 1.5 --- Log message: Make the new function static so GCC will inline it. Also, remove from cruft from earlier testing. --- Diffs of the changes: (+3 -3) Index: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c diff -u llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.4 llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.5 --- llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c:1.4 Thu Aug 5 02:23:48 2004 +++ llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/object.c Thu Aug 5 02:29:17 2004 @@ -51,7 +51,7 @@ return (ObjPtr)o; } -int FPEqual(double d1, double d2) { +static int FPEqual(double d1, double d2) { return fabs(d1-d2) < 0.000001L; } @@ -255,8 +255,8 @@ if(o->Points != NULL) tmp = o->Points; while(tmp != NULL) { - printf("Point[%i] = (%.2lf, %.2lf, %.2lf)",i,tmp->P->x,tmp->P->y,tmp->P->z); - printf(" -> (%.2lf, %.2lf, %.2lf)\n",tmp->P->tx,tmp->P->ty,tmp->P->tz); + printf("Point[%i] = (%.2f, %.2f, %.2f)",i,tmp->P->x,tmp->P->y,tmp->P->z); + printf(" -> (%.2f, %.2f, %.2f)\n",tmp->P->tx,tmp->P->ty,tmp->P->tz); ++i; tmp = tmp->NextPoint; }return; From alkis at cs.uiuc.edu Thu Aug 5 06:28:45 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 5 Aug 2004 06:28:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Globals.cpp Message-ID: <200408051128.GAA30048@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Globals.cpp updated: 1.4 -> 1.5 --- Log message: Make GlobalVariable constructor assert when an initializer is of incorrect type. --- Diffs of the changes: (+5 -1) Index: llvm/lib/VMCore/Globals.cpp diff -u llvm/lib/VMCore/Globals.cpp:1.4 llvm/lib/VMCore/Globals.cpp:1.5 --- llvm/lib/VMCore/Globals.cpp:1.4 Tue Aug 3 21:27:17 2004 +++ llvm/lib/VMCore/Globals.cpp Thu Aug 5 06:28:34 2004 @@ -76,7 +76,11 @@ const std::string &Name, Module *ParentModule) : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Link, Name), isConstantGlobal(constant) { - if (Initializer) Operands.push_back(Use((Value*)Initializer, this)); + if (Initializer) { + assert(Initializer->getType() == Ty && + "Initializer should be the same type as the GlobalVariable!"); + Operands.push_back(Use((Value*)Initializer, this)); + } LeakDetector::addGarbageObject(this); From alkis at cs.uiuc.edu Thu Aug 5 07:54:03 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 5 Aug 2004 07:54:03 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408051254.HAA30529@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.75 -> 1.76 --- Log message: Handle package names in method descriptors. --- Diffs of the changes: (+1 -1) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.75 llvm-java/lib/Compiler/Compiler.cpp:1.76 --- llvm-java/lib/Compiler/Compiler.cpp:1.75 Wed Aug 4 05:20:28 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Thu Aug 5 07:53:53 2004 @@ -431,7 +431,7 @@ std::pair findClassAndMethod(const std::string& classMethodDesc) { - unsigned slash = classMethodDesc.find('/'); + unsigned slash = classMethodDesc.rfind('/', classMethodDesc.find('(')); std::string className = classMethodDesc.substr(0, slash); std::string methodNameAndDescr = classMethodDesc.substr(slash+1); From lattner at cs.uiuc.edu Thu Aug 5 12:45:44 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Aug 2004 12:45:44 -0500 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/comp_cxxeh.lst Message-ID: <200408051745.MAA13633@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: comp_cxxeh.lst (r1.1) removed --- Log message: This file is obsolete --- Diffs of the changes: (+0 -0) From brukman at cs.uiuc.edu Thu Aug 5 13:22:41 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 13:22:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Makefile Message-ID: <200408051822.NAA01893@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.15 -> 1.16 --- Log message: PowerPC is a real target now. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.15 llvm/lib/Target/Makefile:1.16 --- llvm/lib/Target/Makefile:1.15 Fri Jul 16 02:11:53 2004 +++ llvm/lib/Target/Makefile Thu Aug 5 13:22:30 2004 @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../.. -DIRS = CBackend X86 SparcV9 Skeleton +DIRS = CBackend X86 SparcV9 PowerPC Skeleton LIBRARYNAME = target BUILD_ARCHIVE = 1 From alkis at cs.uiuc.edu Thu Aug 5 13:22:53 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 5 Aug 2004 13:22:53 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408051822.NAA01918@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.76 -> 1.77 --- Log message: Introduce vtables. As we do not allocate objects yet this do not really work, but the code generated seems fine. The implementation needs some refactoring. This will happen next. --- Diffs of the changes: (+125 -7) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.76 llvm-java/lib/Compiler/Compiler.cpp:1.77 --- llvm-java/lib/Compiler/Compiler.cpp:1.76 Thu Aug 5 07:53:53 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Thu Aug 5 13:22:43 2004 @@ -149,7 +149,7 @@ struct VTableInfo { VTableInfo() : vtable(NULL) { } - ConstantStruct* vtable; + GlobalVariable* vtable; typedef std::map Method2IndexMap; Method2IndexMap m2iMap; }; @@ -244,7 +244,7 @@ ClassFile* cf = ClassFile::getClassFile(className); ClassInfo& ci = c2ciMap_[className]; assert(!ci.type && ci.f2iMap.empty() && - "got already initialized Classinfo!"); + "got already initialized ClassInfo!"); ci.type = OpaqueType::get(); std::vector elements; @@ -257,7 +257,8 @@ // this is java/lang/Object so we must add the opaque // llvm_java_base type first Type* base = OpaqueType::get(); - module_->addTypeName("llvm_java_base", base); + module_->addTypeName("", base); + ci.f2iMap.insert(std::make_pair("", elements.size())); elements.push_back(base); } @@ -281,7 +282,77 @@ return ci; } - //const VTableInfo& getVTableInfo(const std::string& className); + const VTableInfo& getVTableInfo(const std::string& className) { + Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(className); + if (it != c2viMap_.end() && it->first == className) + return it->second; + + DEBUG(std::cerr << "Building VTableInfo for: " << className << '\n'); + ClassFile* cf = ClassFile::getClassFile(className); + VTableInfo& vi = c2viMap_[className]; + assert(!vi.vtable && vi.m2iMap.empty() && + "got already initialized VTableInfo!"); + + std::vector elements; + std::vector init; + ConstantClass* super = cf->getSuperClass(); + const VTableInfo* superVI = + super ? &getVTableInfo(super->getName()->str()) : NULL; + + if (superVI) { + // copy all the types from the super class' vtable + assert(superVI->vtable && "No vtable found for super class!"); + ConstantStruct* superInit = + cast(superVI->vtable->getInitializer()); + const StructType* superVTableTy = superInit->getType(); + std::copy(superVTableTy->element_begin(), + superVTableTy->element_end(), + std::back_inserter(elements)); + for (unsigned i = 0, e = superInit->getNumOperands(); i != e; ++i) + init.push_back(superInit->getOperand(i)); + vi.m2iMap = superVI->m2iMap; + } +// else { +// // this is java/lang/Object so we must add the opaque +// // llvm_java_vtable_base type first +// Type* baseVTable = OpaqueType::get(); +// module_->addTypeName("", baseVTable); +// elements.push_back(baseVTable); +// init.push_back(llvm::Constant::getNullValue(baseVTable)); +// } + + const Methods& methods = cf->getMethods(); + init.resize(elements.size(), NULL); + + for (unsigned i = 0, e = methods.size(); i != e; ++i) { + Method* method = methods[i]; + if (!method->isStatic() && method->getName()->str() != "") { + std::string methodDescr = + method->getName()->str() + + method->getDescriptor()->str(); + unsigned& index = vi.m2iMap[methodDescr]; + Function* vfun = module_->getOrInsertFunction + (className + '/' + methodDescr, + cast(getType(method->getDescriptor(), + getClassInfo(className).type))); + toCompileFunctions_.insert(vfun); + if (!index) { + index = elements.size(); + elements.push_back(vfun->getType()); + init.resize(elements.size(), NULL); + } + init[index] = vfun; + DEBUG(std::cerr << index << " = " << methodDescr << '\n'); + } + } + + vi.vtable = new GlobalVariable(StructType::get(elements), + true, GlobalVariable::ExternalLinkage, + ConstantStruct::get(init), + className + "", + module_); + return vi; + } Value* getOrCreateLocal(unsigned index, Type* type) { if (!locals_[index] || @@ -313,12 +384,20 @@ (ConstantFieldRef*)(cf_->getConstantPool()[index]); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); + return getField(bcI, + fieldRef->getClass()->getName()->str(), + nameAndType->getName()->str(), + ptr); + } + + Value* getField(unsigned bcI, + std::string className, + const std::string& fieldName, + Value* ptr) { // Cast ptr to correct type - std::string className = fieldRef->getClass()->getName()->str(); ptr = new CastInst(ptr, PointerType::get(getClassInfo(className).type), TMP, getBBAt(bcI)); ClassFile* classfile = ClassFile::getClassFile(className); - std::string fieldName = nameAndType->getName()->str(); // deref pointer std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); @@ -831,7 +910,46 @@ } void do_invokevirtual(unsigned bcI, unsigned index) { - assert(0 && "not implemented"); + ConstantMethodRef* methodRef = + (ConstantMethodRef*)(cf_->getConstantPool()[index]); + ConstantNameAndType* nameAndType = methodRef->getNameAndType(); + + const std::string className = methodRef->getClass()->getName()->str(); + const ClassInfo& ci = getClassInfo(className); + const VTableInfo& vi = getVTableInfo(className); + + std::string methodDescr = + nameAndType->getName()->str() + + nameAndType->getDescriptor()->str(); + + Value* objRef = opStack_.top(); // do not pop + objRef = new CastInst(objRef, PointerType::get(ci.type), + "this", getBBAt(bcI)); + Value* vtable = getField(bcI, className, "", objRef); + vtable = new CastInst(vtable, PointerType::get(vi.vtable->getType()), + TMP, getBBAt(bcI)); + vtable = new LoadInst(vtable, TMP, getBBAt(bcI)); + std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); + assert(vi.m2iMap.find(methodDescr) != vi.m2iMap.end() && + "could not find slot for virtual function!"); + unsigned vSlot = vi.m2iMap.find(methodDescr)->second; + indices.push_back(ConstantUInt::get(Type::UIntTy, vSlot)); + Value* vfun = new LoadInst + (new GetElementPtrInst(vtable, indices, TMP, getBBAt(bcI)), TMP, + getBBAt(bcI)); + + const FunctionType* vfunTy = cast + (cast(vfun->getType())->getElementType()); + std::vector params(vfunTy->getNumParams(), NULL); + for (unsigned i = 0, e = vfunTy->getNumParams(); i != e; ++i) { + Value* p = opStack_.top(); opStack_.pop(); + const Type* paramTy = vfunTy->getParamType(i); + params[i] = p->getType() == paramTy ? p : + new CastInst(p, paramTy, TMP, getBBAt(bcI)); + } + + Value* r = new CallInst(vfun, params, TMP, getBBAt(bcI)); + opStack_.push(r); } void do_invokespecial(unsigned bcI, unsigned index) { From alkis at cs.uiuc.edu Thu Aug 5 13:22:54 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 5 Aug 2004 13:22:54 -0500 Subject: [llvm-commits] CVS: llvm-java/runtime/runtime.ll Message-ID: <200408051822.NAA01921@zion.cs.uiuc.edu> Changes in directory llvm-java/runtime: runtime.ll updated: 1.4 -> 1.5 --- Log message: Introduce vtables. As we do not allocate objects yet this do not really work, but the code generated seems fine. The implementation needs some refactoring. This will happen next. --- Diffs of the changes: (+3 -3) Index: llvm-java/runtime/runtime.ll diff -u llvm-java/runtime/runtime.ll:1.4 llvm-java/runtime/runtime.ll:1.5 --- llvm-java/runtime/runtime.ll:1.4 Wed Aug 4 04:49:18 2004 +++ llvm-java/runtime/runtime.ll Thu Aug 5 13:22:43 2004 @@ -1,6 +1,6 @@ -%llvm_java_base = type { %llvm_java_vtable_base* } -%llvm_java_vtable_base = type { %llvm_java_type_info } -%llvm_java_type_info = type { } +"" = type ""* +"" = type { "" } +"" = type { } implementation From brukman at cs.uiuc.edu Thu Aug 5 13:24:22 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 13:24:22 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200408051824.NAA01960@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.54 -> 1.55 --- Log message: * Add PowerPC library to LLC * Fit used libraries on a few lines --- Diffs of the changes: (+3 -18) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.54 llvm/tools/llc/Makefile:1.55 --- llvm/tools/llc/Makefile:1.54 Wed Aug 4 02:38:52 2004 +++ llvm/tools/llc/Makefile Thu Aug 5 13:24:11 2004 @@ -9,24 +9,9 @@ LEVEL = ../.. TOOLNAME = llc -USEDLIBS = cwriter \ - sparcv9 \ - x86 \ - skeleton \ - selectiondag \ - sparcv9regalloc \ - sched \ - codegen \ - target.a \ - sparcv9livevar \ - ipa.a \ - transforms.a \ - scalaropts.a \ - analysis.a \ - transformutils.a \ - bcreader \ - bcwriter \ - vmcore \ +USEDLIBS = cwriter powerpc sparcv9 x86 skeleton selectiondag sparcv9regalloc + sched codegen target.a sparcv9livevar ipa.a transforms.a + scalaropts.a analysis.a transformutils.a bcreader bcwriter vmcore \ support.a TOOLLINKOPTS = $(PLATFORMLIBDL) From brukman at cs.uiuc.edu Thu Aug 5 13:31:43 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 13:31:43 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200408051831.NAA02330@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.55 -> 1.56 --- Log message: Lines need to end with \ to make sure they're actually continued --- Diffs of the changes: (+2 -2) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.55 llvm/tools/llc/Makefile:1.56 --- llvm/tools/llc/Makefile:1.55 Thu Aug 5 13:24:11 2004 +++ llvm/tools/llc/Makefile Thu Aug 5 13:31:33 2004 @@ -9,8 +9,8 @@ LEVEL = ../.. TOOLNAME = llc -USEDLIBS = cwriter powerpc sparcv9 x86 skeleton selectiondag sparcv9regalloc - sched codegen target.a sparcv9livevar ipa.a transforms.a +USEDLIBS = cwriter powerpc sparcv9 x86 skeleton selectiondag sparcv9regalloc \ + sched codegen target.a sparcv9livevar ipa.a transforms.a \ scalaropts.a analysis.a transformutils.a bcreader bcwriter vmcore \ support.a TOOLLINKOPTS = $(PLATFORMLIBDL) From lattner at cs.uiuc.edu Thu Aug 5 13:33:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Aug 2004 13:33:10 -0500 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200408051833.NAA18520@apoc.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.56 -> 1.57 --- Log message: while we're at it, make the libraries be on separate lines --- Diffs of the changes: (+21 -4) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.56 llvm/tools/llc/Makefile:1.57 --- llvm/tools/llc/Makefile:1.56 Thu Aug 5 13:31:33 2004 +++ llvm/tools/llc/Makefile Thu Aug 5 13:32:57 2004 @@ -9,10 +9,27 @@ LEVEL = ../.. TOOLNAME = llc -USEDLIBS = cwriter powerpc sparcv9 x86 skeleton selectiondag sparcv9regalloc \ - sched codegen target.a sparcv9livevar ipa.a transforms.a \ - scalaropts.a analysis.a transformutils.a bcreader bcwriter vmcore \ - support.a +USEDLIBS = \ + cwriter \ + powerpc \ + sparcv9 \ + x86 \ + skeleton \ + selectiondag \ + sparcv9regalloc \ + sched \ + codegen \ + target.a \ + sparcv9livevar \ + ipa.a \ + transforms.a \ + scalaropts.a \ + analysis.a \ + transformutils.a \ + bcreader \ + bcwriter \ + vmcore \ + support.a TOOLLINKOPTS = $(PLATFORMLIBDL) include $(LEVEL)/Makefile.common From brukman at cs.uiuc.edu Thu Aug 5 13:34:26 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 13:34:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/Makefile Message-ID: <200408051834.NAA02833@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: Makefile updated: 1.7 -> 1.8 --- Log message: Simplify makefile by combining all TableGen dependencies into one variable --- Diffs of the changes: (+15 -22) Index: llvm/lib/Target/PowerPC/Makefile diff -u llvm/lib/Target/PowerPC/Makefile:1.7 llvm/lib/Target/PowerPC/Makefile:1.8 --- llvm/lib/Target/PowerPC/Makefile:1.7 Wed Aug 4 16:37:41 2004 +++ llvm/lib/Target/PowerPC/Makefile Thu Aug 5 13:34:15 2004 @@ -10,41 +10,34 @@ LIBRARYNAME = powerpc include $(LEVEL)/Makefile.common +TARGET = PowerPC + # Make sure that tblgen is run, first thing. $(SourceDepend): PowerPCGenRegisterInfo.h.inc PowerPCGenRegisterNames.inc \ PowerPCGenRegisterInfo.inc PowerPCGenInstrNames.inc \ PowerPCGenInstrInfo.inc -PowerPCGenRegisterNames.inc:: $(SourceDir)/PowerPC.td \ - $(SourceDir)/PowerPCRegisterInfo.td \ - $(SourceDir)/../Target.td $(TBLGEN) - @echo "Building PowerPC.td register names with tblgen" +TDFILES = $(SourceDir)/$(TARGET).td $(wildcard $(SourceDir)/*.td) \ + $(SourceDir)/../Target.td + +$(TARGET)GenRegisterNames.inc:: $(TDFILES) $(TBLGEN) + @echo "Building $(TARGET).td register names with tblgen" $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-register-enums -o $@ -PowerPCGenRegisterInfo.h.inc:: $(SourceDir)/PowerPC.td \ - $(SourceDir)/PowerPCRegisterInfo.td \ - $(SourceDir)/../Target.td $(TBLGEN) - @echo "Building PowerPC.td register information header with tblgen" +$(TARGET)GenRegisterInfo.h.inc:: $(TDFILES) $(TBLGEN) + @echo "Building $(TARGET).td register information header with tblgen" $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-register-desc-header -o $@ -PowerPCGenRegisterInfo.inc:: $(SourceDir)/PowerPC.td \ - $(SourceDir)/PowerPCRegisterInfo.td \ - $(SourceDir)/../Target.td $(TBLGEN) - @echo "Building PowerPC.td register information implementation with tblgen" +$(TARGET)GenRegisterInfo.inc:: $(TDFILES) $(TBLGEN) + @echo "Building $(TARGET).td register information implementation with tblgen" $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-register-desc -o $@ -PowerPCGenInstrNames.inc:: $(SourceDir)/PowerPC.td \ - $(SourceDir)/PowerPCInstrInfo.td \ - $(SourceDir)/PowerPCInstrFormats.td \ - $(SourceDir)/../Target.td $(TBLGEN) - @echo "Building PowerPC.td instruction names with tblgen" +$(TARGET)GenInstrNames.inc:: $(TDFILES) $(TBLGEN) + @echo "Building $(TARGET).td instruction names with tblgen" $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-enums -o $@ -PowerPCGenInstrInfo.inc:: $(SourceDir)/PowerPC.td \ - $(SourceDir)/PowerPCInstrInfo.td \ - $(SourceDir)/PowerPCInstrFormats.td \ - $(SourceDir)/../Target.td $(TBLGEN) - @echo "Building PowerPC.td instruction information with tblgen" +$(TARGET)GenInstrInfo.inc:: $(TDFILES) $(TBLGEN) + @echo "Building $(TARGET).td instruction information with tblgen" $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-desc -o $@ clean:: From alkis at cs.uiuc.edu Thu Aug 5 13:57:06 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 5 Aug 2004 13:57:06 -0500 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200408051857.NAA05839@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.77 -> 1.78 --- Log message: Refactor function calling code into makeCall(). --- Diffs of the changes: (+20 -26) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.77 llvm-java/lib/Compiler/Compiler.cpp:1.78 --- llvm-java/lib/Compiler/Compiler.cpp:1.77 Thu Aug 5 13:22:43 2004 +++ llvm-java/lib/Compiler/Compiler.cpp Thu Aug 5 13:56:55 2004 @@ -909,6 +909,22 @@ new StoreInst(v, getField(bcI, index, p), getBBAt(bcI)); } + void makeCall(Value* fun, BasicBlock* bb) { + const PointerType* funPtrTy = cast(fun->getType()); + const FunctionType* funTy = cast(funPtrTy->getElementType()); + std::vector params(funTy->getNumParams(), NULL); + for (unsigned i = 0, e = funTy->getNumParams(); i != e; ++i) { + Value* p = opStack_.top(); opStack_.pop(); + const Type* paramTy = funTy->getParamType(i); + params[i] = + p->getType() == paramTy ? p : new CastInst(p, paramTy, TMP, bb); + } + + Value* r = new CallInst(fun, params, TMP, bb); + if (funTy->getReturnType() != Type::VoidTy) + opStack_.push(r); + } + void do_invokevirtual(unsigned bcI, unsigned index) { ConstantMethodRef* methodRef = (ConstantMethodRef*)(cf_->getConstantPool()[index]); @@ -934,22 +950,9 @@ "could not find slot for virtual function!"); unsigned vSlot = vi.m2iMap.find(methodDescr)->second; indices.push_back(ConstantUInt::get(Type::UIntTy, vSlot)); - Value* vfun = new LoadInst - (new GetElementPtrInst(vtable, indices, TMP, getBBAt(bcI)), TMP, - getBBAt(bcI)); - - const FunctionType* vfunTy = cast - (cast(vfun->getType())->getElementType()); - std::vector params(vfunTy->getNumParams(), NULL); - for (unsigned i = 0, e = vfunTy->getNumParams(); i != e; ++i) { - Value* p = opStack_.top(); opStack_.pop(); - const Type* paramTy = vfunTy->getParamType(i); - params[i] = p->getType() == paramTy ? p : - new CastInst(p, paramTy, TMP, getBBAt(bcI)); - } - - Value* r = new CallInst(vfun, params, TMP, getBBAt(bcI)); - opStack_.push(r); + Value* vfunPtr = new GetElementPtrInst(vtable, indices, TMP, getBBAt(bcI)); + Value* vfun = new LoadInst(vfunPtr, TMP, getBBAt(bcI)); + makeCall(vfun, getBBAt(bcI)); } void do_invokespecial(unsigned bcI, unsigned index) { @@ -968,18 +971,9 @@ FunctionType* funcType = cast(getType(nameAndType->getDescriptor())); - std::vector params(funcType->getNumParams(), NULL); - for (unsigned i = 0, e = funcType->getNumParams(); i != e; ++i) { - Value* p = opStack_.top(); opStack_.pop(); - const Type* paramTy = funcType->getParamType(i); - params[i] = p->getType() == paramTy ? p : - new CastInst(p, paramTy, TMP, getBBAt(bcI)); - } - Function* function = module_->getOrInsertFunction(funcName, funcType); toCompileFunctions_.insert(function); - Value* r = new CallInst(function, params, TMP, getBBAt(bcI)); - opStack_.push(r); + makeCall(function, getBBAt(bcI)); } void do_invokeinterface(unsigned bcI, unsigned index) { From criswell at cs.uiuc.edu Thu Aug 5 14:01:04 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 14:01:04 -0500 Subject: [llvm-commits] CVS: llvm/test/QMTest/llvmdb.py Message-ID: <200408051901.OAA05975@zion.cs.uiuc.edu> Changes in directory llvm/test/QMTest: llvmdb.py updated: 1.12 -> 1.13 --- Log message: Added Bytecode directory. Added the input bytecode file in Regression.Bytecode to the list of filenames to ignore. --- Diffs of the changes: (+2 -1) Index: llvm/test/QMTest/llvmdb.py diff -u llvm/test/QMTest/llvmdb.py:1.12 llvm/test/QMTest/llvmdb.py:1.13 --- llvm/test/QMTest/llvmdb.py:1.12 Mon Mar 15 12:19:29 2004 +++ llvm/test/QMTest/llvmdb.py Thu Aug 5 14:00:53 2004 @@ -34,6 +34,7 @@ RegressionMap={'Assembler':'llvm.AssembleTest', 'Analysis':'llvm.TestRunner', 'BugPoint':'llvm.TestRunner', + 'Bytecode':'llvm.TestRunner', 'C++Frontend':'llvm.CXXTest', 'CBackend':'llvm.LLToCTest', 'CFrontend':'llvm.CTest', @@ -166,7 +167,7 @@ invalid_dirs = ['CVS', 'QMTest', 'QMTestDB', 'Scripts', 'Programs', 'Fragments', 'Reoptimizer', 'Debugger', 'tmp'] - invalid_files = ['Makefile', 'README.txt', '.cvsignore', 'opaquetypes.ll'] + invalid_files = ['Makefile', 'README.txt', '.cvsignore', 'opaquetypes.ll', 'constexpr.ll.bc-13' ] # # Start with an empty list of files and directories. From brukman at cs.uiuc.edu Thu Aug 5 14:09:57 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 14:09:57 -0500 Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200408051909.OAA06087@zion.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.24 -> 1.25 --- Log message: We now have the PowerPC backend, thanks to Nate Begeman and Luis Gerbarg! --- Diffs of the changes: (+9 -1) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.24 llvm/CREDITS.TXT:1.25 --- llvm/CREDITS.TXT:1.24 Tue Aug 3 15:14:03 2004 +++ llvm/CREDITS.TXT Thu Aug 5 14:09:47 2004 @@ -12,6 +12,10 @@ W: http://www.cs.uiuc.edu/~vadve/ D: The Sparc64 backend, provider of much wisdom, and motivator for LLVM +N: Nate Begeman +E: natebegeman at mac.com +D: Portions of the PowerPC backend + N: Tanya Brethour E: tonic at nondot.org W: http://nondot.org/~tonic/ @@ -20,7 +24,8 @@ N: Misha Brukman E: brukman+llvm at uiuc.edu W: http://misha.brukman.net -D: Portions of X86 and Sparc JIT compilers, incremental bytecode loader +D: Portions of X86 and Sparc JIT compilers, PowerPC backend +D: Incremental bytecode loader N: Cameron Buschardt E: buschard at uiuc.edu @@ -41,6 +46,9 @@ D: Dynamic trace optimizer D: FreeBSD/X86 compatibility fixes, the llvm-nm tool +N: Louis Gerbarg +D: Portions of the PowerPC backend + N: Chris Lattner E: sabre at nondot.org W: http://nondot.org/~sabre/ From gaeke at cs.uiuc.edu Thu Aug 5 14:55:09 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu, 5 Aug 2004 14:55:09 -0500 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.pl Message-ID: <200408051955.OAA06775@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.pl updated: 1.62 -> 1.63 --- Log message: Split out -disable-codegen into -disable-llc and -disable-jit. --- Diffs of the changes: (+10 -5) Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.62 llvm/utils/NightlyTest.pl:1.63 --- llvm/utils/NightlyTest.pl:1.62 Tue Jul 27 13:41:49 2004 +++ llvm/utils/NightlyTest.pl Thu Aug 5 14:54:59 2004 @@ -25,7 +25,8 @@ # -release Build an LLVM Release version # -pedantic Enable additional GCC warnings to detect possible errors. # -enable-linscan Enable linearscan tests -# -disable-codegen Disable LLC and JIT tests in the nightly tester. +# -disable-llc Disable LLC tests in the nightly tester. +# -disable-jit Disable JIT tests in the nightly tester. # -verbose Turn on some debug output # -debug Print information useful only to maintainers of this script. # -nice Checkout/Configure/Build with "nice" to reduce impact @@ -78,7 +79,7 @@ my $PROGTESTOPTS = ""; my $VERBOSE = 0; my $DEBUG = 0; -my $CONFIGUREARGS = "--enable-jit"; +my $CONFIGUREARGS = ""; my $NICE = ""; sub ReadFile { @@ -262,9 +263,10 @@ next; } if (/^-enable-linscan$/) { $PROGTESTOPTS .= " ENABLE_LINEARSCAN=1"; next; } - if (/^-disable-codegen$/){ $PROGTESTOPTS .= " DISABLE_JIT=1 DISABLE_LLC=1"; - $CONFIGUREARGS="--disable-jit --disable-llc_diffs"; - next; } + if (/^-disable-llc$/) { $PROGTESTOPTS .= " DISABLE_LLC=1"; + $CONFIGUREARGS .= " --disable-llc_diffs"; next; } + if (/^-disable-jit$/) { $PROGTESTOPTS .= " DISABLE_JIT=1"; + $CONFIGUREARGS .= " --disable-jit"; next; } if (/^-verbose$/) { $VERBOSE = 1; next; } if (/^-debug$/) { $DEBUG = 1; next; } if (/^-nice$/) { $NICE = "nice "; next; } @@ -279,6 +281,9 @@ if ($ENV{'LLVMGCCDIR'}) { $CONFIGUREARGS .= " --with-llvmgccdir=" . $ENV{'LLVMGCCDIR'}; } +if ($CONFIGUREARGS !~ /--disable-jit/) { + $CONFIGUREARGS .= " --enable-jit"; +} die "Must specify 0 or 3 options!" if (@ARGV != 0 and @ARGV != 3); From criswell at cs.uiuc.edu Thu Aug 5 15:02:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 15:02:05 -0500 Subject: [llvm-commits] CVS: llvm-www/releases/1.3/ Message-ID: <200408052002.PAA06476@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.3: --- Log message: Directory /home/vadve/shared/InternalCVS/llvm-www/releases/1.3 added to the repository --- Diffs of the changes: (+0 -0) From criswell at cs.uiuc.edu Thu Aug 5 15:04:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 15:04:05 -0500 Subject: [llvm-commits] CVS: llvm-www/releases/1.3/LICENSE.TXT announcement.txt index.html Message-ID: <200408052004.PAA06688@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.3: LICENSE.TXT added (r1.1) announcement.txt added (r1.1) index.html added (r1.1) --- Log message: Initial work on LLVM 1.3 release. --- Diffs of the changes: (+149 -0) Index: llvm-www/releases/1.3/LICENSE.TXT diff -c /dev/null llvm-www/releases/1.3/LICENSE.TXT:1.1 *** /dev/null Thu Aug 5 15:04:03 2004 --- llvm-www/releases/1.3/LICENSE.TXT Thu Aug 5 15:03:53 2004 *************** *** 0 **** --- 1,100 ---- + ============================================================================== + LLVM Release License + ============================================================================== + University of Illinois/NCSA + Open Source License + + Copyright (c) 2003, 2004 University of Illinois at Urbana-Champaign. + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.cs.uiuc.edu + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. + + ============================================================================== + Copyrights and Licenses for Third Party Software Distributed with LLVM: + ============================================================================== + The LLVM software contains code written by third parties. Such software will + have its own individual LICENSE.TXT file in the directory in which it appears. + This file will describe the copyrights, license, and restrictions which apply + to that code. + + The disclaimer of warranty in the University of Illinois Open Source License + applies to all code in the LLVM Distribution, and nothing in any of the + other licenses gives permission to use the names of the LLVM Team or the + University of Illinois to endorse or promote products derived from this + Software. + + The following pieces of software have additional or alternate copyrights, + licenses, and/or restrictions: + + Program Directory + ------- --------- + Autoconf: llvm/autoconf + llvm/projects/ModuleMaker/autoconf + llvm/projects/sample/autoconf + Burg: llvm/utils/Burg + llvm/test/Programs/MultiSource/Applications/Burg + Aha: llvm/test/Programs/MultiSource/Applications/aha + SGEFA: llvm/test/Programs/MultiSource/Applications/sgefa + SIOD: llvm/test/Programs/MultiSource/Applications/siod + Spiff: llvm/test/Programs/MultiSource/Applications/spiff + D: llvm/test/Programs/MultiSource/Applications/d + Lambda: llvm/test/Programs/MultiSource/Applications/lambda-0.1.3 + hbd: llvm/test/Programs/MultiSource/Applications/hbd + treecc: llvm/test/Programs/MultiSource/Applications/treecc + kimwitu++: llvm/test/Programs/MultiSource/Applications/kimwitu++ + obsequi: llvm/test/Programs/MultiSource/Applications/obsequi + Fhourstones: llvm/test/Programs/MultiSource/Benchmarks/Fhourstones + McCat: llvm/test/Programs/MultiSource/Benchmarks/McCat + Olden: llvm/test/Programs/MultiSource/Benchmarks/Olden + OptimizerEval: llvm/test/Programs/MultiSource/Benchmarks/OptimizerEval + Ptrdist: llvm/test/Programs/MultiSource/Benchmarks/Ptrdist + LLUBenchmark: llvm/test/Programs/MultiSource/Benchmarks/llubenchmark + SIM: llvm/test/Programs/MultiSource/Benchmarks/sim + cfrac: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/cfrac + espresso: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/espresso + gs: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/gs + p2c: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c + gawk: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/gawk + make: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/make + perl: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/perl + Dhrystone: llvm/test/Programs/SingleSource/Benchmarks/Dhrystone + SingleSource Tests: llvm/test/Programs/SingleSource/Benchmarks/Misc + llvm/test/Programs/SingleSource/CustomChecked + llvm/test/Programs/SingleSource/Gizmos + GNU Libc: llvm/runtime/GCCLibraries/libc + Zlib Library: llvm/runtime/zlib + PNG Library: llvm/runtime/libpng + Index: llvm-www/releases/1.3/announcement.txt diff -c /dev/null llvm-www/releases/1.3/announcement.txt:1.1 *** /dev/null Thu Aug 5 15:04:04 2004 --- llvm-www/releases/1.3/announcement.txt Thu Aug 5 15:03:53 2004 *************** *** 0 **** --- 1,42 ---- + LLVM Compiler Infrastructure -- Release 1.3 + http://llvm.cs.uiuc.edu + + We are pleased to announce the release of version 1.3 of the LLVM Compiler + Infrastructure. If you are new to LLVM, please see "WHAT IS LLVM?" below. + If you are already familiar with LLVM, skip to "WHAT IS NEW IN LLVM 1.3?" + + WHAT IS LLVM? + + LLVM is a new infrastructure designed for compile-time, link-time, runtime, + and "idle-time" optimization of programs from arbitrary programming languages. + LLVM is written in C++ and has been developed over the past 4 years at the + University of Illinois. It currently supports compilation of C and C++ + programs using front-ends derived from GCC 3.4. After optimization, it can + emit native X86, native SparcV9, or C code for the optimized program. New + front-ends are in early development for Java bytecode and CAML, and new + backends are in early development for several other targets. + + The LLVM infrastructure is publicly available under a non-restrictive open + source license. More information about LLVM and the contents of the + publicly released software is available at the LLVM Web site above. + + WHAT IS NEW IN LLVM 1.3? + + This release is substantially faster and introduces several new features, + including: new optimizations, support for several GCC extensions that were not + supported in 1.1, and support for profile-guided optimization. The X86 code + generator in LLVM 1.3 also produces much better native code, and LLVM now + comes with a beta-quality global register allocator. Finally, LLVM 1.3 + includes the usual collection of bug fixes and other minor improvements. + + A full list of new features and bug-fixes are listed in the Release Notes: + http://llvm.cs.uiuc.edu/releases/1.3/docs/ReleaseNotes.html#whatsnew + + For an easier to read set of changes, please see the status updates: + http://mail.cs.uiuc.edu/pipermail/llvm-announce/2004-March/000006.html + http://mail.cs.uiuc.edu/pipermail/llvm-announce/2004-February/000005.html + + HOW DO I GET IT? + + Please see: http://llvm.cs.uiuc.edu/releases + Index: llvm-www/releases/1.3/index.html diff -c /dev/null llvm-www/releases/1.3/index.html:1.1 *** /dev/null Thu Aug 5 15:04:05 2004 --- llvm-www/releases/1.3/index.html Thu Aug 5 15:03:53 2004 *************** *** 0 **** --- 1,7 ---- + + + + + + + From criswell at cs.uiuc.edu Thu Aug 5 15:36:11 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 15:36:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/LICENSE.TXT Message-ID: <200408052036.PAA09028@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: LICENSE.TXT added (r1.1) --- Log message: Add additional copyright notice for the PowerPC backend. Thanks Nate! --- Diffs of the changes: (+7 -0) Index: llvm/lib/Target/PowerPC/LICENSE.TXT diff -c /dev/null llvm/lib/Target/PowerPC/LICENSE.TXT:1.1 *** /dev/null Thu Aug 5 15:36:10 2004 --- llvm/lib/Target/PowerPC/LICENSE.TXT Thu Aug 5 15:36:00 2004 *************** *** 0 **** --- 1,7 ---- + PowerPC Backend + ------------------------------------------------------------------------------- + The PowerPC Backend is licensed under the Illinois Open Source License and has + the following additional copyright: + + Copyright (C) 2004 Nate Begeman + From criswell at cs.uiuc.edu Thu Aug 5 15:36:11 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu, 5 Aug 2004 15:36:11 -0500 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200408052036.PAA09031@zion.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.18 -> 1.19 --- Log message: Add additional copyright notice for the PowerPC backend. Thanks Nate! --- Diffs of the changes: (+1 -0) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.18 llvm/LICENSE.TXT:1.19 --- llvm/LICENSE.TXT:1.18 Tue Jun 1 15:37:41 2004 +++ llvm/LICENSE.TXT Thu Aug 5 15:36:00 2004 @@ -61,6 +61,7 @@ Program Directory ------- --------- +PowerPC Backend llvm/lib/Target/PowerPC Autoconf: llvm/autoconf llvm/projects/ModuleMaker/autoconf llvm/projects/sample/autoconf From brukman at cs.uiuc.edu Thu Aug 5 16:04:14 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu, 5 Aug 2004 16:04:14 -0500 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200408052104.QAA09753@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.225 -> 1.226 --- Log message: * Mention PowerPC as new feature, and experimental feature * Wrap long lines to 80 cols --- Diffs of the changes: (+15 -11) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.225 llvm/docs/ReleaseNotes.html:1.226 --- llvm/docs/ReleaseNotes.html:1.225 Wed Aug 4 03:00:45 2004 +++ llvm/docs/ReleaseNotes.html Thu Aug 5 16:04:03 2004 @@ -149,6 +149,8 @@
    • All LLVM tools will now respond to the --version option which will tell you the version of LLVM on which the tool is based.
    • +
    • An experimental PowerPC backend has been added, capable of compiling several +SPEC benchmarks.
    • @@ -198,13 +200,15 @@ Bytecode Reader
    • Global Vars Have (Somewhat) Limited Type Range
    • -
    • operator<< on a Value* now prints the address of the object instead of its contents.
    • +
    • operator<< on a Value* now +prints the address of the object instead of its contents.
    • Bytecode Enhancements - Needed
    • -
    • [loopsimplify] Loop simplify is really slow on 252.eon
    • -
    • [code-cleanup] SymbolTable - class cleanup, Type should not derive from Value, eliminate - ConstantPointerRef class.
    • +Needed +
    • [loopsimplify] Loop simplify is +really slow on 252.eon
    • +
    • [code-cleanup] SymbolTable class +cleanup, Type should not derive from Value, eliminate ConstantPointerRef +class.
    • The memory footprint of the LLVM IR has been reduced substantially.
    • The LLVM linker and many core classes have been sped up substantially.
    • @@ -345,12 +349,10 @@
    • Intel and AMD machines running Red Hat Linux and FreeBSD (and probably other unix-like systems).
    • Sun UltraSPARC workstations running Solaris 8.
    • -
    • PowerPC-based Mac OS X boxes, running 10.3 and above (C backend and - interpreter only, no native codegen is available yet).
    • +
    • PowerPC-based Mac OS X boxes, running 10.2 and above.
    • Intel and AMD machines running on Win32 with the Cygwin libraries.