From alenhar2 at cs.uiuc.edu Mon Jul 4 15:07:32 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Jul 2005 15:07:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200507042007.PAA32737@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.145 -> 1.146 --- Log message: check the correct VT --- Diffs of the changes: (+1 -1) AlphaISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.145 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.146 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.145 Sun Jul 3 15:06:13 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Mon Jul 4 15:07:21 2005 @@ -1642,7 +1642,7 @@ Select(Chain); unsigned r = dyn_cast(Node)->getReg(); //std::cerr << "CopyFromReg " << Result << " = " << r << "\n"; - if (isFP) + if (MVT::isFloatingPoint(N.getValue(0).getValueType())) BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r); else BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r); From alenhar2 at cs.uiuc.edu Tue Jul 5 10:18:44 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Jul 2005 10:18:44 -0500 Subject: [llvm-commits] CVS: llvm/projects/sample/lib/Makefile Message-ID: <200507051518.KAA01628@zion.cs.uiuc.edu> Changes in directory llvm/projects/sample/lib: Makefile updated: 1.4 -> 1.5 --- Log message: updates --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/sample/lib/Makefile diff -u llvm/projects/sample/lib/Makefile:1.4 llvm/projects/sample/lib/Makefile:1.5 --- llvm/projects/sample/lib/Makefile:1.4 Tue Oct 21 10:33:08 2003 +++ llvm/projects/sample/lib/Makefile Tue Jul 5 10:18:33 2005 @@ -8,6 +8,6 @@ # # List all of the subdirectories that we will compile. # -DIRS=sample +DIRS=lsqcor include $(LEVEL)/Makefile.common From alenhar2 at cs.uiuc.edu Tue Jul 5 10:18:44 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Jul 2005 10:18:44 -0500 Subject: [llvm-commits] CVS: llvm/projects/sample/Makefile Message-ID: <200507051518.KAA01632@zion.cs.uiuc.edu> Changes in directory llvm/projects/sample: Makefile updated: 1.7 -> 1.8 --- Log message: updates --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/sample/Makefile diff -u llvm/projects/sample/Makefile:1.7 llvm/projects/sample/Makefile:1.8 --- llvm/projects/sample/Makefile:1.7 Tue Oct 26 02:03:39 2004 +++ llvm/projects/sample/Makefile Tue Jul 5 10:18:32 2005 @@ -8,7 +8,7 @@ # Indicates our relative path to the top of the project's root directory. # LEVEL = . -DIRS = lib tools +DIRS = lib EXTRA_DIST = include # From alenhar2 at cs.uiuc.edu Tue Jul 5 11:36:29 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Jul 2005 11:36:29 -0500 Subject: [llvm-commits] CVS: llvm/projects/sample/lib/Makefile Message-ID: <200507051636.LAA02139@zion.cs.uiuc.edu> Changes in directory llvm/projects/sample/lib: Makefile updated: 1.5 -> 1.6 --- Log message: oops --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/sample/lib/Makefile diff -u llvm/projects/sample/lib/Makefile:1.5 llvm/projects/sample/lib/Makefile:1.6 --- llvm/projects/sample/lib/Makefile:1.5 Tue Jul 5 10:18:33 2005 +++ llvm/projects/sample/lib/Makefile Tue Jul 5 11:36:18 2005 @@ -8,6 +8,6 @@ # # List all of the subdirectories that we will compile. # -DIRS=lsqcor +DIRS=sample include $(LEVEL)/Makefile.common From alenhar2 at cs.uiuc.edu Tue Jul 5 11:36:30 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Jul 2005 11:36:30 -0500 Subject: [llvm-commits] CVS: llvm/projects/sample/Makefile Message-ID: <200507051636.LAA02143@zion.cs.uiuc.edu> Changes in directory llvm/projects/sample: Makefile updated: 1.8 -> 1.9 --- Log message: oops --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/sample/Makefile diff -u llvm/projects/sample/Makefile:1.8 llvm/projects/sample/Makefile:1.9 --- llvm/projects/sample/Makefile:1.8 Tue Jul 5 10:18:32 2005 +++ llvm/projects/sample/Makefile Tue Jul 5 11:36:18 2005 @@ -8,7 +8,7 @@ # Indicates our relative path to the top of the project's root directory. # LEVEL = . -DIRS = lib +DIRS = lib tools EXTRA_DIST = include # From lattner at cs.uiuc.edu Tue Jul 5 12:48:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 12:48:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200507051748.MAA02538@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.95 -> 1.96 --- Log message: Fix PowerPC varargs --- Diffs of the changes: (+26 -25) PPC32ISelPattern.cpp | 51 ++++++++++++++++++++++++++------------------------- 1 files changed, 26 insertions(+), 25 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.95 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.96 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.95 Fri Jul 1 18:11:56 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Jul 5 12:48:31 2005 @@ -464,36 +464,37 @@ } std::pair -PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { - //vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain); +PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, + SDOperand Dest) { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, + DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); } std::pair PPC32TargetLowering:: -LowerVAArgNext(SDOperand Chain, SDOperand VAList, +LowerVAArgNext(SDOperand Chain, SDOperand VAArgOp, const Type *ArgTy, SelectionDAG &DAG) { - // FIXME: THIS IS BROKEN!!! - - bool isVANext = true; - - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Result; - if (!isVANext) { - Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList, - DAG.getSrcValue(NULL)); - } else { - unsigned Amt; - if (ArgVT == MVT::i32 || ArgVT == MVT::f32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(Amt, VAList.getValueType())); - } + + SDOperand VAList = + DAG.getLoad(MVT::i32, Chain, VAArgOp, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getLoad(ArgVT, VAList.getValue(1), VAList, + DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32 || ArgVT == MVT::f32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, + DAG.getConstant(Amt, VAList.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + VAList, VAArgOp, DAG.getSrcValue(NULL)); return std::make_pair(Result, Chain); } From lattner at cs.uiuc.edu Tue Jul 5 12:50:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 12:50:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507051750.MAA02617@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.142 -> 1.143 --- Log message: Fit to 80 columns --- Diffs of the changes: (+6 -3) X86ISelPattern.cpp | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.142 llvm/lib/Target/X86/X86ISelPattern.cpp:1.143 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.142 Wed Jun 22 16:04:42 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jul 5 12:50:16 2005 @@ -443,10 +443,12 @@ } std::pair -X86TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { +X86TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, + SDOperand Dest) { // vastart just stores the address of the VarArgsFrameIndex slot. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, + DAG.getSrcValue(NULL)); return std::make_pair(Result, Result); } @@ -455,7 +457,8 @@ const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); SDOperand Val = DAG.getLoad(MVT::i32, Chain, VAList, DAG.getSrcValue(NULL)); - SDOperand Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, + DAG.getSrcValue(NULL)); unsigned Amt; if (ArgVT == MVT::i32) Amt = 4; From alenhar2 at cs.uiuc.edu Tue Jul 5 14:52:50 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Jul 2005 14:52:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200507051952.OAA03370@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.134 -> 1.135 --- Log message: 2 fixes: 1: Legalize operand in UINT_TO_FP expanision 2: SRA x, const i8 was not promoting the constant to shift amount type. --- Diffs of the changes: (+13 -4) LegalizeDAG.cpp | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.134 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.135 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.134 Sat Jul 2 15:58:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jul 5 14:52:39 2005 @@ -1100,7 +1100,15 @@ case ISD::SRL: case ISD::SRA: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS - Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS + switch (getTypeAction(Node->getOperand(1).getValueType())) { + case Expand: assert(0 && "Not possible"); + case Legal: + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS. + break; + case Promote: + Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS. + break; + } if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2); @@ -1327,13 +1335,14 @@ TLI.getOperationAction(Node->getOpcode(), Node->getOperand(0).getValueType()) == TargetLowering::Expand) { + SDOperand Op0 = LegalizeOp(Node->getOperand(0)); Tmp1 = DAG.getNode(ISD::SINT_TO_FP, Node->getValueType(0), - Node->getOperand(0)); + Op0); SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), - Node->getOperand(0), + Op0, DAG.getConstant(0, - Node->getOperand(0).getValueType())); + Op0.getValueType())); SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet, Four, Zero); From lattner at cs.uiuc.edu Tue Jul 5 14:57:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:57:28 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200507051957.OAA03456@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.15 -> 1.16 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. --- Diffs of the changes: (+18 -13) TargetLowering.h | 31 ++++++++++++++++++------------- 1 files changed, 18 insertions(+), 13 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.15 llvm/include/llvm/Target/TargetLowering.h:1.16 --- llvm/include/llvm/Target/TargetLowering.h:1.15 Sat Jun 18 13:31:30 2005 +++ llvm/include/llvm/Target/TargetLowering.h Tue Jul 5 14:57:17 2005 @@ -26,6 +26,7 @@ #include namespace llvm { + class Value; class Function; class TargetMachine; class TargetData; @@ -266,25 +267,29 @@ ArgListTy &Args, SelectionDAG &DAG) = 0; /// LowerVAStart - This lowers the llvm.va_start intrinsic. If not - /// implemented, this method prints a message and aborts. - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); + /// implemented, this method prints a message and aborts. This method should + /// return the modified chain value. Note that VAListPtr* correspond to the + /// llvm.va_start operand. + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); /// LowerVAEnd - This lowers llvm.va_end and returns the resultant chain. If /// not implemented, this defaults to a noop. - virtual SDOperand LowerVAEnd(SDOperand Chain, SDOperand L, SelectionDAG &DAG); + virtual SDOperand LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV, + SelectionDAG &DAG); - /// LowerVACopy - This lowers llvm.va_copy and returns the resultant - /// value/chain pair. If not implemented, this defaults to returning the - /// input operand. - virtual std::pair - LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, SelectionDAG &DAG); + /// LowerVACopy - This lowers llvm.va_copy and returns the resultant chain. + /// If not implemented, this defaults to loading a pointer from the input and + /// storing it to the output. + virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, + SDOperand DestP, Value *DestV, + SelectionDAG &DAG); - /// LowerVAArgNext - This lowers the instruction - /// If not implemented, this prints a message and aborts. + /// LowerVAArg - This lowers the vaarg instruction. If not implemented, this + /// prints a message and aborts. virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); /// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or /// llvm.frameaddress (depending on the value of the first argument). The From lattner at cs.uiuc.edu Tue Jul 5 14:58:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:58:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200507051958.OAA03491@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.64 -> 1.65 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. --- Diffs of the changes: (+25 -22) SelectionDAGISel.cpp | 47 +++++++++++++++++++++++++---------------------- 1 files changed, 25 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.64 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.65 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.64 Wed Jun 29 13:54:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jul 5 14:57:53 2005 @@ -837,34 +837,37 @@ DAG.setRoot(Result.second); } -std::pair -TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { +SDOperand TargetLowering::LowerVAStart(SDOperand Chain, + SDOperand VAListP, Value *VAListV, + SelectionDAG &DAG) { // We have no sane default behavior, just emit a useful error message and bail // out. std::cerr << "Variable arguments handling not implemented on this target!\n"; abort(); - return std::make_pair(SDOperand(), SDOperand()); + return SDOperand(); } -SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand L, +SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV, SelectionDAG &DAG) { // Default to a noop. return Chain; } -std::pair -TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG) { - //Default to returning the input list - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, Src, DAG.getSrcValue(NULL)); +SDOperand TargetLowering::LowerVACopy(SDOperand Chain, + SDOperand SrcP, Value *SrcV, + SDOperand DestP, Value *DestV, + SelectionDAG &DAG) { + // Default to copying the input list. + SDOperand Val = DAG.getLoad(getPointerTy(), Chain, + SrcP, DAG.getSrcValue(SrcV)); SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); + Val, DestP, DAG.getSrcValue(DestV)); + return Result; } std::pair -TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { +TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { // We have no sane default behavior, just emit a useful error message and bail // out. std::cerr << "Variable arguments handling not implemented on this target!\n"; @@ -874,28 +877,28 @@ void SelectionDAGLowering::visitVAStart(CallInst &I) { - std::pair Result = TLI.LowerVAStart(getRoot(), DAG, getValue(I.getOperand(1))); - setValue(&I, Result.first); - DAG.setRoot(Result.second); + DAG.setRoot(TLI.LowerVAStart(getRoot(), getValue(I.getOperand(1)), + I.getOperand(1), DAG)); } void SelectionDAGLowering::visitVAArg(VAArgInst &I) { std::pair Result = - TLI.LowerVAArgNext(getRoot(), getValue(I.getOperand(0)), + TLI.LowerVAArg(getRoot(), getValue(I.getOperand(0)), I.getOperand(0), I.getType(), DAG); setValue(&I, Result.first); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), DAG)); + DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), + I.getOperand(1), DAG)); } void SelectionDAGLowering::visitVACopy(CallInst &I) { - std::pair Result = - TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), getValue(I.getOperand(1)), DAG); - setValue(&I, Result.first); - DAG.setRoot(Result.second); + SDOperand Result = + TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), I.getOperand(2), + getValue(I.getOperand(1)), I.getOperand(1), DAG); + DAG.setRoot(Result); } From lattner at cs.uiuc.edu Tue Jul 5 14:59:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:59:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507051959.OAA03543@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.143 -> 1.144 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. 4. Now that we have Value*'s available in the lowering methods, pass them into any load/stores from the valist that are emitted --- Diffs of the changes: (+19 -18) X86ISelPattern.cpp | 37 +++++++++++++++++++------------------ 1 files changed, 19 insertions(+), 18 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.143 llvm/lib/Target/X86/X86ISelPattern.cpp:1.144 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.143 Tue Jul 5 12:50:16 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Jul 5 14:58:54 2005 @@ -175,13 +175,12 @@ bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); - + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); - + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -442,22 +441,24 @@ return std::make_pair(ResultVal, Chain); } -std::pair -X86TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, - SDOperand Dest) { +SDOperand +X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { // vastart just stores the address of the VarArgsFrameIndex slot. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, - DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); } -std::pair -X86TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { + +std::pair +X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, + Value *VAListV, const Type *ArgTy, + SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i32, Chain, VAList, DAG.getSrcValue(NULL)); - SDOperand Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, + SDOperand Val = DAG.getLoad(MVT::i32, Chain, + VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, DAG.getSrcValue(NULL)); unsigned Amt; if (ArgVT == MVT::i32) @@ -470,7 +471,7 @@ Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, DAG.getConstant(Amt, Val.getValueType())); Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAList, DAG.getSrcValue(NULL)); + Val, VAListP, DAG.getSrcValue(VAListV)); return std::make_pair(Result, Chain); } From lattner at cs.uiuc.edu Tue Jul 5 14:59:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:59:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200507051959.OAA03541@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.46 -> 1.47 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. 4. Now that we have Value*'s available in the lowering methods, pass them into any load/stores from the valist that are emitted --- Diffs of the changes: (+16 -27) IA64ISelPattern.cpp | 43 ++++++++++++++++--------------------------- 1 files changed, 16 insertions(+), 27 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.46 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.47 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.46 Wed Jun 22 16:04:42 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Tue Jul 5 14:58:53 2005 @@ -113,16 +113,11 @@ bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); - + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); - - virtual std::pair - LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG); + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); void restoreGP_SP_RP(MachineBasicBlock* BB) { @@ -379,21 +374,24 @@ return std::make_pair(TheCall, Chain); } -std::pair -IA64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { +SDOperand +IA64TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { // vastart just stores the address of the VarArgsFrameIndex slot. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, + VAListP, DAG.getSrcValue(VAListV)); } std::pair IA64TargetLowering:: -LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { +LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); - SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val, DAG.getSrcValue(NULL)); + SDOperand Val = DAG.getLoad(MVT::i64, Chain, + VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val, + DAG.getSrcValue(NULL)); unsigned Amt; if (ArgVT == MVT::i32 || ArgVT == MVT::f32) Amt = 8; @@ -405,19 +403,10 @@ Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, DAG.getConstant(Amt, Val.getValueType())); Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAList, DAG.getSrcValue(NULL)); + Val, VAListP, DAG.getSrcValue(VAListV)); return std::make_pair(Result, Chain); } -std::pair IA64TargetLowering:: -LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG) { - - assert(0 && "LowerFrameReturnAddress not done yet\n"); - abort(); -} - - namespace { //===--------------------------------------------------------------------===// From lattner at cs.uiuc.edu Tue Jul 5 14:59:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:59:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200507051959.OAA03549@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.146 -> 1.147 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. 4. Now that we have Value*'s available in the lowering methods, pass them into any load/stores from the valist that are emitted --- Diffs of the changes: (+38 -56) AlphaISelPattern.cpp | 94 ++++++++++++++++++++------------------------------- 1 files changed, 38 insertions(+), 56 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.146 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.147 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.146 Mon Jul 4 15:07:21 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Tue Jul 5 14:58:53 2005 @@ -156,21 +156,15 @@ bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); - + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, + SDOperand DestP, Value *DestV, + SelectionDAG &DAG); virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); - - std::pair - LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG); - - virtual std::pair - LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG); - + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + void restoreGP(MachineBasicBlock* BB) { BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); @@ -415,35 +409,34 @@ return std::make_pair(TheCall, Chain); } -std::pair -AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, - SDOperand Dest) { - // vastart just stores the address of the VarArgsBase and VarArgsOffset +SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + // vastart stores the address of the VarArgsBase and VarArgsOffset SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); - SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, - DAG.getSrcValue(NULL)); - SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, Dest, + SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); + SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, DAG.getConstant(8, MVT::i64)); - SDOperand S2 = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, - DAG.getConstant(VarArgsOffset, MVT::i64), SA2, - DAG.getSrcValue(NULL), MVT::i32); - return std::make_pair(S2, S2); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, + DAG.getConstant(VarArgsOffset, MVT::i64), SA2, + DAG.getSrcValue(VAListV, 8), MVT::i32); } std::pair AlphaTargetLowering:: -LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { - SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); - SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAList, +LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, + DAG.getSrcValue(VAListV)); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, DAG.getConstant(8, MVT::i64)); SDOperand Offset = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), - Tmp, DAG.getSrcValue(NULL), MVT::i32); + Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); if (ArgTy->isFloatingPoint()) { //if fp && Offset < 6*8, then subtract 6*8 from DataPtr SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, - DAG.getConstant(8*6, MVT::i64)); + DAG.getConstant(8*6, MVT::i64)); SDOperand CC = DAG.getSetCC(ISD::SETLT, MVT::i64, Offset, DAG.getConstant(8*6, MVT::i64)); DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); @@ -464,41 +457,30 @@ DAG.getConstant(8, MVT::i64)); SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Result.getValue(1), NewOffset, - Tmp, DAG.getSrcValue(NULL), MVT::i32); + Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); return std::make_pair(Result, Update); } -std::pair AlphaTargetLowering:: -LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, - SelectionDAG &DAG) { - //Default to returning the input list - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, Src, - DAG.getSrcValue(NULL)); + +SDOperand AlphaTargetLowering:: +LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, + Value *DestV, SelectionDAG &DAG) { + SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, + DAG.getSrcValue(SrcV)); SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, Dest, DAG.getSrcValue(NULL)); - SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, Src, + Val, DestP, DAG.getSrcValue(DestV)); + SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, DAG.getConstant(8, MVT::i64)); - Val = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Result, NP, DAG.getSrcValue(NULL), - MVT::i32); - SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, Dest, + Val = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Result, NP, + DAG.getSrcValue(SrcV, 8), MVT::i32); + SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, DAG.getConstant(8, MVT::i64)); - Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), - Val, NPD, DAG.getSrcValue(NULL), MVT::i32); - return std::make_pair(Result, Result); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), + Val, NPD, DAG.getSrcValue(DestV, 8), MVT::i32); } -std::pair AlphaTargetLowering:: -LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG) { - abort(); -} - - - - - namespace { //===--------------------------------------------------------------------===// From lattner at cs.uiuc.edu Tue Jul 5 14:59:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Jul 2005 14:59:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200507051959.OAA03551@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.96 -> 1.97 --- Log message: Make several cleanups to Andrews varargs change: 1. Pass Value*'s into lowering methods so that the proper pointers can be added to load/stores from the valist 2. Intrinsics that return void should only return a token chain, not a token chain/retval pair. 3. Rename LowerVAArgNext -> LowerVAArg, because VANext is long gone. 4. Now that we have Value*'s available in the lowering methods, pass them into any load/stores from the valist that are emitted --- Diffs of the changes: (+17 -19) PPC32ISelPattern.cpp | 36 +++++++++++++++++------------------- 1 files changed, 17 insertions(+), 19 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.96 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.97 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.96 Tue Jul 5 12:48:31 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Jul 5 14:58:53 2005 @@ -97,13 +97,13 @@ bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); - + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); - + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -463,26 +463,24 @@ return std::make_pair(TheCall, Chain); } -std::pair -PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, - SDOperand Dest) { +SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, - DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); } -std::pair PPC32TargetLowering:: -LowerVAArgNext(SDOperand Chain, SDOperand VAArgOp, - const Type *ArgTy, SelectionDAG &DAG) { +std::pair +PPC32TargetLowering::LowerVAArg(SDOperand Chain, + SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); SDOperand VAList = - DAG.getLoad(MVT::i32, Chain, VAArgOp, DAG.getSrcValue(NULL)); - SDOperand Result = DAG.getLoad(ArgVT, VAList.getValue(1), VAList, - DAG.getSrcValue(NULL)); + DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL)); unsigned Amt; if (ArgVT == MVT::i32 || ArgVT == MVT::f32) Amt = 4; @@ -494,7 +492,7 @@ VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, DAG.getConstant(Amt, VAList.getValueType())); Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - VAList, VAArgOp, DAG.getSrcValue(NULL)); + VAList, VAListP, DAG.getSrcValue(VAListV)); return std::make_pair(Result, Chain); } From natebegeman at mac.com Wed Jul 6 13:59:15 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Jul 2005 13:59:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200507061859.NAA05421@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.39 -> 1.40 --- Log message: First round of support for doing scalar FP using the SSE2 ISA extension and XMM registers. There are many known deficiencies and fixmes, which will be addressed ASAP. The major benefit of this work is that it will allow the LLVM register allocator to allocate FP registers across basic blocks. The x86 backend will still default to x87 style FP. To enable this work, you must pass -enable-sse-scalar-fp and either -sse2 or -sse3 to llc. An example before and after would be for: double foo(double *P) { double Sum = 0; int i; for (i = 0; i < 1000; ++i) Sum += P[i]; return Sum; } The inner loop looks like the following: x87: .LBB_foo_1: # no_exit fldl (%esp) faddl (%eax,%ecx,8) fstpl (%esp) incl %ecx cmpl $1000, %ecx #FP_REG_KILL jne .LBB_foo_1 # no_exit SSE2: addsd (%eax,%ecx,8), %xmm0 incl %ecx cmpl $1000, %ecx #FP_REG_KILL jne .LBB_foo_1 # no_exit --- Diffs of the changes: (+6 -0) TargetMachine.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.39 llvm/lib/Target/TargetMachine.cpp:1.40 --- llvm/lib/Target/TargetMachine.cpp:1.39 Fri May 13 14:48:34 2005 +++ llvm/lib/Target/TargetMachine.cpp Wed Jul 6 13:59:03 2005 @@ -27,6 +27,7 @@ bool NoExcessFPPrecision; int PatternISelTriState; bool UnsafeFPMath; + bool PICEnabled; }; namespace { cl::opt PrintCode("print-machineinstrs", @@ -52,6 +53,11 @@ cl::desc("Enable optimizations that may decrease FP precision"), cl::location(UnsafeFPMath), cl::init(false)); + cl::opt + EnablePIC("enable-pic", + cl::desc("Enable generation of position independant code"), + cl::location(PICEnabled), + cl::init(false)); }; //--------------------------------------------------------------------------- From natebegeman at mac.com Wed Jul 6 13:59:15 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Jul 2005 13:59:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h X86.td X86CodeEmitter.cpp X86ISelPattern.cpp X86InstrInfo.cpp X86InstrInfo.h X86InstrInfo.td X86RegisterInfo.cpp X86RegisterInfo.td X86TargetMachine.cpp Message-ID: <200507061859.NAA05443@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.32 -> 1.33 X86.td updated: 1.14 -> 1.15 X86CodeEmitter.cpp updated: 1.80 -> 1.81 X86ISelPattern.cpp updated: 1.144 -> 1.145 X86InstrInfo.cpp updated: 1.38 -> 1.39 X86InstrInfo.h updated: 1.46 -> 1.47 X86InstrInfo.td updated: 1.128 -> 1.129 X86RegisterInfo.cpp updated: 1.105 -> 1.106 X86RegisterInfo.td updated: 1.18 -> 1.19 X86TargetMachine.cpp updated: 1.80 -> 1.81 --- Log message: First round of support for doing scalar FP using the SSE2 ISA extension and XMM registers. There are many known deficiencies and fixmes, which will be addressed ASAP. The major benefit of this work is that it will allow the LLVM register allocator to allocate FP registers across basic blocks. The x86 backend will still default to x87 style FP. To enable this work, you must pass -enable-sse-scalar-fp and either -sse2 or -sse3 to llc. An example before and after would be for: double foo(double *P) { double Sum = 0; int i; for (i = 0; i < 1000; ++i) Sum += P[i]; return Sum; } The inner loop looks like the following: x87: .LBB_foo_1: # no_exit fldl (%esp) faddl (%eax,%ecx,8) fstpl (%esp) incl %ecx cmpl $1000, %ecx #FP_REG_KILL jne .LBB_foo_1 # no_exit SSE2: addsd (%eax,%ecx,8), %xmm0 incl %ecx cmpl $1000, %ecx #FP_REG_KILL jne .LBB_foo_1 # no_exit --- Diffs of the changes: (+382 -91) X86.h | 1 X86.td | 2 X86CodeEmitter.cpp | 14 + X86ISelPattern.cpp | 395 +++++++++++++++++++++++++++++++++++++++++---------- X86InstrInfo.cpp | 2 X86InstrInfo.h | 4 X86InstrInfo.td | 20 ++ X86RegisterInfo.cpp | 22 ++ X86RegisterInfo.td | 4 X86TargetMachine.cpp | 9 - 10 files changed, 382 insertions(+), 91 deletions(-) Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.32 llvm/lib/Target/X86/X86.h:1.33 --- llvm/lib/Target/X86/X86.h:1.32 Mon Jun 27 01:30:12 2005 +++ llvm/lib/Target/X86/X86.h Wed Jul 6 13:59:03 2005 @@ -28,6 +28,7 @@ }; extern X86VectorEnum X86Vector; +extern bool X86ScalarSSE; /// createX86SimpleInstructionSelector - This pass converts an LLVM function /// into a machine code representation in a very simple peep-hole fashion. The Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.14 llvm/lib/Target/X86/X86.td:1.15 --- llvm/lib/Target/X86/X86.td:1.14 Sun Oct 3 15:36:57 2004 +++ llvm/lib/Target/X86/X86.td Wed Jul 6 13:59:03 2005 @@ -61,7 +61,7 @@ def X86 : Target { // Specify the callee saved registers. - let CalleeSavedRegisters = [ESI, EDI, EBX, EBP]; + let CalleeSavedRegisters = [ESI, EDI, EBX, EBP, XMM4, XMM5, XMM6, XMM7]; // Yes, pointers are 32-bits in size. let PointerType = i32; Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.80 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.81 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.80 Thu May 19 00:54:33 2005 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Wed Jul 6 13:59:03 2005 @@ -361,8 +361,18 @@ // Emit the repeat opcode prefix as needed. if ((Desc.TSFlags & X86II::Op0Mask) == X86II::REP) MCE.emitByte(0xF3); - // Emit instruction prefixes if necessary - if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66);// Operand size... + // Emit the operand size opcode prefix as needed. + if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66); + + // Emit the double precision sse fp opcode prefix as needed. + if ((Desc.TSFlags & X86II::Op0Mask) == X86II::XD) { + MCE.emitByte(0xF2); MCE.emitByte(0x0F); + } + + // Emit the double precision sse fp opcode prefix as needed. + if ((Desc.TSFlags & X86II::Op0Mask) == X86II::XS) { + MCE.emitByte(0xF3); MCE.emitByte(0x0F); + } switch (Desc.TSFlags & X86II::Op0Mask) { case X86II::TB: Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.144 llvm/lib/Target/X86/X86ISelPattern.cpp:1.145 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.144 Tue Jul 5 14:58:54 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jul 6 13:59:03 2005 @@ -97,15 +97,13 @@ setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 // Set up the register classes. + // FIXME: Eliminate these two classes when legalize can handle promotions + // well. + addRegisterClass(MVT::i1, X86::R8RegisterClass); addRegisterClass(MVT::i8, X86::R8RegisterClass); addRegisterClass(MVT::i16, X86::R16RegisterClass); addRegisterClass(MVT::i32, X86::R32RegisterClass); - addRegisterClass(MVT::f64, X86::RFPRegisterClass); - - // FIXME: Eliminate these two classes when legalize can handle promotions - // well. -/**/ addRegisterClass(MVT::i1, X86::R8RegisterClass); - + setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); @@ -123,7 +121,7 @@ setOperationAction(ISD::CTPOP , MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand); setOperationAction(ISD::CTLZ , MVT::i32 , Expand); - + setOperationAction(ISD::READIO , MVT::i1 , Expand); setOperationAction(ISD::READIO , MVT::i8 , Expand); setOperationAction(ISD::READIO , MVT::i16 , Expand); @@ -132,24 +130,47 @@ setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); - - if (!UnsafeFPMath) { - setOperationAction(ISD::FSIN , MVT::f64 , Expand); - setOperationAction(ISD::FCOS , MVT::f64 , Expand); - } - + // These should be promoted to a larger select which is supported. -/**/ setOperationAction(ISD::SELECT , MVT::i1 , Promote); + setOperationAction(ISD::SELECT , MVT::i1 , Promote); setOperationAction(ISD::SELECT , MVT::i8 , Promote); - + + if (X86ScalarSSE) { + // Set up the FP register classes. + addRegisterClass(MVT::f32, X86::RXMMRegisterClass); + addRegisterClass(MVT::f64, X86::RXMMRegisterClass); + + setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); + setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); + + // We don't support sin/cos/sqrt/fmod + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FABS , MVT::f64, Expand); + setOperationAction(ISD::FNEG , MVT::f64, Expand); + setOperationAction(ISD::SREM , MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FABS , MVT::f32, Expand); + setOperationAction(ISD::FNEG , MVT::f32, Expand); + setOperationAction(ISD::SREM , MVT::f32, Expand); + } else { + // Set up the FP register classes. + addRegisterClass(MVT::f64, X86::RFPRegisterClass); + + if (!UnsafeFPMath) { + setOperationAction(ISD::FSIN , MVT::f64 , Expand); + setOperationAction(ISD::FCOS , MVT::f64 , Expand); + } + + addLegalFPImmediate(+0.0); // FLD0 + addLegalFPImmediate(+1.0); // FLD1 + addLegalFPImmediate(-0.0); // FLD0/FCHS + addLegalFPImmediate(-1.0); // FLD1/FCHS + } computeRegisterProperties(); - - addLegalFPImmediate(+0.0); // FLD0 - addLegalFPImmediate(+1.0); // FLD1 - addLegalFPImmediate(-0.0); // FLD0/FCHS - addLegalFPImmediate(-1.0); // FLD1/FCHS } - + // Return the number of bytes that a function should pop when it returns (in // addition to the space used by the return address). // @@ -400,7 +421,10 @@ RetVals.push_back(MVT::i32); break; case MVT::f32: - RetVals.push_back(MVT::f64); + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); break; case MVT::i64: RetVals.push_back(MVT::i32); @@ -805,7 +829,10 @@ RetVals.push_back(MVT::i32); break; case MVT::f32: - RetVals.push_back(MVT::f64); + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); break; case MVT::i64: RetVals.push_back(MVT::i32); @@ -1041,6 +1068,8 @@ BuildMI(BB, X86::MOV32rr, 1, LI->second).addReg(LI->first); } else if (RC == X86::RFPRegisterClass) { BuildMI(BB, X86::FpMOV, 1, LI->second).addReg(LI->first); + } else if (RC == X86::RXMMRegisterClass) { + BuildMI(BB, X86::MOVAPDrr, 1, LI->second).addReg(LI->first); } else { assert(0 && "Unknown regclass!"); } @@ -1641,6 +1670,11 @@ /*missing*/0, /*missing*/0, X86::FCMOVB , X86::FCMOVBE, X86::FCMOVA , X86::FCMOVAE, X86::FCMOVP , X86::FCMOVNP }; + static const unsigned SSE_CMOVTAB[] = { + 0 /* CMPEQSS */, 4 /* CMPNEQSS */, 1 /* CMPLTSS */, 2 /* CMPLESS */, + 2 /* CMPLESS */, 1 /* CMPLTSS */, /*missing*/0, /*missing*/0, + /*missing*/0, /*missing*/0, /*missing*/0, /*missing*/0 + }; if (SetCCSDNode *SetCC = dyn_cast(Cond)) { if (MVT::isInteger(SetCC->getOperand(0).getValueType())) { @@ -1657,6 +1691,20 @@ case ISD::SETULE: CondCode = BE; break; case ISD::SETUGE: CondCode = AE; break; } + } else if (X86ScalarSSE) { + switch (SetCC->getCondition()) { + default: assert(0 && "Unknown scalar fp comparison!"); + case ISD::SETEQ: CondCode = EQ; break; + case ISD::SETNE: CondCode = NE; break; + case ISD::SETULT: + case ISD::SETLT: CondCode = LT; break; + case ISD::SETULE: + case ISD::SETLE: CondCode = LE; break; + case ISD::SETUGT: + case ISD::SETGT: CondCode = GT; break; + case ISD::SETUGE: + case ISD::SETGE: CondCode = GE; break; + } } else { // On a floating point condition, the flags are set as follows: // ZF PF CF op @@ -1693,6 +1741,79 @@ } } + // There's no SSE equivalent of FCMOVE. In some cases we can fake it up, in + // Others we will have to do the PowerPC thing and generate an MBB for the + // true and false values and select between them with a PHI. + if (X86ScalarSSE) { + if (CondCode != NOT_SET) { + unsigned CMPSOpc = (SVT == MVT::f64) ? X86::CMPSDrr : X86::CMPSSrr; + unsigned CMPSImm = SSE_CMOVTAB[CondCode]; + // FIXME check for min + // FIXME check for max + // FIXME check for reverse + unsigned LHS = SelectExpr(Cond.getOperand(0)); + unsigned RHS = SelectExpr(Cond.getOperand(1)); + // emit compare mask + unsigned MaskReg = MakeReg(SVT); + BuildMI(BB, CMPSOpc, 3, MaskReg).addReg(LHS).addReg(RHS).addImm(CMPSImm); + // emit and with mask + unsigned TrueMask = MakeReg(SVT); + unsigned AndOpc = (SVT == MVT::f32) ? X86::ANDPSrr : X86::ANDPDrr; + BuildMI(BB, AndOpc, 2, TrueMask).addReg(RTrue).addReg(MaskReg); + // emit and with inverse mask + unsigned FalseMask = MakeReg(SVT); + unsigned AndnOpc = (SVT == MVT::f32) ? X86::ANDNPSrr : X86::ANDNPDrr; + BuildMI(BB, AndnOpc, 2, FalseMask).addReg(RFalse).addReg(MaskReg); + // emit or into dest reg + unsigned OROpc = (SVT == MVT::f32) ? X86::ORPSrr : X86::ORPDrr; + BuildMI(BB, OROpc, 2, RDest).addReg(TrueMask).addReg(FalseMask); + return; + } else { + // do the test and branch thing + // Get the condition into the zero flag. + unsigned CondReg = SelectExpr(Cond); + BuildMI(BB, X86::TEST8rr, 2).addReg(CondReg).addReg(CondReg); + + // Create an iterator with which to insert the MBB for copying the false + // value and the MBB to hold the PHI instruction for this SetCC. + MachineBasicBlock *thisMBB = BB; + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + ilist::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY ccX, r1, r2 + // bCC sinkMBB + // fallthrough --> copy0MBB + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + BuildMI(BB, X86::JNE, 1).addMBB(sinkMBB); + MachineFunction *F = BB->getParent(); + F->getBasicBlockList().insert(It, copy0MBB); + F->getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = sinkMBB; + BuildMI(BB, X86::PHI, 4, RDest).addReg(RFalse) + .addMBB(copy0MBB).addReg(RTrue).addMBB(thisMBB); + } + return; + } + unsigned Opc = 0; if (CondCode != NOT_SET) { switch (SVT) { @@ -1702,7 +1823,7 @@ case MVT::f64: Opc = CMOVTABFP[CondCode]; break; } } - + // Finally, if we weren't able to fold this, just emit the condition and test // it. if (CondCode == NOT_SET || Opc == 0) { @@ -1757,8 +1878,8 @@ return; } } else if (ConstantFPSDNode *CN = dyn_cast(RHS)) { - if (CN->isExactlyValue(+0.0) || - CN->isExactlyValue(-0.0)) { + if (!X86ScalarSSE && (CN->isExactlyValue(+0.0) || + CN->isExactlyValue(-0.0))) { unsigned Reg = SelectExpr(LHS); BuildMI(BB, X86::FTST, 1).addReg(Reg); BuildMI(BB, X86::FNSTSW8r, 0); @@ -1791,7 +1912,8 @@ case MVT::i8: Opc = X86::CMP8rr; break; case MVT::i16: Opc = X86::CMP16rr; break; case MVT::i32: Opc = X86::CMP32rr; break; - case MVT::f64: Opc = X86::FUCOMIr; break; + case MVT::f32: Opc = X86::UCOMISSrr; break; + case MVT::f64: Opc = X86ScalarSSE ? X86::UCOMISDrr : X86::FUCOMIr; break; } unsigned Tmp1, Tmp2; if (getRegPressure(LHS) > getRegPressure(RHS)) { @@ -2040,6 +2162,11 @@ default: Node->dump(); assert(0 && "Node not handled!\n"); + case ISD::FP_EXTEND: + assert(X86ScalarSSE && "Scalar SSE FP must be enabled to use f32"); + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, X86::CVTSS2SDrr, 1, Result).addReg(Tmp1); + return Result; case ISD::CopyFromReg: Select(N.getOperand(0)); if (Result == 1) { @@ -2212,6 +2339,37 @@ case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: { + Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register + unsigned PromoteOpcode = 0; + + // We can handle any sint to fp, and 8 and 16 uint to fp with the direct + // sse conversion instructions. + if (X86ScalarSSE) { + MVT::ValueType SrcTy = N.getOperand(0).getValueType(); + MVT::ValueType DstTy = N.getValueType(); + switch (SrcTy) { + case MVT::i1: + case MVT::i8: + PromoteOpcode = (N.getOpcode() == ISD::UINT_TO_FP) ? + X86::MOVZX32rr8 : X86::MOVSX32rr8; + break; + case MVT::i16: + PromoteOpcode = (N.getOpcode() == ISD::UINT_TO_FP) ? + X86::MOVZX32rr16 : X86::MOVSX32rr16; + break; + default: + assert(N.getOpcode() != ISD::UINT_TO_FP); + break; + } + if (PromoteOpcode) { + BuildMI(BB, PromoteOpcode, 1, Tmp2).addReg(Tmp1); + Tmp1 = Tmp2; + } + Opc = (DstTy == MVT::f64) ? X86::CVTSI2SDrr : X86::CVTSI2SSrr; + BuildMI(BB, Opc, 1, Result).addReg(Tmp1); + return Result; + } + // FIXME: Most of this grunt work should be done by legalize! ContainsFPCode = true; @@ -2221,8 +2379,6 @@ // MVT::ValueType PromoteType = MVT::Other; MVT::ValueType SrcTy = N.getOperand(0).getValueType(); - unsigned PromoteOpcode = 0; - unsigned RealDestReg = Result; switch (SrcTy) { case MVT::i1: case MVT::i8: @@ -2245,8 +2401,6 @@ break; } - Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register - if (PromoteType != MVT::Other) { Tmp2 = MakeReg(PromoteType); BuildMI(BB, PromoteOpcode, 1, Tmp2).addReg(Tmp1); @@ -2272,31 +2426,28 @@ break; default: break; // No promotion required. } - - if (Node->getOpcode() == ISD::UINT_TO_FP && Result != RealDestReg) { - // If this is a cast from uint -> double, we need to be careful when if - // the "sign" bit is set. If so, we don't want to make a negative number, - // we want to make a positive number. Emit code to add an offset if the - // sign bit is set. - - // Compute whether the sign bit is set by shifting the reg right 31 bits. - unsigned IsNeg = MakeReg(MVT::i32); - BuildMI(BB, X86::SHR32ri, 2, IsNeg).addReg(Tmp1).addImm(31); - - // Create a CP value that has the offset in one word and 0 in the other. - static ConstantInt *TheOffset = ConstantUInt::get(Type::ULongTy, - 0x4f80000000000000ULL); - unsigned CPI = F->getConstantPool()->getConstantPoolIndex(TheOffset); - BuildMI(BB, X86::FADD32m, 5, RealDestReg).addReg(Result) - .addConstantPoolIndex(CPI).addZImm(4).addReg(IsNeg).addSImm(0); - } - return RealDestReg; + return Result; } case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: { // FIXME: Most of this grunt work should be done by legalize! Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register + // If the target supports SSE2 and is performing FP operations in SSE regs + // instead of the FP stack, then we can use the efficient CVTSS2SI and + // CVTSD2SI instructions. + if (ISD::FP_TO_SINT == N.getOpcode() && X86ScalarSSE) { + if (MVT::f32 == N.getOperand(0).getValueType()) { + BuildMI(BB, X86::CVTSS2SIrr, 1, Result).addReg(Tmp1); + } else if (MVT::f64 == N.getOperand(0).getValueType()) { + BuildMI(BB, X86::CVTSD2SIrr, 1, Result).addReg(Tmp1); + } else { + assert(0 && "Not an f32 or f64?"); + abort(); + } + return Result; + } + // Change the floating point control register to use "round towards zero" // mode when truncating to an integer value. // @@ -2385,9 +2536,15 @@ case MVT::i8: Opc = X86::ADD8rm; break; case MVT::i16: Opc = X86::ADD16rm; break; case MVT::i32: Opc = X86::ADD32rm; break; + case MVT::f32: Opc = X86::ADDSSrm; break; case MVT::f64: // For F64, handle promoted load operations (from F32) as well! - Opc = Op1.getOpcode() == ISD::LOAD ? X86::FADD64m : X86::FADD32m; + if (X86ScalarSSE) { + assert(Op1.getOpcode() == ISD::LOAD && "SSE load not promoted"); + Opc = X86::ADDSDrm; + } else { + Opc = Op1.getOpcode() == ISD::LOAD ? X86::FADD64m : X86::FADD32m; + } break; } X86AddressMode AM; @@ -2458,7 +2615,8 @@ case MVT::i8: Opc = X86::ADD8rr; break; case MVT::i16: Opc = X86::ADD16rr; break; case MVT::i32: Opc = X86::ADD32rr; break; - case MVT::f64: Opc = X86::FpADD; break; + case MVT::f32: Opc = X86::ADDSSrr; break; + case MVT::f64: Opc = X86ScalarSSE ? X86::ADDSDrr : X86::FpADD; break; } if (getRegPressure(Op0) > getRegPressure(Op1)) { @@ -2472,18 +2630,29 @@ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; + case ISD::FSQRT: + Tmp1 = SelectExpr(Node->getOperand(0)); + if (X86ScalarSSE) { + Opc = (N.getValueType() == MVT::f32) ? X86::SQRTSSrr : X86::SQRTSDrr; + BuildMI(BB, Opc, 1, Result).addReg(Tmp1); + } else { + BuildMI(BB, X86::FSQRT, 1, Result).addReg(Tmp1); + } + return Result; + + // FIXME: + // Once we can spill 16 byte constants into the constant pool, we can + // implement SSE equivalents of FABS and FCHS. case ISD::FABS: case ISD::FNEG: case ISD::FSIN: case ISD::FCOS: - case ISD::FSQRT: assert(N.getValueType()==MVT::f64 && "Illegal type for this operation"); Tmp1 = SelectExpr(Node->getOperand(0)); switch (N.getOpcode()) { default: assert(0 && "Unreachable!"); case ISD::FABS: BuildMI(BB, X86::FABS, 1, Result).addReg(Tmp1); break; case ISD::FNEG: BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1); break; - case ISD::FSQRT: BuildMI(BB, X86::FSQRT, 1, Result).addReg(Tmp1); break; case ISD::FSIN: BuildMI(BB, X86::FSIN, 1, Result).addReg(Tmp1); break; case ISD::FCOS: BuildMI(BB, X86::FCOS, 1, Result).addReg(Tmp1); break; } @@ -2550,11 +2719,21 @@ X86::SUB8rm, X86::SUB16rm, X86::SUB32rm, X86::FSUB32m, X86::FSUB64m, X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::FpSUB , X86::FpSUB, }; + static const unsigned SSE_SUBTab[] = { + X86::SUB8ri, X86::SUB16ri, X86::SUB32ri, 0, 0, + X86::SUB8rm, X86::SUB16rm, X86::SUB32rm, X86::SUBSSrm, X86::SUBSDrm, + X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::SUBSSrr, X86::SUBSDrr, + }; static const unsigned MULTab[] = { 0, X86::IMUL16rri, X86::IMUL32rri, 0, 0, 0, X86::IMUL16rm , X86::IMUL32rm, X86::FMUL32m, X86::FMUL64m, 0, X86::IMUL16rr , X86::IMUL32rr, X86::FpMUL , X86::FpMUL, }; + static const unsigned SSE_MULTab[] = { + 0, X86::IMUL16rri, X86::IMUL32rri, 0, 0, + 0, X86::IMUL16rm , X86::IMUL32rm, X86::MULSSrm, X86::MULSDrm, + 0, X86::IMUL16rr , X86::IMUL32rr, X86::MULSSrr, X86::MULSDrr, + }; static const unsigned ANDTab[] = { X86::AND8ri, X86::AND16ri, X86::AND32ri, 0, 0, X86::AND8rm, X86::AND16rm, X86::AND32rm, 0, 0, @@ -2637,8 +2816,8 @@ } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); - case ISD::SUB: Opc = SUBTab[Opc]; break; - case ISD::MUL: Opc = MULTab[Opc]; break; + case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; case ISD::XOR: Opc = XORTab[Opc]; break; @@ -2656,7 +2835,7 @@ goto FoldOps; } else { // For FP, emit 'reverse' subract, with a memory operand. - if (N.getValueType() == MVT::f64) { + if (N.getValueType() == MVT::f64 && !X86ScalarSSE) { if (Op0.getOpcode() == ISD::EXTLOAD) Opc = X86::FSUBR32m; else @@ -2678,13 +2857,17 @@ case MVT::i8: Opc = 5; break; case MVT::i16: Opc = 6; break; case MVT::i32: Opc = 7; break; + case MVT::f32: Opc = 8; break; // For F64, handle promoted load operations (from F32) as well! - case MVT::f64: Opc = Op1.getOpcode() == ISD::LOAD ? 9 : 8; break; + case MVT::f64: + assert((!X86ScalarSSE || Op1.getOpcode() == ISD::LOAD) && + "SSE load should have been promoted"); + Opc = Op1.getOpcode() == ISD::LOAD ? 9 : 8; break; } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); - case ISD::SUB: Opc = SUBTab[Opc]; break; - case ISD::MUL: Opc = MULTab[Opc]; break; + case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; case ISD::XOR: Opc = XORTab[Opc]; break; @@ -2725,8 +2908,8 @@ } switch (Node->getOpcode()) { default: assert(0 && "Unreachable!"); - case ISD::SUB: Opc = SUBTab[Opc]; break; - case ISD::MUL: Opc = MULTab[Opc]; break; + case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break; + case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break; case ISD::AND: Opc = ANDTab[Opc]; break; case ISD::OR: Opc = ORTab[Opc]; break; case ISD::XOR: Opc = XORTab[Opc]; break; @@ -2844,7 +3027,7 @@ if (N.getOpcode() == ISD::SDIV) { // We can fold loads into FpDIVs, but not really into any others. - if (N.getValueType() == MVT::f64) { + if (N.getValueType() == MVT::f64 || !X86ScalarSSE) { // Check for reversed and unreversed DIV. if (isFoldableLoad(N.getOperand(0), N.getOperand(1), true)) { if (N.getOperand(0).getOpcode() == ISD::EXTLOAD) @@ -2962,8 +3145,12 @@ ClrOpcode = X86::MOV32ri; SExtOpcode = X86::CDQ; break; + case MVT::f32: + BuildMI(BB, X86::DIVSSrr, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; case MVT::f64: - BuildMI(BB, X86::FpDIV, 2, Result).addReg(Tmp1).addReg(Tmp2); + Opc = X86ScalarSSE ? X86::DIVSDrr : X86::FpDIV; + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; } @@ -3108,7 +3295,15 @@ case MVT::i8: Opc = X86::MOV8rm; break; case MVT::i16: Opc = X86::MOV16rm; break; case MVT::i32: Opc = X86::MOV32rm; break; - case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break; + case MVT::f32: Opc = X86::MOVSSrm; break; + case MVT::f64: + if (X86ScalarSSE) { + Opc = X86::MOVSDrm; + } else { + Opc = X86::FLD64m; + ContainsFPCode = true; + } + break; } if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(1))){ @@ -3385,9 +3580,21 @@ BuildMI(BB, X86::MOV32rr, 1, Result+1).addReg(X86::EDX); break; case MVT::f64: // Floating-point return values live in %ST(0) - ContainsFPCode = true; - BuildMI(BB, X86::FpGETRESULT, 1, Result); - break; + if (X86ScalarSSE) { + ContainsFPCode = true; + BuildMI(BB, X86::FpGETRESULT, 1, X86::FP0); + + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size); + addFrameReference(BuildMI(BB, X86::FST64m, 5), FrameIdx).addReg(X86::FP0); + addFrameReference(BuildMI(BB, X86::MOVSDrm, 4, Result), FrameIdx); + break; + } else { + ContainsFPCode = true; + BuildMI(BB, X86::FpGETRESULT, 1, Result); + break; + } } return Result+N.ResNo-1; } @@ -3977,7 +4184,15 @@ case MVT::i8: Opc = X86::MOV8rr; break; case MVT::i16: Opc = X86::MOV16rr; break; case MVT::i32: Opc = X86::MOV32rr; break; - case MVT::f64: Opc = X86::FpMOV; ContainsFPCode = true; break; + case MVT::f32: Opc = X86::MOVAPSrr; break; + case MVT::f64: + if (X86ScalarSSE) { + Opc = X86::MOVAPDrr; + } else { + Opc = X86::FpMOV; + ContainsFPCode = true; + } + break; } BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1); } @@ -4018,12 +4233,38 @@ } switch (N.getOperand(1).getValueType()) { default: assert(0 && "All other types should have been promoted!!"); + case MVT::f32: + if (X86ScalarSSE) { + // Spill the value to memory and reload it into top of stack. + unsigned Size = MVT::getSizeInBits(MVT::f32)/8; + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size); + addFrameReference(BuildMI(BB, X86::MOVSSmr, 5), FrameIdx).addReg(Tmp1); + addFrameReference(BuildMI(BB, X86::FLD32m, 4, X86::FP0), FrameIdx); + BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0); + ContainsFPCode = true; + } else { + assert(0 && "MVT::f32 only legal with scalar sse fp"); + abort(); + } + break; case MVT::f64: - BuildMI(BB, X86::FpSETRESULT, 1).addReg(Tmp1); - break; + if (X86ScalarSSE) { + // Spill the value to memory and reload it into top of stack. + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size); + addFrameReference(BuildMI(BB, X86::MOVSDmr, 5), FrameIdx).addReg(Tmp1); + addFrameReference(BuildMI(BB, X86::FLD64m, 4, X86::FP0), FrameIdx); + BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0); + ContainsFPCode = true; + } else { + BuildMI(BB, X86::FpSETRESULT, 1).addReg(Tmp1); + } + break; case MVT::i32: - BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Tmp1); - break; + BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Tmp1); + break; } break; case 1: @@ -4144,7 +4385,9 @@ switch (StoredTy) { default: assert(0 && "Cannot truncstore this type!"); case MVT::i1: Opc = X86::MOV8mr; break; - case MVT::f32: Opc = X86::FST32m; break; + case MVT::f32: + assert(!X86ScalarSSE && "Cannot truncstore scalar SSE regs"); + Opc = X86::FST32m; break; } std::vector > RP; @@ -4176,7 +4419,6 @@ case MVT::i8: Opc = X86::MOV8mi; break; case MVT::i16: Opc = X86::MOV16mi; break; case MVT::i32: Opc = X86::MOV32mi; break; - case MVT::f64: break; } if (Opc) { if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(2))) { @@ -4215,7 +4457,8 @@ case MVT::i8: Opc = X86::MOV8mr; break; case MVT::i16: Opc = X86::MOV16mr; break; case MVT::i32: Opc = X86::MOV32mr; break; - case MVT::f64: Opc = X86::FST64m; break; + case MVT::f32: Opc = X86::MOVSSmr; break; + case MVT::f64: Opc = X86ScalarSSE ? X86::MOVSDmr : X86::FST64m; break; } std::vector > RP; Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.38 llvm/lib/Target/X86/X86InstrInfo.cpp:1.39 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.38 Thu Apr 21 18:38:14 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Jul 6 13:59:04 2005 @@ -28,7 +28,7 @@ unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr || - oc == X86::FpMOV) { + oc == X86::FpMOV || oc == X86::MOVAPDrr) { assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.46 llvm/lib/Target/X86/X86InstrInfo.h:1.47 --- llvm/lib/Target/X86/X86InstrInfo.h:1.46 Thu Apr 21 18:38:14 2005 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed Jul 6 13:59:04 2005 @@ -107,6 +107,10 @@ DA = 5 << Op0Shift, DB = 6 << Op0Shift, DC = 7 << Op0Shift, DD = 8 << Op0Shift, DE = 9 << Op0Shift, DF = 10 << Op0Shift, + + // XS, XD - These prefix codes are for single and double precision scalar + // floating point operations performed in the SSE registers. + XD = 11 << Op0Shift, XS = 12 << Op0Shift, //===------------------------------------------------------------------===// // This two-bit field describes the size of an immediate operand. Zero is Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.128 llvm/lib/Target/X86/X86InstrInfo.td:1.129 --- llvm/lib/Target/X86/X86InstrInfo.td:1.128 Mon Jun 27 16:20:31 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jul 6 13:59:04 2005 @@ -187,7 +187,8 @@ // let isCall = 1 in // All calls clobber the non-callee saved registers... - let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0] in { + let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, + XMM0, XMM1, XMM2, XMM3] in { def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst">; def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst">; def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst">; @@ -1436,6 +1437,23 @@ "cvtss2sd {$src, $dst|$dst, $src}">, XD; def CVTSS2SDrm: I<0x5A, MRMSrcMem, (ops R32:$dst, f32mem:$src), "cvtss2sd {$src, $dst|$dst, $src}">, XD; +def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops R32:$dst, RXMM:$src), + "cvtsi2ss {$src, $dst|$dst, $src}">, XS; +def CVTSI2SSrm: I<0x2A, MRMSrcMem, (ops R32:$dst, f32mem:$src), + "cvtsi2ss {$src, $dst|$dst, $src}">, XS; +def CVTSI2SDrr: I<0x2A, MRMSrcReg, (ops R32:$dst, RXMM:$src), + "cvtsi2sd {$src, $dst|$dst, $src}">, XD; +def CVTSI2SDrm: I<0x2A, MRMSrcMem, (ops R32:$dst, f64mem:$src), + "cvtsi2sd {$src, $dst|$dst, $src}">, XD; + +def SQRTSSrm : I<0x51, MRMSrcMem, (ops RXMM:$dst, f32mem:$src), + "subss {$src, $dst|$dst, $src}">, XS; +def SQRTSSrr : I<0x51, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), + "subss {$src, $dst|$dst, $src}">, XS; +def SQRTSDrm : I<0x51, MRMSrcMem, (ops RXMM:$dst, f64mem:$src), + "subsd {$src, $dst|$dst, $src}">, XD; +def SQRTSDrr : I<0x51, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), + "subsd {$src, $dst|$dst, $src}">, XD; def UCOMISDrr: I<0x2E, MRMSrcReg, (ops RXMM:$dst, RXMM:$src), "ucomisd {$src, $dst|$dst, $src}">, TB, OpSize; Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.105 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.106 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.105 Sun May 15 00:49:58 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Jul 6 13:59:04 2005 @@ -52,6 +52,7 @@ case 32: return 2; case 64: return 3; // FP in 64-bit spill mode. case 80: return 4; // FP in 80-bit spill mode. + case 128: return 5; // XMM reg in 128 bit mode. } } @@ -59,18 +60,24 @@ MachineBasicBlock::iterator MI, unsigned SrcReg, int FrameIdx) const { static const unsigned Opcode[] = - { X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST64m, X86::FSTP80m }; + { X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST64m, X86::FSTP80m, + X86::MOVAPDmr }; unsigned Idx = getIdx(getSpillSize(SrcReg)); - addFrameReference(BuildMI(MBB, MI, Opcode[Idx], 5), FrameIdx).addReg(SrcReg); + unsigned Opc = Opcode[Idx]; + if (X86ScalarSSE && Opc == X86::FST64m) Opc = X86::MOVSDmr; + addFrameReference(BuildMI(MBB, MI, Opc, 5), FrameIdx).addReg(SrcReg); } void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx)const{ static const unsigned Opcode[] = - { X86::MOV8rm, X86::MOV16rm, X86::MOV32rm, X86::FLD64m, X86::FLD80m }; + { X86::MOV8rm, X86::MOV16rm, X86::MOV32rm, X86::FLD64m, X86::FLD80m, + X86::MOVAPDrm }; unsigned Idx = getIdx(getSpillSize(DestReg)); - addFrameReference(BuildMI(MBB, MI, Opcode[Idx], 4, DestReg), FrameIdx); + unsigned Opc = Opcode[Idx]; + if (X86ScalarSSE && Opc == X86::FLD64m) Opc = X86::MOVSDrm; + addFrameReference(BuildMI(MBB, MI, Opc, 4, DestReg), FrameIdx); } void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, @@ -78,8 +85,11 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const { static const unsigned Opcode[] = - { X86::MOV8rr, X86::MOV16rr, X86::MOV32rr, X86::FpMOV, X86::FpMOV }; - BuildMI(MBB, MI, Opcode[getIdx(RC->getSize()*8)], 1, DestReg).addReg(SrcReg); + { X86::MOV8rr, X86::MOV16rr, X86::MOV32rr, X86::FpMOV, X86::FpMOV, + X86::MOVAPDrr }; + unsigned Opc = Opcode[getIdx(RC->getSize()*8)]; + if (X86ScalarSSE && Opc == X86::FpMOV) Opc = X86::MOVAPDrr; + BuildMI(MBB, MI, Opc, 1, DestReg).addReg(SrcReg); } static MachineInstr *MakeMInst(unsigned Opcode, unsigned FrameIndex, Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.18 llvm/lib/Target/X86/X86RegisterInfo.td:1.19 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.18 Mon Jun 27 16:20:31 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.td Wed Jul 6 13:59:04 2005 @@ -99,8 +99,8 @@ // FIXME: These registers can contain both integer and fp values. We should // figure out the right way to deal with that. For now, since they'll be used // for scalar FP, they are being declared f64 -def RXMM : RegisterClass; +def RXMM : RegisterClass; // FIXME: This sets up the floating point register files as though they are f64 // values, though they really are f80 values. This will cause us to spill Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.80 llvm/lib/Target/X86/X86TargetMachine.cpp:1.81 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.80 Mon Jun 27 01:30:12 2005 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Wed Jul 6 13:59:04 2005 @@ -26,6 +26,7 @@ using namespace llvm; X86VectorEnum llvm::X86Vector = NoSSE; +bool llvm::X86ScalarSSE = false; /// X86TargetMachineModule - Note that this is used on hosts that cannot link /// in a library unless there are references into the library. In particular, @@ -41,8 +42,11 @@ cl::opt DisableOutput("disable-x86-llc-output", cl::Hidden, cl::desc("Disable the X86 asm printer, for use " "when profiling the code generator.")); + cl::opt EnableSSEFP("enable-sse-scalar-fp", + cl::desc("Perform FP math in SSE regs instead of the FP stack"), + cl::location(X86ScalarSSE), + cl::init(false)); -#if 0 // FIXME: This should eventually be handled with target triples and // subtarget support! cl::opt @@ -54,7 +58,6 @@ clEnumValN(SSE3, "sse3", " Enable SSE, SSE2, and SSE3 support"), clEnumValEnd), cl::location(X86Vector), cl::init(NoSSE)); -#endif // Register the target. RegisterTarget X("x86", " IA-32 (Pentium and above)"); @@ -91,6 +94,8 @@ : TargetMachine("X86", IL, true, 4, 4, 4, 4, 4), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -4), JITInfo(*this) { + // Scalar SSE FP requires at least SSE2 + X86ScalarSSE &= X86Vector >= SSE2; } From natebegeman at mac.com Thu Jul 7 01:32:13 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 7 Jul 2005 01:32:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507070632.BAA10235@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.145 -> 1.146 --- Log message: Fix a typo in my checkin today that caused regressions. Oops! --- Diffs of the changes: (+1 -1) X86ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.145 llvm/lib/Target/X86/X86ISelPattern.cpp:1.146 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.145 Wed Jul 6 13:59:03 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Jul 7 01:32:01 2005 @@ -3027,7 +3027,7 @@ if (N.getOpcode() == ISD::SDIV) { // We can fold loads into FpDIVs, but not really into any others. - if (N.getValueType() == MVT::f64 || !X86ScalarSSE) { + if (N.getValueType() == MVT::f64 && !X86ScalarSSE) { // Check for reversed and unreversed DIV. if (isFoldableLoad(N.getOperand(0), N.getOperand(1), true)) { if (N.getOperand(0).getOpcode() == ISD::EXTLOAD) From lattner at cs.uiuc.edu Thu Jul 7 02:00:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 02:00:49 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ELFWriter.h Message-ID: <200507070700.CAA11774@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ELFWriter.h updated: 1.1 -> 1.2 --- Log message: Add support for building/representing the symbol table, add some enum constants --- Diffs of the changes: (+56 -7) ELFWriter.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 56 insertions(+), 7 deletions(-) Index: llvm/include/llvm/CodeGen/ELFWriter.h diff -u llvm/include/llvm/CodeGen/ELFWriter.h:1.1 llvm/include/llvm/CodeGen/ELFWriter.h:1.2 --- llvm/include/llvm/CodeGen/ELFWriter.h:1.1 Mon Jun 27 01:28:45 2005 +++ llvm/include/llvm/CodeGen/ELFWriter.h Thu Jul 7 02:00:37 2005 @@ -86,10 +86,14 @@ unsigned Info; unsigned Align; unsigned EntSize; - ELFSection() : Type(0), Flags(0), Addr(0), Offset(0), Size(0), Link(0), - Info(0), Align(0), EntSize(0) { - } - ELFSection(const char *name, unsigned offset) + + enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3, + SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7, + SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11 }; + enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2 }; + enum { SHF_WRITE = 1, SHF_ALLOC = 2, SHF_EXECINSTR = 4 }; + + ELFSection(const char *name = "", unsigned offset = 0) : Name(name), Type(0), Flags(0), Addr(0), Offset(offset), Size(0), Link(0), Info(0), Align(0), EntSize(0) { } @@ -100,6 +104,41 @@ /// is constructed from this info. std::vector SectionList; + /// ELFSym - This struct contains information about each symbol that is + /// added to logical symbol table for the module. This is eventually + /// turned into a real symbol table in the file. + struct ELFSym { + GlobalValue *GV; // The global value this corresponds to. + //std::string Name; // Name of the symbol. + unsigned NameIdx; // Index in .strtab of name, once emitted. + uint64_t Value; + unsigned Size; + unsigned char Info; + unsigned char Other; + unsigned short SectionIdx; + + enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 }; + enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3, + STT_FILE = 4 }; + ELFSym(GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0), + Other(0), SectionIdx(0) {} + + void SetBind(unsigned X) { + assert(X == (X & 0xF) && "Bind value out of range!"); + Info = (Info & 0x0F) | (X << 4); + } + void SetType(unsigned X) { + assert(X == (X & 0xF) && "Type value out of range!"); + Info = (Info & 0xF0) | X; + } + }; + + /// SymbolTable - This is the list of symbols we have emitted to the file. + /// This actually gets rearranged before emission to OutputBuffer (to put + /// the local symbols first in the list). + std::vector SymbolTable; + + // As we accumulate the ELF file into OutputBuffer, we occasionally need to // keep track of locations to update later (e.g. the location of the section // table in the ELF header. These members keep track of the offset in @@ -109,6 +148,15 @@ unsigned ELFHeader_e_shstrndx_Offset; // e_shstrndx in ELF header. unsigned ELFHeader_e_shnum_Offset; // e_shnum in ELF header. + // align - Emit padding into the file until the current output position is + // aligned to the specified power of two boundary. + void align(unsigned Boundary) { + assert(Boundary && (Boundary & (Boundary-1)) == 0 && + "Must align to 2^k boundary"); + while (OutputBuffer.size() & (Boundary-1)) + outbyte(0xAB); + } + void outbyte(unsigned char X) { OutputBuffer.push_back(X); } void outhalf(unsigned short X) { if (isLittleEndian) { @@ -162,9 +210,10 @@ } private: - void EmitDATASectionGlobal(GlobalVariable *GV); - void EmitBSSSectionGlobal(GlobalVariable *GV); - void EmitGlobal(GlobalVariable *GV); + void EmitGlobal(GlobalVariable *GV, ELFSection &DataSection, + ELFSection &BSSSection); + + void EmitSymbolTable(); void EmitSectionTableStringTable(); void EmitSectionTable(); From lattner at cs.uiuc.edu Thu Jul 7 02:02:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 02:02:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp Message-ID: <200507070702.CAA11790@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ELFWriter.cpp updated: 1.1 -> 1.2 --- Log message: Add support for emitting the symbol table (and its string table) of the module to the ELF file. Test it by adding support for emitting common symbols. This allows us to compile this: %X = weak global int 0 %Y = weak global int 0 %Z = weak global int 0 to an elf file that 'readelf's this: Symbol table '.symtab' contains 4 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000004 4 OBJECT GLOBAL DEFAULT COM X 2: 00000004 4 OBJECT GLOBAL DEFAULT COM Y 3: 00000004 4 OBJECT GLOBAL DEFAULT COM Z --- Diffs of the changes: (+140 -53) ELFWriter.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 140 insertions(+), 53 deletions(-) Index: llvm/lib/CodeGen/ELFWriter.cpp diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.1 llvm/lib/CodeGen/ELFWriter.cpp:1.2 --- llvm/lib/CodeGen/ELFWriter.cpp:1.1 Mon Jun 27 01:29:00 2005 +++ llvm/lib/CodeGen/ELFWriter.cpp Thu Jul 7 02:02:20 2005 @@ -11,17 +11,18 @@ // the ELF file in the following order: // // #1. ELF Header -// #2. '.data' section -// #3. '.bss' section +// #2. '.text' section +// #3. '.data' section +// #4. '.bss' section (conceptual position in file) // ... // #X. '.shstrtab' section // #Y. Section Table // // The entries in the section table are laid out as: // #0. Null entry [required] -// #1. ".data" entry - global variables with initializers. [ if needed ] -// #2. ".bss" entry - global variables without initializers. [ if needed ] -// #3. ".text" entry - the program code +// #1. ".text" entry - the program code +// #2. ".data" entry - global variables with initializers. [ if needed ] +// #3. ".bss" entry - global variables without initializers. [ if needed ] // ... // #N. ".shstrtab" entry - String table for the section names. @@ -83,62 +84,50 @@ // Add the null section. SectionList.push_back(ELFSection()); - // Okay, the ELF header has been completed, emit the .data section next. - ELFSection DataSection(".data", OutputBuffer.size()); - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - EmitDATASectionGlobal(I); - - // If the .data section is nonempty, add it to our list. - if ((DataSection.Size = OutputBuffer.size()-DataSection.Offset)) { - DataSection.Align = 4; // FIXME: Compute! - SectionList.push_back(DataSection); - } + // Start up the symbol table. The first entry in the symtab is the null + // entry. + SymbolTable.push_back(ELFSym(0)); - // Okay, emit the .bss section next. - ELFSection BSSSection(".bss", OutputBuffer.size()); - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - EmitBSSSectionGlobal(I); - // If the .bss section is nonempty, add it to our list. - if ((BSSSection.Size = OutputBuffer.size()-BSSSection.Offset)) { - BSSSection.Align = 4; // FIXME: Compute! - SectionList.push_back(BSSSection); - } + // FIXME: Should start the .text section. return false; } -// isCOMM - A global variable should be emitted to the common area if it is zero -// initialized and has linkage that permits it to be merged with other globals. -static bool isCOMM(GlobalVariable *GV) { - return GV->getInitializer()->isNullValue() && - (GV->hasLinkOnceLinkage() || GV->hasInternalLinkage() || - GV->hasWeakLinkage()); -} - -// EmitDATASectionGlobal - Emit a global variable to the .data section if it -// belongs there. -void ELFWriter::EmitDATASectionGlobal(GlobalVariable *GV) { - if (!GV->hasInitializer()) return; - - // Do not emit a symbol here if it should be emitted to the common area. - if (isCOMM(GV)) return; - - EmitGlobal(GV); -} - -void ELFWriter::EmitBSSSectionGlobal(GlobalVariable *GV) { - if (!GV->hasInitializer()) return; +void ELFWriter::EmitGlobal(GlobalVariable *GV, ELFSection &DataSection, + ELFSection &BSSSection) { + // If this is an external global, emit it... + assert(GV->hasInitializer() && "FIXME: unimp"); + + // If this global has a zero initializer, it is part of the .bss or common + // section. + if (GV->getInitializer()->isNullValue()) { + // If this global is part of the common block, add it now. Variables are + // part of the common block if they are zero initialized and allowed to be + // merged with other symbols. + if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) { + ELFSym CommonSym(GV); + // Value for common symbols is the alignment required. + const Type *GVType = (const Type*)GV->getType(); + CommonSym.Value = TM.getTargetData().getTypeAlignment(GVType); + CommonSym.Size = TM.getTargetData().getTypeSize(GVType); + CommonSym.SetBind(ELFSym::STB_GLOBAL); + CommonSym.SetType(ELFSym::STT_OBJECT); + // TODO SOMEDAY: add ELF visibility. + CommonSym.SectionIdx = ELFSection::SHN_COMMON; + SymbolTable.push_back(CommonSym); + return; + } - // FIXME: We don't support BSS yet! - return; + // FIXME: Implement the .bss section. + return; + } - EmitGlobal(GV); -} + // FIXME: handle .rodata + //assert(!GV->isConstant() && "unimp"); -void ELFWriter::EmitGlobal(GlobalVariable *GV) { + // FIXME: handle .data + //assert(0 && "unimp"); } @@ -149,6 +138,37 @@ /// doFinalization - Now that the module has been completely processed, emit /// the ELF file to 'O'. bool ELFWriter::doFinalization(Module &M) { + // Okay, the .text section has now been finalized. + // FIXME: finalize the .text section. + + // Okay, the ELF header and .text sections have been completed, build the + // .data, .bss, and "common" sections next. + ELFSection DataSection(".data", OutputBuffer.size()); + ELFSection BSSSection (".bss"); + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + EmitGlobal(I, DataSection, BSSSection); + + // If the .data section is nonempty, add it to our list. + if (DataSection.Size) { + DataSection.Align = 4; // FIXME: Compute! + // FIXME: Set the right flags and stuff. + SectionList.push_back(DataSection); + } + + // If the .bss section is nonempty, add it to our list. + if (BSSSection.Size) { + BSSSection.Offset = OutputBuffer.size(); + BSSSection.Align = 4; // FIXME: Compute! + // FIXME: Set the right flags and stuff. + SectionList.push_back(BSSSection); + } + + // Emit the symbol table now, if non-empty. + EmitSymbolTable(); + + // FIXME: Emit the relocations now. + // Emit the string table for the sections in the ELF file we have. EmitSectionTableStringTable(); @@ -163,13 +183,80 @@ return false; } +/// EmitSymbolTable - If the current symbol table is non-empty, emit the string +/// table for it and then the symbol table itself. +void ELFWriter::EmitSymbolTable() { + if (SymbolTable.size() == 1) return; // Only the null entry. + + // FIXME: compact all local symbols to the start of the symtab. + unsigned FirstNonLocalSymbol = 1; + + SectionList.push_back(ELFSection(".strtab", OutputBuffer.size())); + ELFSection &StrTab = SectionList.back(); + StrTab.Type = ELFSection::SHT_STRTAB; + StrTab.Align = 1; + + // Set the zero'th symbol to a null byte, as required. + outbyte(0); + SymbolTable[0].NameIdx = 0; + unsigned Index = 1; + for (unsigned i = 1, e = SymbolTable.size(); i != e; ++i) { + // FIXME: USE A MANGLER!! + const std::string &Name = SymbolTable[i].GV->getName(); + + if (Name.empty()) { + SymbolTable[i].NameIdx = 0; + } else { + SymbolTable[i].NameIdx = Index; + + // Add the name to the output buffer, including the null terminator. + OutputBuffer.insert(OutputBuffer.end(), Name.begin(), Name.end()); + + // Add a null terminator. + OutputBuffer.push_back(0); + + // Keep track of the number of bytes emitted to this section. + Index += Name.size()+1; + } + } + + StrTab.Size = OutputBuffer.size()-StrTab.Offset; + + // Now that we have emitted the string table and know the offset into the + // string table of each symbol, emit the symbol table itself. + assert(!is64Bit && "Should this be 8 byte aligned for 64-bit?" + " (check .Align below also)"); + align(4); + + SectionList.push_back(ELFSection(".symtab", OutputBuffer.size())); + ELFSection &SymTab = SectionList.back(); + SymTab.Type = ELFSection::SHT_SYMTAB; + SymTab.Align = 4; // FIXME: check for ELF64 + SymTab.Link = SectionList.size()-2; // Section Index of .strtab. + SymTab.Info = FirstNonLocalSymbol; // First non-STB_LOCAL symbol. + SymTab.EntSize = 16; // Size of each symtab entry. FIXME: wrong for ELF64 + + assert(!is64Bit && "check this!"); + for (unsigned i = 0, e = SymbolTable.size(); i != e; ++i) { + ELFSym &Sym = SymbolTable[i]; + outword(Sym.NameIdx); + outaddr(Sym.Value); + outword(Sym.Size); + outbyte(Sym.Info); + outbyte(Sym.Other); + outhalf(Sym.SectionIdx); + } + + SymTab.Size = OutputBuffer.size()-SymTab.Offset; +} + /// EmitSectionTableStringTable - This method adds and emits a section for the /// ELF Section Table string table: the string table that holds all of the /// section names. void ELFWriter::EmitSectionTableStringTable() { // First step: add the section for the string table to the list of sections: SectionList.push_back(ELFSection(".shstrtab", OutputBuffer.size())); - SectionList.back().Type = 3; // SHT_STRTAB + SectionList.back().Type = ELFSection::SHT_STRTAB; // Now that we know which section number is the .shstrtab section, update the // e_shstrndx entry in the ELF header. From reid at x10sys.com Thu Jul 7 03:41:55 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 07 Jul 2005 01:41:55 -0700 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp In-Reply-To: <200506270629.BAA28563@zion.cs.uiuc.edu> References: <200506270629.BAA28563@zion.cs.uiuc.edu> Message-ID: <1120725715.725.57.camel@bashful.x10sys.com> I didn't realize you were going to implement this. I have a partial implementation in the same file name(s) that is based on libelf. I don't see why we would want to re-invent this wheel, but I'm sure you have your reasons. If you're opposed to libelf, then please remove it from the lib/CodeGen/ELF directory. Reid. On Mon, 2005-06-27 at 01:29 -0500, Chris Lattner wrote: > > Changes in directory llvm/lib/CodeGen: > > ELFWriter.cpp added (r1.1) > --- > Log message: > > iniital checkin of ELFWriter implementation > > For now, the elf writer is only capable of emitting an empty elf file, with > a section table and a section table string table. This will be enhanced > in the future :) > > > --- > Diffs of the changes: (+230 -0) > > ELFWriter.cpp | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 230 insertions(+) > > > Index: llvm/lib/CodeGen/ELFWriter.cpp > diff -c /dev/null llvm/lib/CodeGen/ELFWriter.cpp:1.1 > *** /dev/null Mon Jun 27 01:29:10 2005 > --- llvm/lib/CodeGen/ELFWriter.cpp Mon Jun 27 01:29:00 2005 > *************** > *** 0 **** > --- 1,230 ---- > + //===-- ELFWriter.cpp - Target-independent ELF Writer code ----------------===// > + // > + // 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 target-independent ELF writer. This file writes out > + // the ELF file in the following order: > + // > + // #1. ELF Header > + // #2. '.data' section > + // #3. '.bss' section > + // ... > + // #X. '.shstrtab' section > + // #Y. Section Table > + // > + // The entries in the section table are laid out as: > + // #0. Null entry [required] > + // #1. ".data" entry - global variables with initializers. [ if needed ] > + // #2. ".bss" entry - global variables without initializers. [ if needed ] > + // #3. ".text" entry - the program code > + // ... > + // #N. ".shstrtab" entry - String table for the section names. > + > + // > + // NOTE: This code should eventually be extended to support 64-bit ELF (this > + // won't be hard), but we haven't done so yet! > + // > + //===----------------------------------------------------------------------===// > + > + #include "llvm/CodeGen/ELFWriter.h" > + #include "llvm/Module.h" > + #include "llvm/Target/TargetMachine.h" > + using namespace llvm; > + > + ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { > + e_machine = 0; // e_machine defaults to 'No Machine' > + e_flags = 0; // e_flags defaults to 0, no flags. > + > + is64Bit = TM.getTargetData().getPointerSizeInBits() == 64; > + isLittleEndian = TM.getTargetData().isLittleEndian(); > + } > + > + // doInitialization - Emit the file header and all of the global variables for > + // the module to the ELF file. > + bool ELFWriter::doInitialization(Module &M) { > + outbyte(0x7F); // EI_MAG0 > + outbyte('E'); // EI_MAG1 > + outbyte('L'); // EI_MAG2 > + outbyte('F'); // EI_MAG3 > + outbyte(is64Bit ? 2 : 1); // EI_CLASS > + outbyte(isLittleEndian ? 1 : 2); // EI_DATA > + outbyte(1); // EI_VERSION > + for (unsigned i = OutputBuffer.size(); i != 16; ++i) > + outbyte(0); // EI_PAD up to 16 bytes. > + > + // This should change for shared objects. > + outhalf(1); // e_type = ET_REL > + outhalf(e_machine); // e_machine = whatever the target wants > + outword(1); // e_version = 1 > + outaddr(0); // e_entry = 0 -> no entry point in .o file > + outaddr(0); // e_phoff = 0 -> no program header for .o > + > + ELFHeader_e_shoff_Offset = OutputBuffer.size(); > + outaddr(0); // e_shoff > + outword(e_flags); // e_flags = whatever the target wants > + > + assert(!is64Bit && "These sizes need to be adjusted for 64-bit!"); > + outhalf(52); // e_ehsize = ELF header size > + outhalf(0); // e_phentsize = prog header entry size > + outhalf(0); // e_phnum = # prog header entries = 0 > + outhalf(40); // e_shentsize = sect header entry size > + > + > + ELFHeader_e_shnum_Offset = OutputBuffer.size(); > + outhalf(0); // e_shnum = # of section header ents > + ELFHeader_e_shstrndx_Offset = OutputBuffer.size(); > + outhalf(0); // e_shstrndx = Section # of '.shstrtab' > + > + // Add the null section. > + SectionList.push_back(ELFSection()); > + > + // Okay, the ELF header has been completed, emit the .data section next. > + ELFSection DataSection(".data", OutputBuffer.size()); > + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); > + I != E; ++I) > + EmitDATASectionGlobal(I); > + > + // If the .data section is nonempty, add it to our list. > + if ((DataSection.Size = OutputBuffer.size()-DataSection.Offset)) { > + DataSection.Align = 4; // FIXME: Compute! > + SectionList.push_back(DataSection); > + } > + > + // Okay, emit the .bss section next. > + ELFSection BSSSection(".bss", OutputBuffer.size()); > + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); > + I != E; ++I) > + EmitBSSSectionGlobal(I); > + > + // If the .bss section is nonempty, add it to our list. > + if ((BSSSection.Size = OutputBuffer.size()-BSSSection.Offset)) { > + BSSSection.Align = 4; // FIXME: Compute! > + SectionList.push_back(BSSSection); > + } > + > + return false; > + } > + > + // isCOMM - A global variable should be emitted to the common area if it is zero > + // initialized and has linkage that permits it to be merged with other globals. > + static bool isCOMM(GlobalVariable *GV) { > + return GV->getInitializer()->isNullValue() && > + (GV->hasLinkOnceLinkage() || GV->hasInternalLinkage() || > + GV->hasWeakLinkage()); > + } > + > + // EmitDATASectionGlobal - Emit a global variable to the .data section if it > + // belongs there. > + void ELFWriter::EmitDATASectionGlobal(GlobalVariable *GV) { > + if (!GV->hasInitializer()) return; > + > + // Do not emit a symbol here if it should be emitted to the common area. > + if (isCOMM(GV)) return; > + > + EmitGlobal(GV); > + } > + > + void ELFWriter::EmitBSSSectionGlobal(GlobalVariable *GV) { > + if (!GV->hasInitializer()) return; > + > + // FIXME: We don't support BSS yet! > + return; > + > + EmitGlobal(GV); > + } > + > + void ELFWriter::EmitGlobal(GlobalVariable *GV) { > + } > + > + > + bool ELFWriter::runOnMachineFunction(MachineFunction &MF) { > + return false; > + } > + > + /// doFinalization - Now that the module has been completely processed, emit > + /// the ELF file to 'O'. > + bool ELFWriter::doFinalization(Module &M) { > + // Emit the string table for the sections in the ELF file we have. > + EmitSectionTableStringTable(); > + > + // Emit the .o file section table. > + EmitSectionTable(); > + > + // Emit the .o file to the specified stream. > + O.write((char*)&OutputBuffer[0], OutputBuffer.size()); > + > + // Free the output buffer. > + std::vector().swap(OutputBuffer); > + return false; > + } > + > + /// EmitSectionTableStringTable - This method adds and emits a section for the > + /// ELF Section Table string table: the string table that holds all of the > + /// section names. > + void ELFWriter::EmitSectionTableStringTable() { > + // First step: add the section for the string table to the list of sections: > + SectionList.push_back(ELFSection(".shstrtab", OutputBuffer.size())); > + SectionList.back().Type = 3; // SHT_STRTAB > + > + // Now that we know which section number is the .shstrtab section, update the > + // e_shstrndx entry in the ELF header. > + fixhalf(SectionList.size()-1, ELFHeader_e_shstrndx_Offset); > + > + // Set the NameIdx of each section in the string table and emit the bytes for > + // the string table. > + unsigned Index = 0; > + > + for (unsigned i = 0, e = SectionList.size(); i != e; ++i) { > + // Set the index into the table. Note if we have lots of entries with > + // common suffixes, we could memoize them here if we cared. > + SectionList[i].NameIdx = Index; > + > + // Add the name to the output buffer, including the null terminator. > + OutputBuffer.insert(OutputBuffer.end(), SectionList[i].Name.begin(), > + SectionList[i].Name.end()); > + // Add a null terminator. > + OutputBuffer.push_back(0); > + > + // Keep track of the number of bytes emitted to this section. > + Index += SectionList[i].Name.size()+1; > + } > + > + // Set the size of .shstrtab now that we know what it is. > + SectionList.back().Size = Index; > + } > + > + /// EmitSectionTable - Now that we have emitted the entire contents of the file > + /// (all of the sections), emit the section table which informs the reader where > + /// the boundaries are. > + void ELFWriter::EmitSectionTable() { > + // Now that all of the sections have been emitted, set the e_shnum entry in > + // the ELF header. > + fixhalf(SectionList.size(), ELFHeader_e_shnum_Offset); > + > + // Now that we know the offset in the file of the section table (which we emit > + // next), update the e_shoff address in the ELF header. > + fixaddr(OutputBuffer.size(), ELFHeader_e_shoff_Offset); > + > + // Emit all of the section table entries. > + for (unsigned i = 0, e = SectionList.size(); i != e; ++i) { > + const ELFSection &S = SectionList[i]; > + outword(S.NameIdx); // sh_name - Symbol table name idx > + outword(S.Type); // sh_type - Section contents & semantics > + outword(S.Flags); // sh_flags - Section flags. > + outaddr(S.Addr); // sh_addr - The mem address this section appears in. > + outaddr(S.Offset); // sh_offset - The offset from the start of the file. > + outword(S.Size); // sh_size - The section size. > + outword(S.Link); // sh_link - Section header table index link. > + outword(S.Info); // sh_info - Auxillary information. > + outword(S.Align); // sh_addralign - Alignment of section. > + outword(S.EntSize); // sh_entsize - Size of each entry in the section. > + } > + > + // Release the memory allocated for the section list. > + std::vector().swap(SectionList); > + } > > > > _______________________________________________ > 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/20050707/866e93e8/attachment.bin From lattner at cs.uiuc.edu Thu Jul 7 10:56:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 10:56:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELF/COPYING.LIB ChangeLog INSTALL MANIFEST Makefile.in README VERSION acconfig.h aclocal.m4 config.guess config.h.in config.sub configure configure.in install-sh mkinstalldirs stamp-h.in Message-ID: <200507071556.KAA11523@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ELF: COPYING.LIB (r1.1) removed ChangeLog (r1.1) removed INSTALL (r1.1) removed MANIFEST (r1.1) removed Makefile.in (r1.1) removed README (r1.1) removed VERSION (r1.1) removed acconfig.h (r1.1) removed aclocal.m4 (r1.1) removed config.guess (r1.1) removed config.h.in (r1.1) removed config.sub (r1.1) removed configure (r1.1) removed configure.in (r1.1) removed install-sh (r1.1) removed mkinstalldirs (r1.1) removed stamp-h.in (r1.1) removed --- Log message: Remove libelf, as we are going to use a hand written elf writer. --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Thu Jul 7 10:56:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 10:56:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELF/lib/32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c 32.newphdr.c 32.xlatetof.c 64.xlatetof.c Makefile.in assert.c begin.c byteswap.h checksum.c cntl.c cook.c data.c elf_repl.h end.c errmsg.c errno.c errors.h ext_types.h fill.c flag.c gelf.h gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c getarhdr.c getarsym.c getbase.c getdata.c getident.c getscn.c hash.c input.c kind.c libelf.h memset.c ndxscn.c newdata.c newscn.c next.c nextscn.c nlist.c nlist.h opt.delscn.c private.h rand.c rawdata.c rawfile.c strptr.c swap64.c sys_elf.h.in update.c verdef.h verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c verneed.h version.c x.movscn.c x.remscn.c Message-ID: <200507071556.KAA11592@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ELF/lib: 32.fsize.c (r1.1) removed 32.getehdr.c (r1.1) removed 32.getphdr.c (r1.1) removed 32.getshdr.c (r1.1) removed 32.newehdr.c (r1.1) removed 32.newphdr.c (r1.1) removed 32.xlatetof.c (r1.1) removed 64.xlatetof.c (r1.1) removed Makefile.in (r1.1) removed assert.c (r1.1) removed begin.c (r1.1) removed byteswap.h (r1.1) removed checksum.c (r1.1) removed cntl.c (r1.1) removed cook.c (r1.1) removed data.c (r1.1) removed elf_repl.h (r1.1) removed end.c (r1.1) removed errmsg.c (r1.1) removed errno.c (r1.1) removed errors.h (r1.1) removed ext_types.h (r1.1) removed fill.c (r1.1) removed flag.c (r1.1) removed gelf.h (r1.1) removed gelfehdr.c (r1.1) removed gelfphdr.c (r1.1) removed gelfshdr.c (r1.1) removed gelftrans.c (r1.1) removed getarhdr.c (r1.1) removed getarsym.c (r1.1) removed getbase.c (r1.1) removed getdata.c (r1.1) removed getident.c (r1.1) removed getscn.c (r1.1) removed hash.c (r1.1) removed input.c (r1.1) removed kind.c (r1.1) removed libelf.h (r1.1) removed memset.c (r1.1) removed ndxscn.c (r1.1) removed newdata.c (r1.1) removed newscn.c (r1.1) removed next.c (r1.1) removed nextscn.c (r1.1) removed nlist.c (r1.1) removed nlist.h (r1.1) removed opt.delscn.c (r1.1) removed private.h (r1.1) removed rand.c (r1.1) removed rawdata.c (r1.1) removed rawfile.c (r1.1) removed strptr.c (r1.1) removed swap64.c (r1.1) removed sys_elf.h.in (r1.1) removed update.c (r1.1) removed verdef.h (r1.1) removed verdef_32_tof.c (r1.1) removed verdef_32_tom.c (r1.1) removed verdef_64_tof.c (r1.1) removed verdef_64_tom.c (r1.1) removed verneed.h (r1.1) removed version.c (r1.1) removed x.movscn.c (r1.1) removed x.remscn.c (r1.1) removed --- Log message: Remove libelf, as we are going to use a hand written elf writer. --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Thu Jul 7 10:56:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 10:56:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELF/po/Makefile.in de.gmo de.msg de.po gmo2msg.c libelf.pot stamp-po Message-ID: <200507071556.KAA11603@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ELF/po: Makefile.in (r1.1) removed de.gmo (r1.1) removed de.msg (r1.1) removed de.po (r1.1) removed gmo2msg.c (r1.1) removed libelf.pot (r1.1) removed stamp-po (r1.1) removed --- Log message: Remove libelf, as we are going to use a hand written elf writer. --- Diffs of the changes: (+0 -0) 0 files changed From sabre at nondot.org Thu Jul 7 11:33:09 2005 From: sabre at nondot.org (Chris Lattner) Date: Thu, 7 Jul 2005 11:33:09 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp In-Reply-To: <1120725715.725.57.camel@bashful.x10sys.com> References: <200506270629.BAA28563@zion.cs.uiuc.edu> <1120725715.725.57.camel@bashful.x10sys.com> Message-ID: On Thu, 7 Jul 2005, Reid Spencer wrote: > I didn't realize you were going to implement this. I have a partial > implementation in the same file name(s) that is based on libelf. I don't Ouch, I'm sorry, I didn't know you were currently working on it :( > see why we would want to re-invent this wheel, but I'm sure you have > your reasons. The short version is that using libelf doesn't solve the hard problems of writing the ELF file: organizing the information coming out of the code generator so that we can spit it out into the file. It does solve the easy problem: handling the on disk format (which is really really simple) but at a very high cost: it is LGPL, which puts some serious restrictions on how we can build the software. It is also a pretty big chunk of code to have to keep around in our source tree as well. BTW, I found the answer to your question about Sun's use of libelf. The answer is that Sun is not using the LGPL libelf. The LGPL libelf is a clone of the preexisting Sun implementation. This is why Sun can use (their) libelf without any restrictions. -Chris > If you're opposed to libelf, then please remove it from > the lib/CodeGen/ELF directory. Done. -Chris > Reid. > > On Mon, 2005-06-27 at 01:29 -0500, Chris Lattner wrote: >> >> Changes in directory llvm/lib/CodeGen: >> >> ELFWriter.cpp added (r1.1) >> --- >> Log message: >> >> iniital checkin of ELFWriter implementation >> >> For now, the elf writer is only capable of emitting an empty elf file, with >> a section table and a section table string table. This will be enhanced >> in the future :) >> >> >> --- >> Diffs of the changes: (+230 -0) >> >> ELFWriter.cpp | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 230 insertions(+) >> >> >> Index: llvm/lib/CodeGen/ELFWriter.cpp >> diff -c /dev/null llvm/lib/CodeGen/ELFWriter.cpp:1.1 >> *** /dev/null Mon Jun 27 01:29:10 2005 >> --- llvm/lib/CodeGen/ELFWriter.cpp Mon Jun 27 01:29:00 2005 >> *************** >> *** 0 **** >> --- 1,230 ---- >> + //===-- ELFWriter.cpp - Target-independent ELF Writer code ----------------===// >> + // >> + // 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 target-independent ELF writer. This file writes out >> + // the ELF file in the following order: >> + // >> + // #1. ELF Header >> + // #2. '.data' section >> + // #3. '.bss' section >> + // ... >> + // #X. '.shstrtab' section >> + // #Y. Section Table >> + // >> + // The entries in the section table are laid out as: >> + // #0. Null entry [required] >> + // #1. ".data" entry - global variables with initializers. [ if needed ] >> + // #2. ".bss" entry - global variables without initializers. [ if needed ] >> + // #3. ".text" entry - the program code >> + // ... >> + // #N. ".shstrtab" entry - String table for the section names. >> + >> + // >> + // NOTE: This code should eventually be extended to support 64-bit ELF (this >> + // won't be hard), but we haven't done so yet! >> + // >> + //===----------------------------------------------------------------------===// >> + >> + #include "llvm/CodeGen/ELFWriter.h" >> + #include "llvm/Module.h" >> + #include "llvm/Target/TargetMachine.h" >> + using namespace llvm; >> + >> + ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { >> + e_machine = 0; // e_machine defaults to 'No Machine' >> + e_flags = 0; // e_flags defaults to 0, no flags. >> + >> + is64Bit = TM.getTargetData().getPointerSizeInBits() == 64; >> + isLittleEndian = TM.getTargetData().isLittleEndian(); >> + } >> + >> + // doInitialization - Emit the file header and all of the global variables for >> + // the module to the ELF file. >> + bool ELFWriter::doInitialization(Module &M) { >> + outbyte(0x7F); // EI_MAG0 >> + outbyte('E'); // EI_MAG1 >> + outbyte('L'); // EI_MAG2 >> + outbyte('F'); // EI_MAG3 >> + outbyte(is64Bit ? 2 : 1); // EI_CLASS >> + outbyte(isLittleEndian ? 1 : 2); // EI_DATA >> + outbyte(1); // EI_VERSION >> + for (unsigned i = OutputBuffer.size(); i != 16; ++i) >> + outbyte(0); // EI_PAD up to 16 bytes. >> + >> + // This should change for shared objects. >> + outhalf(1); // e_type = ET_REL >> + outhalf(e_machine); // e_machine = whatever the target wants >> + outword(1); // e_version = 1 >> + outaddr(0); // e_entry = 0 -> no entry point in .o file >> + outaddr(0); // e_phoff = 0 -> no program header for .o >> + >> + ELFHeader_e_shoff_Offset = OutputBuffer.size(); >> + outaddr(0); // e_shoff >> + outword(e_flags); // e_flags = whatever the target wants >> + >> + assert(!is64Bit && "These sizes need to be adjusted for 64-bit!"); >> + outhalf(52); // e_ehsize = ELF header size >> + outhalf(0); // e_phentsize = prog header entry size >> + outhalf(0); // e_phnum = # prog header entries = 0 >> + outhalf(40); // e_shentsize = sect header entry size >> + >> + >> + ELFHeader_e_shnum_Offset = OutputBuffer.size(); >> + outhalf(0); // e_shnum = # of section header ents >> + ELFHeader_e_shstrndx_Offset = OutputBuffer.size(); >> + outhalf(0); // e_shstrndx = Section # of '.shstrtab' >> + >> + // Add the null section. >> + SectionList.push_back(ELFSection()); >> + >> + // Okay, the ELF header has been completed, emit the .data section next. >> + ELFSection DataSection(".data", OutputBuffer.size()); >> + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); >> + I != E; ++I) >> + EmitDATASectionGlobal(I); >> + >> + // If the .data section is nonempty, add it to our list. >> + if ((DataSection.Size = OutputBuffer.size()-DataSection.Offset)) { >> + DataSection.Align = 4; // FIXME: Compute! >> + SectionList.push_back(DataSection); >> + } >> + >> + // Okay, emit the .bss section next. >> + ELFSection BSSSection(".bss", OutputBuffer.size()); >> + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); >> + I != E; ++I) >> + EmitBSSSectionGlobal(I); >> + >> + // If the .bss section is nonempty, add it to our list. >> + if ((BSSSection.Size = OutputBuffer.size()-BSSSection.Offset)) { >> + BSSSection.Align = 4; // FIXME: Compute! >> + SectionList.push_back(BSSSection); >> + } >> + >> + return false; >> + } >> + >> + // isCOMM - A global variable should be emitted to the common area if it is zero >> + // initialized and has linkage that permits it to be merged with other globals. >> + static bool isCOMM(GlobalVariable *GV) { >> + return GV->getInitializer()->isNullValue() && >> + (GV->hasLinkOnceLinkage() || GV->hasInternalLinkage() || >> + GV->hasWeakLinkage()); >> + } >> + >> + // EmitDATASectionGlobal - Emit a global variable to the .data section if it >> + // belongs there. >> + void ELFWriter::EmitDATASectionGlobal(GlobalVariable *GV) { >> + if (!GV->hasInitializer()) return; >> + >> + // Do not emit a symbol here if it should be emitted to the common area. >> + if (isCOMM(GV)) return; >> + >> + EmitGlobal(GV); >> + } >> + >> + void ELFWriter::EmitBSSSectionGlobal(GlobalVariable *GV) { >> + if (!GV->hasInitializer()) return; >> + >> + // FIXME: We don't support BSS yet! >> + return; >> + >> + EmitGlobal(GV); >> + } >> + >> + void ELFWriter::EmitGlobal(GlobalVariable *GV) { >> + } >> + >> + >> + bool ELFWriter::runOnMachineFunction(MachineFunction &MF) { >> + return false; >> + } >> + >> + /// doFinalization - Now that the module has been completely processed, emit >> + /// the ELF file to 'O'. >> + bool ELFWriter::doFinalization(Module &M) { >> + // Emit the string table for the sections in the ELF file we have. >> + EmitSectionTableStringTable(); >> + >> + // Emit the .o file section table. >> + EmitSectionTable(); >> + >> + // Emit the .o file to the specified stream. >> + O.write((char*)&OutputBuffer[0], OutputBuffer.size()); >> + >> + // Free the output buffer. >> + std::vector().swap(OutputBuffer); >> + return false; >> + } >> + >> + /// EmitSectionTableStringTable - This method adds and emits a section for the >> + /// ELF Section Table string table: the string table that holds all of the >> + /// section names. >> + void ELFWriter::EmitSectionTableStringTable() { >> + // First step: add the section for the string table to the list of sections: >> + SectionList.push_back(ELFSection(".shstrtab", OutputBuffer.size())); >> + SectionList.back().Type = 3; // SHT_STRTAB >> + >> + // Now that we know which section number is the .shstrtab section, update the >> + // e_shstrndx entry in the ELF header. >> + fixhalf(SectionList.size()-1, ELFHeader_e_shstrndx_Offset); >> + >> + // Set the NameIdx of each section in the string table and emit the bytes for >> + // the string table. >> + unsigned Index = 0; >> + >> + for (unsigned i = 0, e = SectionList.size(); i != e; ++i) { >> + // Set the index into the table. Note if we have lots of entries with >> + // common suffixes, we could memoize them here if we cared. >> + SectionList[i].NameIdx = Index; >> + >> + // Add the name to the output buffer, including the null terminator. >> + OutputBuffer.insert(OutputBuffer.end(), SectionList[i].Name.begin(), >> + SectionList[i].Name.end()); >> + // Add a null terminator. >> + OutputBuffer.push_back(0); >> + >> + // Keep track of the number of bytes emitted to this section. >> + Index += SectionList[i].Name.size()+1; >> + } >> + >> + // Set the size of .shstrtab now that we know what it is. >> + SectionList.back().Size = Index; >> + } >> + >> + /// EmitSectionTable - Now that we have emitted the entire contents of the file >> + /// (all of the sections), emit the section table which informs the reader where >> + /// the boundaries are. >> + void ELFWriter::EmitSectionTable() { >> + // Now that all of the sections have been emitted, set the e_shnum entry in >> + // the ELF header. >> + fixhalf(SectionList.size(), ELFHeader_e_shnum_Offset); >> + >> + // Now that we know the offset in the file of the section table (which we emit >> + // next), update the e_shoff address in the ELF header. >> + fixaddr(OutputBuffer.size(), ELFHeader_e_shoff_Offset); >> + >> + // Emit all of the section table entries. >> + for (unsigned i = 0, e = SectionList.size(); i != e; ++i) { >> + const ELFSection &S = SectionList[i]; >> + outword(S.NameIdx); // sh_name - Symbol table name idx >> + outword(S.Type); // sh_type - Section contents & semantics >> + outword(S.Flags); // sh_flags - Section flags. >> + outaddr(S.Addr); // sh_addr - The mem address this section appears in. >> + outaddr(S.Offset); // sh_offset - The offset from the start of the file. >> + outword(S.Size); // sh_size - The section size. >> + outword(S.Link); // sh_link - Section header table index link. >> + outword(S.Info); // sh_info - Auxillary information. >> + outword(S.Align); // sh_addralign - Alignment of section. >> + outword(S.EntSize); // sh_entsize - Size of each entry in the section. >> + } >> + >> + // Release the memory allocated for the section list. >> + std::vector().swap(SectionList); >> + } >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits > -Chris -- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/ From lattner at cs.uiuc.edu Thu Jul 7 12:13:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 12:13:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507071713.MAA25514@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.146 -> 1.147 --- Log message: Restore some code that was accidentally removed by Nate's patch yesterday. This fixes the regressions from last night. --- Diffs of the changes: (+20 -1) X86ISelPattern.cpp | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.146 llvm/lib/Target/X86/X86ISelPattern.cpp:1.147 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.146 Thu Jul 7 01:32:01 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Jul 7 12:12:53 2005 @@ -2379,6 +2379,7 @@ // MVT::ValueType PromoteType = MVT::Other; MVT::ValueType SrcTy = N.getOperand(0).getValueType(); + unsigned RealDestReg = Result; switch (SrcTy) { case MVT::i1: case MVT::i8: @@ -2426,7 +2427,25 @@ break; default: break; // No promotion required. } - return Result; + + if (Node->getOpcode() == ISD::UINT_TO_FP && Result != RealDestReg) { + // If this is a cast from uint -> double, we need to be careful when if + // the "sign" bit is set. If so, we don't want to make a negative number, + // we want to make a positive number. Emit code to add an offset if the + // sign bit is set. + + // Compute whether the sign bit is set by shifting the reg right 31 bits. + unsigned IsNeg = MakeReg(MVT::i32); + BuildMI(BB, X86::SHR32ri, 2, IsNeg).addReg(Tmp1).addImm(31); + + // Create a CP value that has the offset in one word and 0 in the other. + static ConstantInt *TheOffset = ConstantUInt::get(Type::ULongTy, + 0x4f80000000000000ULL); + unsigned CPI = F->getConstantPool()->getConstantPoolIndex(TheOffset); + BuildMI(BB, X86::FADD32m, 5, RealDestReg).addReg(Result) + .addConstantPoolIndex(CPI).addZImm(4).addReg(IsNeg).addSImm(0); + } + return RealDestReg; } case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: { From alenhar2 at cs.uiuc.edu Thu Jul 7 12:32:57 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Jul 2005 12:32:57 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c llvm-representation.c llvm-representation.h Message-ID: <200507071732.MAA25701@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.102 -> 1.103 llvm-representation.c updated: 1.18 -> 1.19 llvm-representation.h updated: 1.16 -> 1.17 --- Log message: Convert llvm-gcc to using new style varargs. This has been running for a couple weeks on alpha without problems. --- Diffs of the changes: (+22 -49) llvm-expand.c | 59 ++++++++++++++++---------------------------------- llvm-representation.c | 7 ----- llvm-representation.h | 5 ---- 3 files changed, 22 insertions(+), 49 deletions(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.102 llvm-gcc/gcc/llvm-expand.c:1.103 --- llvm-gcc/gcc/llvm-expand.c:1.102 Sat Jun 18 16:11:19 2005 +++ llvm-gcc/gcc/llvm-expand.c Thu Jul 7 12:32:46 2005 @@ -265,7 +265,6 @@ static llvm_value *llvm_get_scalar_vararg(llvm_function *Fn, llvm_value *VAListPtr, llvm_type *ArgTy) { - llvm_value *VAList = append_inst(Fn, create_load_inst("valist", VAListPtr,0)); llvm_value *Result; llvm_instruction *VA; llvm_type *ActualTy = ArgTy; @@ -286,16 +285,9 @@ VA = llvm_instruction_new(ActualTy, "tmp", O_VAArg, 1); - VA->Operands[0] = VAList; + VA->Operands[0] = VAListPtr; Result = append_inst(Fn, VA); - /* Update the valist */ - VA = llvm_instruction_new(VAList->Ty, "vanextlist", O_VANext, 1); - VA->Operands[0] = VAList; - VA->x.VANext.ArgTy = ActualTy; - VAList = append_inst(Fn, VA); - - append_inst(Fn, create_store_inst(VAList, VAListPtr, 0)); return Result; } @@ -4390,11 +4382,12 @@ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); llvm_type *FnType = llvm_type_get_from_tree(TREE_TYPE(fndecl)); llvm_type *VAListTy = GET_FUNCTION_TYPE_ARGUMENT(FnType, 0); - llvm_type *Ty = llvm_type_create_function(0, GET_POINTER_TYPE_ELEMENT(VAListTy)); - Ty = llvm_type_get_cannonical_function(Ty); + llvm_type *FnTy = llvm_type_create_function(1, VoidTy); + FnTy->Elements[1] = VAListTy; + llvm_type *Ty = llvm_type_get_cannonical_function(FnTy); llvm_va_start_fn = CreateIntrinsicFnWithType("llvm.va_start", Ty); } - + if (TYPE_ARG_TYPES (fntype) == 0 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) == void_type_node)) { error("`va_start' used in function with fixed args"); @@ -4423,13 +4416,10 @@ */ DestVal = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0); VAListTy = GET_FUNCTION_TYPE_RETURN(GET_POINTER_TYPE_ELEMENT(G2V(llvm_va_start_fn)->Ty)); - Call = llvm_instruction_new(VAListTy, "begin", O_Call, 1); + Call = llvm_instruction_new(VoidTy, "", O_Call, 2); Call->Operands[0] = G2V(llvm_va_start_fn); + Call->Operands[1] = DestVal; append_inst(Fn, Call); - - DestVal = cast_if_type_not_equal(Fn, DestVal, - llvm_type_get_pointer(VAListTy)); - append_inst(Fn, create_store_inst(D2V(Call), DestVal, 0)); } static void llvm_expand_builtin_va_end(llvm_function *Fn, tree exp) { @@ -4443,7 +4433,7 @@ llvm_type *VACopyTy = llvm_type_get_from_tree(TREE_TYPE(fndecl)); llvm_type *PtrVAListTy = GET_FUNCTION_TYPE_ARGUMENT(VACopyTy, 0); llvm_type *FnTy = llvm_type_create_function(1, VoidTy); - FnTy->Elements[1] = GET_POINTER_TYPE_ELEMENT(PtrVAListTy); + FnTy->Elements[1] = PtrVAListTy; FnTy = llvm_type_get_cannonical_function(FnTy); llvm_va_end_fn = CreateIntrinsicFnWithType("llvm.va_end", FnTy); } @@ -4451,11 +4441,10 @@ VAListType = GET_FUNCTION_TYPE_ARGUMENT(GET_POINTER_TYPE_ELEMENT(G2V(llvm_va_end_fn)->Ty), 0); Arg = llvm_expand_expr(Fn, TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - Arg = append_inst(Fn, create_load_inst("valist", Arg, 0)); Call = llvm_instruction_new(VoidTy, "", O_Call, 2); Call->Operands[0] = G2V(llvm_va_end_fn); - Call->Operands[1] = cast_if_type_not_equal(Fn, Arg, VAListType); + Call->Operands[1] = Arg; append_inst(Fn, Call); } @@ -4466,29 +4455,21 @@ llvm_type *VAListType; if (!llvm_va_copy_fn) { llvm_type *VACopyTy = llvm_type_get_from_tree(TREE_TYPE(fndecl)); - llvm_type *VAListTy = GET_FUNCTION_TYPE_ARGUMENT(VACopyTy, 1); - llvm_type *FnTy = llvm_type_create_function(1, VAListTy); - FnTy->Elements[1] = VAListTy; + llvm_type *VAListTyPtr = GET_FUNCTION_TYPE_ARGUMENT(VACopyTy, 0); + llvm_type *FnTy = llvm_type_create_function(2, VoidTy); + FnTy->Elements[1] = VAListTyPtr; + FnTy->Elements[2] = VAListTyPtr; FnTy = llvm_type_get_cannonical_function(FnTy); llvm_va_copy_fn = CreateIntrinsicFnWithType("llvm.va_copy", FnTy); } - VAListType = GET_FUNCTION_TYPE_RETURN(GET_POINTER_TYPE_ELEMENT(G2V(llvm_va_copy_fn)->Ty)); - - { - tree SrcArg = TREE_VALUE(TREE_CHAIN(TREE_OPERAND(exp, 1))); - llvm_instruction *I = llvm_instruction_new(VAListType, "tmp", O_Call, 2); - llvm_value *DestAddr; - I->Operands[0] = G2V(llvm_va_copy_fn); - I->Operands[1] = llvm_expand_expr(Fn, SrcArg, 0); - I->Operands[1] = cast_if_type_not_equal(Fn, I->Operands[1], VAListType); - append_inst(Fn, I); - - DestAddr = llvm_expand_expr(Fn, TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - DestAddr = cast_if_type_not_equal(Fn, DestAddr, - llvm_type_get_pointer(VAListType)); - append_inst(Fn, create_store_inst(D2V(I), DestAddr, 0)); - } + tree SrcArg = TREE_VALUE(TREE_CHAIN(TREE_OPERAND(exp, 1))); + llvm_value *DestAddr = llvm_expand_expr(Fn, TREE_VALUE(TREE_OPERAND(exp, 1)), 0); + llvm_instruction *I = llvm_instruction_new(VoidTy, "", O_Call, 3); + I->Operands[0] = G2V(llvm_va_copy_fn); + I->Operands[1] = DestAddr; + I->Operands[2] = llvm_expand_lvalue_expr(Fn, SrcArg, 0, 0); + append_inst(Fn, I); } static llvm_value *llvm_expand_builtin_alloca(llvm_function *Fn, tree arglist) { Index: llvm-gcc/gcc/llvm-representation.c diff -u llvm-gcc/gcc/llvm-representation.c:1.18 llvm-gcc/gcc/llvm-representation.c:1.19 --- llvm-gcc/gcc/llvm-representation.c:1.18 Sat Jun 18 16:11:20 2005 +++ llvm-gcc/gcc/llvm-representation.c Thu Jul 7 12:32:46 2005 @@ -405,8 +405,7 @@ case O_Shl: fprintf(F, "shl"); break; case O_Shr: fprintf(F, "shr"); break; case O_Select: fprintf(F, "select"); break; - case O_VAArg: fprintf(F, "vaarg"); break; - case O_VANext: fprintf(F, "vanext"); break; + case O_VAArg: fprintf(F, "va_arg"); break; default: fprintf(F, ""); break; } } @@ -754,10 +753,6 @@ llvm_value_print_operand(Operand, 1, F); fprintf(F, ", "); llvm_type_print(D2V(I)->Ty, F); - } else if (I->Opcode == O_VANext) { - llvm_value_print_operand(Operand, 1, F); - fprintf(F, ", "); - llvm_type_print(I->x.VANext.ArgTy, F); } else if (I->NumOperands) { /* PrintAllTypes - Instructions who have operands of all the same type omit * the type from all but the first operand. If the instruction has Index: llvm-gcc/gcc/llvm-representation.h diff -u llvm-gcc/gcc/llvm-representation.h:1.16 llvm-gcc/gcc/llvm-representation.h:1.17 --- llvm-gcc/gcc/llvm-representation.h:1.16 Sat Jun 18 16:11:20 2005 +++ llvm-gcc/gcc/llvm-representation.h Thu Jul 7 12:32:46 2005 @@ -168,7 +168,7 @@ O_And, O_Or, O_Xor, O_SetEQ, O_SetNE, O_SetLE, O_SetGE, O_SetLT, O_SetGT, O_Alloca, O_Malloc, O_Load, O_Store, O_GetElementPtr, - O_PHINode, O_Cast, O_Call, O_Shl, O_Shr, O_Select, O_VAArg, O_VANext + O_PHINode, O_Cast, O_Call, O_Shl, O_Shr, O_Select, O_VAArg } Opcode; union { @@ -178,9 +178,6 @@ struct { /* Valid for the O_Switch instruction */ llvm_switch_case *Cases; } Switch; - struct { /* Valid for the O_VANext instruction */ - struct llvm_type *ArgTy; - } VANext; } x; unsigned NumOperands; From reid at x10sys.com Thu Jul 7 13:21:56 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:56 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-nm/llvm-nm.cpp Message-ID: <200507071821.NAA26408@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-nm: llvm-nm.cpp updated: 1.24 -> 1.25 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+1 -1) llvm-nm.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-nm/llvm-nm.cpp diff -u llvm/tools/llvm-nm/llvm-nm.cpp:1.24 llvm/tools/llvm-nm/llvm-nm.cpp:1.25 --- llvm/tools/llvm-nm/llvm-nm.cpp:1.24 Thu Apr 21 18:59:41 2005 +++ llvm/tools/llvm-nm/llvm-nm.cpp Thu Jul 7 13:21:42 2005 @@ -119,7 +119,7 @@ void DumpSymbolNamesFromFile (std::string &Filename) { std::string ErrorMessage; sys::Path aPath(Filename); - if (Filename != "-" && !aPath.readable()) { + if (Filename != "-" && !aPath.canRead()) { std::cerr << ToolName << ": " << Filename << ": " << strerror (errno) << "\n"; return; From reid at x10sys.com Thu Jul 7 13:21:56 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Path.cpp Message-ID: <200507071821.NAA26406@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Path.cpp updated: 1.17 -> 1.18 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+2 -2) Path.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/System/Path.cpp diff -u llvm/lib/System/Path.cpp:1.17 llvm/lib/System/Path.cpp:1.18 --- llvm/lib/System/Path.cpp:1.17 Thu May 5 17:33:05 2005 +++ llvm/lib/System/Path.cpp Thu Jul 7 13:21:42 2005 @@ -62,14 +62,14 @@ bool Path::isArchive() const { - if (readable()) + if (canRead()) return hasMagicNumber("!\012"); return false; } bool Path::isDynamicLibrary() const { - if (readable()) + if (canRead()) return hasMagicNumber("\177ELF"); return false; } From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/SystemUtils.cpp Message-ID: <200507071821.NAA26424@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.43 -> 1.44 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+1 -1) SystemUtils.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.43 llvm/lib/Support/SystemUtils.cpp:1.44 --- llvm/lib/Support/SystemUtils.cpp:1.43 Tue May 10 17:03:50 2005 +++ llvm/lib/Support/SystemUtils.cpp Thu Jul 7 13:21:42 2005 @@ -48,7 +48,7 @@ Result.elideFile(); if (!Result.isEmpty()) { Result.appendFile(ExeName); - if (Result.executable()) + if (Result.canExecute()) return Result; } From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkItems.cpp Linker.cpp Message-ID: <200507071821.NAA26420@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkItems.cpp updated: 1.6 -> 1.7 Linker.cpp updated: 1.5 -> 1.6 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+2 -2) LinkItems.cpp | 2 +- Linker.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Linker/LinkItems.cpp diff -u llvm/lib/Linker/LinkItems.cpp:1.6 llvm/lib/Linker/LinkItems.cpp:1.7 --- llvm/lib/Linker/LinkItems.cpp:1.6 Thu Apr 21 17:47:36 2005 +++ llvm/lib/Linker/LinkItems.cpp Thu Jul 7 13:21:42 2005 @@ -118,7 +118,7 @@ /// bool Linker::LinkInFile(const sys::Path &File) { // Make sure we can at least read the file - if (!File.readable()) + if (!File.canRead()) return error("Cannot find linker input '" + File.toString() + "'"); // A user may specify an ar archive without -l, perhaps because it Index: llvm/lib/Linker/Linker.cpp diff -u llvm/lib/Linker/Linker.cpp:1.5 llvm/lib/Linker/Linker.cpp:1.6 --- llvm/lib/Linker/Linker.cpp:1.5 Thu Apr 21 17:47:36 2005 +++ llvm/lib/Linker/Linker.cpp Thu Jul 7 13:21:42 2005 @@ -153,7 +153,7 @@ { // Determine if the pathname can be found as it stands. sys::Path FilePath(Filename); - if (FilePath.readable() && + if (FilePath.canRead() && (FilePath.isArchive() || FilePath.isDynamicLibrary())) return FilePath; From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200507071821.NAA26436@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.22 -> 1.23 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+11 -3) Path.h | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.22 llvm/include/llvm/System/Path.h:1.23 --- llvm/include/llvm/System/Path.h:1.22 Thu May 5 17:31:47 2005 +++ llvm/include/llvm/System/Path.h Thu Jul 7 13:21:42 2005 @@ -241,6 +241,14 @@ /// @brief Determines if the path name references a directory. bool isDirectory() const; + /// This function determines if the path refers to a hidden file. The + /// notion of hidden files is defined by the underlying system. The + /// system may not support hidden files in which case this function always + /// returns false on such systems. Hidden files have the "hidden" + /// attribute set on Win32. On Unix, hidden files start with a period. + /// @brief Determines if the path name references a hidden file. + bool isHidden() const; + /// This function determines if the path name in this object references /// the root (top level directory) of the file system. The details of what /// is considered the "root" may vary from system to system so this method @@ -303,7 +311,7 @@ /// @returns true if the pathname references a readable file. /// @brief Determines if the path is a readable file or directory /// in the file system. - bool readable() const; + bool canRead() const; /// This function determines if the path name references a writable file /// or directory in the file system. Unlike isFile and isDirectory, this @@ -312,7 +320,7 @@ /// @returns true if the pathname references a writable file. /// @brief Determines if the path is a writable file or directory /// in the file system. - bool writable() const; + bool canWrite() const; /// This function determines if the path name references an executable /// file in the file system. Unlike isFile and isDirectory, this @@ -321,7 +329,7 @@ /// @returns true if the pathname references an executable file. /// @brief Determines if the path is an executable file in the file /// system. - bool executable() const; + bool canExecute() const; /// This function returns the current contents of the path as a /// std::string. This allows the underlying path string to be manipulated From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Program.inc Message-ID: <200507071821.NAA26444@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.35 -> 1.36 Program.inc updated: 1.13 -> 1.14 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+9 -9) Path.inc | 12 ++++++------ Program.inc | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.35 llvm/lib/System/Unix/Path.inc:1.36 --- llvm/lib/System/Unix/Path.inc:1.35 Thu Jun 2 00:38:20 2005 +++ llvm/lib/System/Unix/Path.inc Thu Jul 7 13:21:42 2005 @@ -168,14 +168,14 @@ while( delim != 0 ) { std::string tmp(at, size_t(delim-at)); if (tmpPath.setDirectory(tmp)) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); at = delim + 1; delim = strchr(at, ':'); } if (*at != 0) if (tmpPath.setDirectory(std::string(at))) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); } @@ -205,7 +205,7 @@ { Path tmpPath; if (tmpPath.setDirectory(LLVM_LIBDIR)) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); } #endif @@ -305,17 +305,17 @@ } bool -Path::readable() const { +Path::canRead() const { return 0 == access(path.c_str(), F_OK | R_OK ); } bool -Path::writable() const { +Path::canWrite() const { return 0 == access(path.c_str(), F_OK | W_OK ); } bool -Path::executable() const { +Path::canExecute() const { struct stat st; int r = stat(path.c_str(), &st); if (r != 0 || !S_ISREG(st.st_mode)) Index: llvm/lib/System/Unix/Program.inc diff -u llvm/lib/System/Unix/Program.inc:1.13 llvm/lib/System/Unix/Program.inc:1.14 --- llvm/lib/System/Unix/Program.inc:1.13 Thu May 5 17:33:06 2005 +++ llvm/lib/System/Unix/Program.inc Thu Jul 7 13:21:42 2005 @@ -46,7 +46,7 @@ return Path(); // FIXME: have to check for absolute filename - we cannot assume anything // about "." being in $PATH - if (temp.executable()) // already executable as is + if (temp.canExecute()) // already executable as is return temp; // At this point, the file name is valid and its not executable @@ -66,7 +66,7 @@ Path FilePath; if (FilePath.setDirectory(std::string(PathStr,Colon))) { FilePath.appendFile(progName); - if (FilePath.executable()) + if (FilePath.canExecute()) return FilePath; // Found the executable! } @@ -109,7 +109,7 @@ const Path** redirects, unsigned secondsToWait ) { - if (!path.executable()) + if (!path.canExecute()) throw path.toString() + " is not executable"; #ifdef HAVE_SYS_WAIT_H From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Debugger/ProgramInfo.cpp Message-ID: <200507071821.NAA26432@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: ProgramInfo.cpp updated: 1.10 -> 1.11 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+1 -1) ProgramInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Debugger/ProgramInfo.cpp diff -u llvm/lib/Debugger/ProgramInfo.cpp:1.10 llvm/lib/Debugger/ProgramInfo.cpp:1.11 --- llvm/lib/Debugger/ProgramInfo.cpp:1.10 Thu Apr 21 17:36:21 2005 +++ llvm/lib/Debugger/ProgramInfo.cpp Thu Jul 7 13:21:42 2005 @@ -174,7 +174,7 @@ if (!Directory.empty()) tmpPath.setDirectory(Directory); tmpPath.appendFile(BaseName); - if (tmpPath.readable()) + if (tmpPath.canRead()) SourceText = new SourceFile(tmpPath.toString(), Descriptor); else SourceText = new SourceFile(BaseName, Descriptor); From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507071821.NAA26414@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.31 -> 1.32 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+6 -6) Path.inc | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.31 llvm/lib/System/Win32/Path.inc:1.32 --- llvm/lib/System/Win32/Path.inc:1.31 Thu May 5 17:33:09 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 13:21:42 2005 @@ -139,14 +139,14 @@ while( delim != 0 ) { std::string tmp(at, size_t(delim-at)); if (tmpPath.setDirectory(tmp)) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); at = delim + 1; delim = strchr(at, ';'); } if (*at != 0) if (tmpPath.setDirectory(std::string(at))) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); } @@ -167,7 +167,7 @@ { Path tmpPath; if (tmpPath.setDirectory(LLVM_LIBDIR)) - if (tmpPath.readable()) + if (tmpPath.canRead()) Paths.push_back(tmpPath); } #endif @@ -237,21 +237,21 @@ } bool -Path::readable() const { +Path::canRead() const { // FIXME: take security attributes into account. DWORD attr = GetFileAttributes(path.c_str()); return attr != INVALID_FILE_ATTRIBUTES; } bool -Path::writable() const { +Path::canWrite() const { // FIXME: take security attributes into account. DWORD attr = GetFileAttributes(path.c_str()); return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY); } bool -Path::executable() const { +Path::canExecute() const { // FIXME: take security attributes into account. DWORD attr = GetFileAttributes(path.c_str()); return attr != INVALID_FILE_ATTRIBUTES; From reid at x10sys.com Thu Jul 7 13:21:57 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 13:21:57 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvmc/CompilerDriver.cpp Configuration.cpp Message-ID: <200507071821.NAA26422@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvmc: CompilerDriver.cpp updated: 1.31 -> 1.32 Configuration.cpp updated: 1.21 -> 1.22 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Change interface to Path class: readable -> canRead writable -> canWrite executable -> canExecute More (incremental) changes coming to close 495. --- Diffs of the changes: (+14 -14) CompilerDriver.cpp | 18 +++++++++--------- Configuration.cpp | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) Index: llvm/tools/llvmc/CompilerDriver.cpp diff -u llvm/tools/llvmc/CompilerDriver.cpp:1.31 llvm/tools/llvmc/CompilerDriver.cpp:1.32 --- llvm/tools/llvmc/CompilerDriver.cpp:1.31 Wed May 18 19:52:29 2005 +++ llvm/tools/llvmc/CompilerDriver.cpp Thu Jul 7 13:21:42 2005 @@ -187,7 +187,7 @@ void cleanup() { if (!isSet(KEEP_TEMPS_FLAG)) { - if (TempDir.isDirectory() && TempDir.writable()) + if (TempDir.isDirectory() && TempDir.canWrite()) TempDir.destroyDirectory(/*remove_contents=*/true); } else { std::cout << "Temporary files are in " << TempDir << "\n"; @@ -415,7 +415,7 @@ if (progpath.isEmpty()) throw std::string("Can't find program '" + action->program.toString()+"'"); - else if (progpath.executable()) + else if (progpath.canExecute()) action->program = progpath; else throw std::string("Program '"+action->program.toString()+ @@ -449,32 +449,32 @@ bool native = false) { sys::Path fullpath; fullpath.setFile(link_item); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; for (PathVector::iterator PI = LibraryPaths.begin(), PE = LibraryPaths.end(); PI != PE; ++PI) { fullpath.setDirectory(PI->toString()); fullpath.appendFile(link_item); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; if (native) { fullpath.appendSuffix("a"); } else { fullpath.appendSuffix("bc"); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; fullpath.elideSuffix(); fullpath.appendSuffix("o"); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; fullpath = *PI; fullpath.appendFile(std::string("lib") + link_item); fullpath.appendSuffix("a"); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; fullpath.elideSuffix(); fullpath.appendSuffix("so"); - if (fullpath.readable()) + if (fullpath.canRead()) return fullpath; } } @@ -494,7 +494,7 @@ // First, see if the unadorned file name is not readable. If so, // we must track down the file in the lib search path. sys::Path fullpath; - if (!link_item.readable()) { + if (!link_item.canRead()) { // look for the library using the -L arguments specified // on the command line. fullpath = GetPathForLinkageItem(link_item.toString()); Index: llvm/tools/llvmc/Configuration.cpp diff -u llvm/tools/llvmc/Configuration.cpp:1.21 llvm/tools/llvmc/Configuration.cpp:1.22 --- llvm/tools/llvmc/Configuration.cpp:1.21 Wed May 18 20:06:46 2005 +++ llvm/tools/llvmc/Configuration.cpp Thu Jul 7 13:21:42 2005 @@ -549,7 +549,7 @@ if (conf) { confFile.setDirectory(conf); confFile.appendFile(ftype); - if (!confFile.readable()) + if (!confFile.canRead()) throw std::string("Configuration file for '") + ftype + "' is not available."; } else { @@ -559,18 +559,18 @@ confFile.appendDirectory(".llvm"); confFile.appendDirectory("etc"); confFile.appendFile(ftype); - if (!confFile.readable()) + if (!confFile.canRead()) confFile.clear(); } if (confFile.isEmpty()) { // Okay, try the LLVM installation directory confFile = sys::Path::GetLLVMConfigDir(); confFile.appendFile(ftype); - if (!confFile.readable()) { + if (!confFile.canRead()) { // Okay, try the "standard" place confFile = sys::Path::GetLLVMDefaultConfigDir(); confFile.appendFile(ftype); - if (!confFile.readable()) { + if (!confFile.canRead()) { throw std::string("Configuration file for '") + ftype + "' is not available."; } @@ -580,7 +580,7 @@ } else { confFile = configDir; confFile.appendFile(ftype); - if (!confFile.readable()) + if (!confFile.canRead()) throw std::string("Configuration file for '") + ftype + "' is not available."; } From alenhar2 at cs.uiuc.edu Thu Jul 7 14:53:09 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Jul 2005 14:53:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp AlphaRegisterInfo.cpp Message-ID: <200507071953.OAA30418@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.147 -> 1.148 AlphaRegisterInfo.cpp updated: 1.23 -> 1.24 --- Log message: clean up prolouge and epilouge --- Diffs of the changes: (+39 -28) AlphaISelPattern.cpp | 16 +++++++++++++-- AlphaRegisterInfo.cpp | 51 ++++++++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 28 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.147 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.148 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.147 Tue Jul 5 14:58:53 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Jul 7 14:52:58 2005 @@ -94,10 +94,10 @@ setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - setOperationAction(ISD::ZEXTLOAD, MVT::i1, Expand); + setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); - setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); + setOperationAction(ISD::SEXTLOAD, MVT::i1, Promote); setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); @@ -613,6 +613,7 @@ ++i; offset = i; } else if (const Instruction* I = dyn_cast(v)) { + assert(dyn_cast(I->getType())); type = 3; const BasicBlock* bb = I->getParent(); const Function* F = bb->getParent(); @@ -627,6 +628,13 @@ for(BasicBlock::const_iterator ii = bb->begin(); &*ii != I; ++ii) ++i; offset = i; + } else if (const Constant* C = dyn_cast(v)) { + //Don't know how to look these up yet + type = 0; + fun = 0; + offset = 0; + } else { + assert(0 && "Error in value marking"); } //type = 4: register spilling //type = 5: global address loading or constant loading @@ -1407,6 +1415,10 @@ BuildMI(BB, Alpha::BSR, 1, Alpha::R26) .addGlobalAddress(GASD->getGlobal(),true); } else { + //Must always reread relocation table before a call + if (GASD) + ExprMap.erase(N.getOperand(1)); + //no need to restore GP as we are doing an indirect call Tmp1 = SelectExpr(N.getOperand(1)); BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1); Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.23 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.24 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.23 Fri Jul 1 14:12:13 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Thu Jul 7 14:52:58 2005 @@ -224,15 +224,12 @@ MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineInstr *MI; bool FP = hasFP(MF); //handle GOP offset - MI = BuildMI(Alpha::LDGP, 0); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::LDGP, 0); //evil const_cast until MO stuff setup to handle const - MI = BuildMI(Alpha::ALTENT, 1).addGlobalAddress(const_cast(MF.getFunction()), true); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::ALTENT, 1).addGlobalAddress(const_cast(MF.getFunction()), true); // Get the number of bytes to allocate from the FrameInfo long NumBytes = MFI->getStackSize(); @@ -259,13 +256,13 @@ // adjust stack pointer: r30 -= numbytes NumBytes = -NumBytes; if (NumBytes >= IMM_LOW) { - MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(NumBytes).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) + .addReg(Alpha::R30); } else if (getUpper16(NumBytes) >= IMM_LOW) { - MI=BuildMI(Alpha::LDAH, 2, Alpha::R30).addImm(getUpper16(NumBytes)).addReg(Alpha::R30); - MBB.insert(MBBI, MI); - MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(getLower16(NumBytes)).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30).addImm(getUpper16(NumBytes)) + .addReg(Alpha::R30); + BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(getLower16(NumBytes)) + .addReg(Alpha::R30); } else { std::cerr << "Too big a stack frame at " << NumBytes << "\n"; abort(); @@ -274,11 +271,12 @@ //now if we need to, save the old FP and set the new if (FP) { - MI=BuildMI(Alpha::STQ, 3).addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + if (EnableAlphaLSMark) + BuildMI(MBB, MBBI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(1) + .addImm(getUID()); + BuildMI(MBB, MBBI, Alpha::STQ, 3).addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); //this must be the last instr in the prolog - MI=BuildMI(Alpha::BIS, 2, Alpha::R15).addReg(Alpha::R30).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R15).addReg(Alpha::R30).addReg(Alpha::R30); } } @@ -287,7 +285,6 @@ MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); - MachineInstr *MI; assert((MBBI->getOpcode() == Alpha::RET) && "Can only insert epilog into returning blocks"); @@ -300,23 +297,25 @@ if (FP) { //copy the FP into the SP (discards allocas) - MI=BuildMI(Alpha::BIS, 2, Alpha::R30).addReg(Alpha::R15).addReg(Alpha::R15); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R30).addReg(Alpha::R15) + .addReg(Alpha::R15); //restore the FP - MI=BuildMI(Alpha::LDQ, 2, Alpha::R15).addImm(0).addReg(Alpha::R15); - MBB.insert(MBBI, MI); + if (EnableAlphaLSMark) + BuildMI(MBB, MBBI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(2) + .addImm(getUID()); + BuildMI(MBB, MBBI, Alpha::LDQ, 2, Alpha::R15).addImm(0).addReg(Alpha::R15); } if (NumBytes != 0) { if (NumBytes <= IMM_HIGH) { - MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(NumBytes).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) + .addReg(Alpha::R30); } else if (getUpper16(NumBytes) <= IMM_HIGH) { - MI=BuildMI(Alpha::LDAH, 2, Alpha::R30).addImm(getUpper16(NumBytes)).addReg(Alpha::R30); - MBB.insert(MBBI, MI); - MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(getLower16(NumBytes)).addReg(Alpha::R30); - MBB.insert(MBBI, MI); + BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30) + .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); + BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30) + .addImm(getLower16(NumBytes)).addReg(Alpha::R30); } else { std::cerr << "Too big a stack frame at " << NumBytes << "\n"; abort(); From lattner at cs.uiuc.edu Thu Jul 7 15:39:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 15:39:56 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2005-07-07-DeadPHILoop.ll Message-ID: <200507072039.PAA30830@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2005-07-07-DeadPHILoop.ll added (r1.1) --- Log message: New testcase distilled from a large chunk of code Misha sent me. --- Diffs of the changes: (+13 -0) 2005-07-07-DeadPHILoop.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/2005-07-07-DeadPHILoop.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2005-07-07-DeadPHILoop.ll:1.1 *** /dev/null Thu Jul 7 15:39:55 2005 --- llvm/test/Regression/Transforms/InstCombine/2005-07-07-DeadPHILoop.ll Thu Jul 7 15:39:45 2005 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | opt -instcombine -disable-output + + ; This example caused instcombine to spin into an infinite loop. + + void %test(int *%P) { + ret void + Dead: + %X = phi int [%Y, %Dead] + %Y = div int %X, 10 + store int %Y, int* %P + br label %Dead + } + From lattner at cs.uiuc.edu Thu Jul 7 15:40:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Jul 2005 15:40:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200507072040.PAA30847@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.356 -> 1.357 --- Log message: Fix a problem that instcombine would hit when dealing with unreachable code. Because the instcombine has to scan the entire function when it starts up to begin with, we might as well do it in DFO so we can nuke unreachable code. This fixes: Transforms/InstCombine/2005-07-07-DeadPHILoop.ll --- Diffs of the changes: (+28 -4) InstructionCombining.cpp | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.356 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.357 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.356 Sat Jun 18 12:37:34 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Jul 7 15:40:38 2005 @@ -45,9 +45,9 @@ #include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/Support/InstIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/PatternMatch.h" +#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include @@ -4400,7 +4400,8 @@ // However, because we don't have dom info, we can't do a perfect job. if (Instruction *I = dyn_cast(V)) { // We know that the instruction dominates the PHI if there are no undef - // values coming in. + // values coming in. If the instruction is defined in the entry block, + // and is not an invoke, we know it is ok. if (I->getParent() != &I->getParent()->getParent()->front() || isa(I)) for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) @@ -5226,9 +5227,32 @@ bool Changed = false; TD = &getAnalysis(); - for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) - WorkList.push_back(&*i); + { + // Populate the worklist with the reachable instructions. + std::set Visited; + for (df_ext_iterator BB = df_ext_begin(&F.front(), Visited), + E = df_ext_end(&F.front(), Visited); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + WorkList.push_back(I); + + // Do a quick scan over the function. If we find any blocks that are + // unreachable, remove any instructions inside of them. This prevents + // the instcombine code from having to deal with some bad special cases. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (!Visited.count(BB)) { + Instruction *Term = BB->getTerminator(); + while (Term != BB->begin()) { // Remove instrs bottom-up + BasicBlock::iterator I = Term; --I; + + DEBUG(std::cerr << "IC: DCE: " << *I); + ++NumDeadInst; + if (!I->use_empty()) + I->replaceAllUsesWith(UndefValue::get(I->getType())); + I->eraseFromParent(); + } + } + } while (!WorkList.empty()) { Instruction *I = WorkList.back(); // Get an instruction from the worklist From reid at x10sys.com Thu Jul 7 18:21:59 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:21:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveReader.cpp ArchiveWriter.cpp Message-ID: <200507072321.SAA31933@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveReader.cpp updated: 1.40 -> 1.41 ArchiveWriter.cpp updated: 1.18 -> 1.19 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+4 -4) ArchiveReader.cpp | 2 +- ArchiveWriter.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Bytecode/Archive/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.40 llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.41 --- llvm/lib/Bytecode/Archive/ArchiveReader.cpp:1.40 Thu Apr 21 16:13:18 2005 +++ llvm/lib/Bytecode/Archive/ArchiveReader.cpp Thu Jul 7 18:21:43 2005 @@ -187,7 +187,7 @@ member->next = 0; member->prev = 0; member->parent = this; - member->path.setFile(pathname); + member->path.set(pathname); member->info.fileSize = MemberSize; member->info.modTime.fromEpochTime(atoi(Hdr->date)); unsigned int mode; Index: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.18 llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.19 --- llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.18 Thu Apr 21 16:13:18 2005 +++ llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Thu Jul 7 18:21:43 2005 @@ -450,17 +450,17 @@ // Close up shop FinalFile.close(); arch.close(); - TmpArchive.destroyFile(); + TmpArchive.destroy(); } else { // We don't have to insert the symbol table, so just renaming the temp // file to the correct name will suffice. - TmpArchive.renameFile(archPath); + TmpArchive.rename(archPath); } } catch (...) { // Make sure we clean up. if (TmpArchive.exists()) - TmpArchive.destroyFile(); + TmpArchive.destroy(); throw; } } From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Linker/LinkModules.cpp Linker.cpp Message-ID: <200507072322.SAA31978@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: LinkModules.cpp updated: 1.106 -> 1.107 Linker.cpp updated: 1.6 -> 1.7 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+28 -20) LinkModules.cpp | 2 +- Linker.cpp | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 20 deletions(-) Index: llvm/lib/Linker/LinkModules.cpp diff -u llvm/lib/Linker/LinkModules.cpp:1.106 llvm/lib/Linker/LinkModules.cpp:1.107 --- llvm/lib/Linker/LinkModules.cpp:1.106 Sun May 8 20:09:39 2005 +++ llvm/lib/Linker/LinkModules.cpp Thu Jul 7 18:21:43 2005 @@ -899,7 +899,7 @@ // If the source library's module id is in the dependent library list of the // destination library, remove it since that module is now linked in. sys::Path modId; - modId.setFile(Src->getModuleIdentifier()); + modId.set(Src->getModuleIdentifier()); if (!modId.isEmpty()) Dest->removeLibrary(modId.getBasename()); Index: llvm/lib/Linker/Linker.cpp diff -u llvm/lib/Linker/Linker.cpp:1.6 llvm/lib/Linker/Linker.cpp:1.7 --- llvm/lib/Linker/Linker.cpp:1.6 Thu Jul 7 13:21:42 2005 +++ llvm/lib/Linker/Linker.cpp Thu Jul 7 18:21:43 2005 @@ -69,7 +69,6 @@ void Linker::addPath(const sys::Path& path) { - assert(path.isDirectory() && "Can only insert directories into the path"); LibPaths.push_back(path); } @@ -77,7 +76,7 @@ Linker::addPaths(const std::vector& paths) { for (unsigned i = 0; i != paths.size(); ++i) { sys::Path aPath; - aPath.setDirectory(paths[i]); + aPath.set(paths[i]); LibPaths.push_back(aPath); } } @@ -118,26 +117,35 @@ static inline sys::Path IsLibrary(const std::string& Name, const sys::Path& Directory) { - assert(Directory.isDirectory() && "Need to specify a directory"); sys::Path FullPath(Directory); - FullPath.appendFile("lib" + Name); - FullPath.appendSuffix("a"); - if (FullPath.isArchive()) - return FullPath; - - FullPath.elideSuffix(); - FullPath.appendSuffix("bca"); - if (FullPath.isArchive()) - return FullPath; - - FullPath.elideSuffix(); - FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1])); - if (FullPath.isDynamicLibrary()) // Native shared library? - return FullPath; - if (FullPath.isBytecodeFile()) // .so file containing bytecode? - return FullPath; + // Make sure the directory actually is a directory in the file system. + if (FullPath.isDirectory()) + { + // Try the libX.a form + FullPath.appendComponent("lib" + Name); + FullPath.appendSuffix("a"); + if (FullPath.isArchive()) + return FullPath; + + // Try the libX.bca form + FullPath.eraseSuffix(); + FullPath.appendSuffix("bca"); + if (FullPath.isArchive()) + return FullPath; + + // Try the libX.so form + FullPath.eraseSuffix(); + FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1])); + if (FullPath.isDynamicLibrary()) // Native shared library? + return FullPath; + if (FullPath.isBytecodeFile()) // .so file containing bytecode? + return FullPath; + + // Not found .. fall through + } + // Indicate that the library was not found in the directory. FullPath.clear(); return FullPath; } From reid at x10sys.com Thu Jul 7 18:21:59 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:21:59 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-link/llvm-link.cpp Message-ID: <200507072321.SAA31937@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-link: llvm-link.cpp updated: 1.57 -> 1.58 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+1 -1) llvm-link.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-link/llvm-link.cpp diff -u llvm/tools/llvm-link/llvm-link.cpp:1.57 llvm/tools/llvm-link/llvm-link.cpp:1.58 --- llvm/tools/llvm-link/llvm-link.cpp:1.57 Thu Apr 21 18:59:40 2005 +++ llvm/tools/llvm-link/llvm-link.cpp Thu Jul 7 18:21:43 2005 @@ -50,7 +50,7 @@ // static inline std::auto_ptr LoadFile(const std::string &FN) { sys::Path Filename; - if (!Filename.setFile(FN)) { + if (!Filename.set(FN)) { std::cerr << "Invalid file name: '" << FN << "'\n"; return std::auto_ptr(); } From reid at x10sys.com Thu Jul 7 18:22:00 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Debugger/ProgramInfo.cpp Message-ID: <200507072322.SAA31949@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: ProgramInfo.cpp updated: 1.11 -> 1.12 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+2 -2) ProgramInfo.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Debugger/ProgramInfo.cpp diff -u llvm/lib/Debugger/ProgramInfo.cpp:1.11 llvm/lib/Debugger/ProgramInfo.cpp:1.12 --- llvm/lib/Debugger/ProgramInfo.cpp:1.11 Thu Jul 7 13:21:42 2005 +++ llvm/lib/Debugger/ProgramInfo.cpp Thu Jul 7 18:21:43 2005 @@ -172,8 +172,8 @@ if (SourceText == 0) { // Read the file in if we haven't already. sys::Path tmpPath; if (!Directory.empty()) - tmpPath.setDirectory(Directory); - tmpPath.appendFile(BaseName); + tmpPath.set(Directory); + tmpPath.appendComponent(BaseName); if (tmpPath.canRead()) SourceText = new SourceFile(tmpPath.toString(), Descriptor); else From reid at x10sys.com Thu Jul 7 18:22:00 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Program.inc Signals.inc Message-ID: <200507072322.SAA31943@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.36 -> 1.37 Program.inc updated: 1.14 -> 1.15 Signals.inc updated: 1.7 -> 1.8 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+83 -134) Path.inc | 209 ++++++++++++++++++++++-------------------------------------- Program.inc | 6 - Signals.inc | 2 3 files changed, 83 insertions(+), 134 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.36 llvm/lib/System/Unix/Path.inc:1.37 --- llvm/lib/System/Unix/Path.inc:1.36 Thu Jul 7 13:21:42 2005 +++ llvm/lib/System/Unix/Path.inc Thu Jul 7 18:21:43 2005 @@ -84,7 +84,7 @@ Path Path::GetRootDirectory() { Path result; - result.setDirectory("/"); + result.set("/"); return result; } @@ -98,7 +98,7 @@ if (0 == mkdtemp(pathname)) ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkdtemp didn't create a valid pathname!"); return result; #elif defined(HAVE_MKSTEMP) @@ -117,7 +117,7 @@ if (-1 == ::mkdir(pathname, S_IRWXU)) // end race condition ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkstemp didn't create a valid pathname!"); return result; #elif defined(HAVE_MKTEMP) @@ -134,7 +134,7 @@ if (-1 == ::mkdir(TmpName, S_IRWXU)) ThrowErrno(std::string(TmpName) + ": can't create temporary directory"); Path result; - result.setDirectory(TmpName); + result.set(TmpName); assert(result.isValid() && "mktemp didn't create a valid pathname!"); return result; #else @@ -155,7 +155,7 @@ if (-1 == ::mkdir(pathname, S_IRWXU)) ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkstemp didn't create a valid pathname!"); return result; #endif @@ -167,14 +167,14 @@ Path tmpPath; while( delim != 0 ) { std::string tmp(at, size_t(delim-at)); - if (tmpPath.setDirectory(tmp)) + if (tmpPath.set(tmp)) if (tmpPath.canRead()) Paths.push_back(tmpPath); at = delim + 1; delim = strchr(at, ':'); } if (*at != 0) - if (tmpPath.setDirectory(std::string(at))) + if (tmpPath.set(std::string(at))) if (tmpPath.canRead()) Paths.push_back(tmpPath); @@ -204,7 +204,7 @@ #ifdef LLVM_LIBDIR { Path tmpPath; - if (tmpPath.setDirectory(LLVM_LIBDIR)) + if (tmpPath.set(LLVM_LIBDIR)) if (tmpPath.canRead()) Paths.push_back(tmpPath); } @@ -222,7 +222,7 @@ const char* home = getenv("HOME"); if (home) { Path result; - if (result.setDirectory(home)) + if (result.set(home)) return result; } return GetRootDirectory(); @@ -230,12 +230,20 @@ bool Path::isFile() const { - return (isValid() && path[path.length()-1] != '/'); + struct stat buf; + if (0 != stat(path.c_str(), &buf)) { + ThrowErrno(path + ": can't determine type of path object: "); + } + return S_ISREG(buf.st_mode); } bool Path::isDirectory() const { - return (isValid() && path[path.length()-1] == '/'); + struct stat buf; + if (0 != stat(path.c_str(), &buf)) { + ThrowErrno(path + ": can't determine type of path object: "); + } + return S_ISDIR(buf.st_mode); } std::string @@ -357,8 +365,6 @@ info.user = buf.st_uid; info.group = buf.st_gid; info.isDir = S_ISDIR(buf.st_mode); - if (info.isDir && path[path.length()-1] != '/') - path += '/'; } static bool AddPermissionBits(const std::string& Filename, int bits) { @@ -419,8 +425,6 @@ ThrowErrno(aPath.path + ": can't determine file object type", stat_errno); } - if (S_ISDIR(buf.st_mode)) - aPath.path += "/"; result.insert(aPath); } } @@ -430,124 +434,84 @@ } bool -Path::setDirectory(const std::string& a_path) { - if (a_path.size() == 0) +Path::set(const std::string& a_path) { + if (a_path.empty()) return false; - Path save(*this); + std::string save(path); path = a_path; - size_t last = a_path.size() -1; - if (a_path[last] != '/') - path += '/'; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::setFile(const std::string& a_path) { - if (a_path.size() == 0) - return false; - Path save(*this); - path = a_path; - size_t last = a_path.size() - 1; - while (last > 0 && a_path[last] == '/') - last--; - path.erase(last+1); - if (!isValid()) { - path = save.path; +Path::appendComponent(const std::string& name) { + if (name.empty()) return false; + std::string save(path); + if (!path.empty()) { + size_t last = path.size() - 1; + if (path[last] != '/') + path += '/'; } - return true; -} - -bool -Path::appendDirectory(const std::string& dir) { - if (isFile()) - return false; - Path save(*this); - path += dir; - path += "/"; + path += name; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::elideDirectory() { - if (isFile()) - return false; +Path::eraseComponent() { size_t slashpos = path.rfind('/',path.size()); - if (slashpos == 0 || slashpos == std::string::npos) - return false; + if (slashpos == 0 || slashpos == std::string::npos) { + path.erase(); + return true; + } if (slashpos == path.size() - 1) slashpos = path.rfind('/',slashpos-1); - if (slashpos == std::string::npos) - return false; - path.erase(slashpos); - return true; -} - -bool -Path::appendFile(const std::string& file) { - if (!isDirectory()) - return false; - Path save(*this); - path += file; - if (!isValid()) { - path = save.path; - return false; + if (slashpos == std::string::npos) { + path.erase(); + return true; } - return true; -} - -bool -Path::elideFile() { - if (isDirectory()) - return false; - size_t slashpos = path.rfind('/',path.size()); - if (slashpos == std::string::npos) - return false; - path.erase(slashpos+1); + path.erase(slashpos); return true; } bool Path::appendSuffix(const std::string& suffix) { - if (isDirectory()) - return false; - Path save(*this); + std::string save(path); path.append("."); path.append(suffix); if (!isValid()) { - path = save.path; + path = save; return false; } return true; } -bool -Path::elideSuffix() { - if (isDirectory()) return false; +bool +Path::eraseSuffix() { + std::string save(path); size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); - if (slashpos != std::string::npos && dotpos != std::string::npos && + if (slashpos != std::string::npos && + dotpos != std::string::npos && dotpos > slashpos) { path.erase(dotpos, path.size()-dotpos); - return true; } - return false; + if (!isValid()) { + path = save; + return false; + } + return true; } - bool Path::createDirectory( bool create_parents) { - // Make sure we're dealing with a directory - if (!isDirectory()) return false; - // Get a writeable copy of the path name char pathname[MAXPATHLEN]; path.copy(pathname,MAXPATHLEN); @@ -586,9 +550,6 @@ bool Path::createFile() { - // Make sure we're dealing with a file - if (!isFile()) return false; - // Create the file int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR); if (fd < 0) @@ -600,10 +561,6 @@ bool Path::createTemporaryFile(bool reuse_current) { - // Make sure we're dealing with a file - if (!isFile()) - return false; - // Make this into a unique file name makeUnique( reuse_current ); @@ -617,45 +574,38 @@ } bool -Path::destroyDirectory(bool remove_contents) const { +Path::destroy(bool remove_contents) const { // Make sure we're dealing with a directory - if (!isDirectory()) return false; - - // If it doesn't exist, we're done. - if (!exists()) return true; - - if (remove_contents) { - // Recursively descend the directory to remove its content - std::string cmd("/bin/rm -rf "); - cmd += path; - system(cmd.c_str()); - } else { - // Otherwise, try to just remove the one directory - char pathname[MAXPATHLEN]; - path.copy(pathname,MAXPATHLEN); - int lastchar = path.length() - 1 ; - if (pathname[lastchar] == '/') - pathname[lastchar] = 0; - else - pathname[lastchar+1] = 0; - if ( 0 != rmdir(pathname)) - ThrowErrno(std::string(pathname) + ": can't destroy directory"); + if (isFile()) { + if (0 != unlink(path.c_str())) + ThrowErrno(path + ": can't destroy file"); + } else if (isDirectory()) { + if (remove_contents) { + // Recursively descend the directory to remove its content + std::string cmd("/bin/rm -rf "); + cmd += path; + system(cmd.c_str()); + } else { + // Otherwise, try to just remove the one directory + char pathname[MAXPATHLEN]; + path.copy(pathname,MAXPATHLEN); + int lastchar = path.length() - 1 ; + if (pathname[lastchar] == '/') + pathname[lastchar] = 0; + else + pathname[lastchar+1] = 0; + if ( 0 != rmdir(pathname)) + ThrowErrno(std::string(pathname) + ": can't destroy directory"); + } } + else + return false; return true; } bool -Path::destroyFile() const { - if (!isFile()) return false; - if (0 != unlink(path.c_str())) - ThrowErrno(path + ": can't destroy file"); - return true; -} - -bool -Path::renameFile(const Path& newName) { - if (!isFile()) return false; - if (0 != rename(path.c_str(), newName.c_str())) +Path::rename(const Path& newName) { + if (0 != ::rename(path.c_str(), newName.c_str())) ThrowErrno(std::string("can't rename '") + path + "' as '" + newName.toString() + "' "); return true; @@ -663,7 +613,6 @@ bool Path::setStatusInfo(const StatusInfo& si) const { - if (!isFile()) return false; struct utimbuf utb; utb.actime = si.modTime.toPosixTime(); utb.modtime = utb.actime; Index: llvm/lib/System/Unix/Program.inc diff -u llvm/lib/System/Unix/Program.inc:1.14 llvm/lib/System/Unix/Program.inc:1.15 --- llvm/lib/System/Unix/Program.inc:1.14 Thu Jul 7 13:21:42 2005 +++ llvm/lib/System/Unix/Program.inc Thu Jul 7 18:21:43 2005 @@ -42,7 +42,7 @@ if (progName.length() == 0) // no program return Path(); Path temp; - if (!temp.setFile(progName)) // invalid name + if (!temp.set(progName)) // invalid name return Path(); // FIXME: have to check for absolute filename - we cannot assume anything // about "." being in $PATH @@ -64,8 +64,8 @@ // Check to see if this first directory contains the executable... Path FilePath; - if (FilePath.setDirectory(std::string(PathStr,Colon))) { - FilePath.appendFile(progName); + if (FilePath.set(std::string(PathStr,Colon))) { + FilePath.appendComponent(progName); if (FilePath.canExecute()) return FilePath; // Found the executable! } Index: llvm/lib/System/Unix/Signals.inc diff -u llvm/lib/System/Unix/Signals.inc:1.7 llvm/lib/System/Unix/Signals.inc:1.8 --- llvm/lib/System/Unix/Signals.inc:1.7 Thu May 5 17:33:06 2005 +++ llvm/lib/System/Unix/Signals.inc Thu Jul 7 18:21:43 2005 @@ -112,7 +112,7 @@ if (DirectoriesToRemove != 0) while (!DirectoriesToRemove->empty()) { - DirectoriesToRemove->back().destroyDirectory(true); + DirectoriesToRemove->back().destroy(true); DirectoriesToRemove->pop_back(); } From reid at x10sys.com Thu Jul 7 18:22:00 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:00 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ranlib/llvm-ranlib.cpp Message-ID: <200507072322.SAA31958@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ranlib: llvm-ranlib.cpp updated: 1.6 -> 1.7 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+1 -1) llvm-ranlib.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-ranlib/llvm-ranlib.cpp diff -u llvm/tools/llvm-ranlib/llvm-ranlib.cpp:1.6 llvm/tools/llvm-ranlib/llvm-ranlib.cpp:1.7 --- llvm/tools/llvm-ranlib/llvm-ranlib.cpp:1.6 Thu Apr 21 18:59:44 2005 +++ llvm/tools/llvm-ranlib/llvm-ranlib.cpp Thu Jul 7 18:21:43 2005 @@ -59,7 +59,7 @@ // Check the path name of the archive sys::Path ArchivePath; - if (!ArchivePath.setFile(ArchiveName)) + if (!ArchivePath.set(ArchiveName)) throw std::string("Archive name invalid: ") + ArchiveName; // Make sure it exists, we don't create empty archives From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200507072322.SAA31965@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.24 -> 1.25 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+2 -2) llvm-ld.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.24 llvm/tools/llvm-ld/llvm-ld.cpp:1.25 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.24 Thu Apr 21 18:59:38 2005 +++ llvm/tools/llvm-ld/llvm-ld.cpp Thu Jul 7 18:21:43 2005 @@ -480,7 +480,7 @@ gcc, envp); // Remove the assembly language file. - AssemblyFile.destroyFile(); + AssemblyFile.destroy(); } else if (NativeCBE) { sys::Path CFile (OutputFilename); CFile.appendSuffix("cbe.c"); @@ -505,7 +505,7 @@ GenerateNative(OutputFilename, CFile.toString(), Libraries, gcc, envp); // Remove the assembly language file. - CFile.destroyFile(); + CFile.destroy(); } else { EmitShellScript(argv); From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp ExecutionDriver.cpp Miscompilation.cpp OptimizerDriver.cpp Message-ID: <200507072322.SAA31998@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.42 -> 1.43 ExecutionDriver.cpp updated: 1.54 -> 1.55 Miscompilation.cpp updated: 1.65 -> 1.66 OptimizerDriver.cpp updated: 1.31 -> 1.32 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+15 -14) CrashDebugger.cpp | 4 ++-- ExecutionDriver.cpp | 11 ++++++----- Miscompilation.cpp | 10 +++++----- OptimizerDriver.cpp | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.42 llvm/tools/bugpoint/CrashDebugger.cpp:1.43 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.42 Thu Apr 21 18:59:23 2005 +++ llvm/tools/bugpoint/CrashDebugger.cpp Thu Jul 7 18:21:43 2005 @@ -58,7 +58,7 @@ if (BD.runPasses(Prefix, PfxOutput)) return KeepPrefix; - PrefixOutput.setFile(PfxOutput); + PrefixOutput.set(PfxOutput); OrigProgram = BD.Program; BD.Program = ParseInputFile(PrefixOutput.toString()); @@ -67,7 +67,7 @@ << PrefixOutput << "'!\n"; exit(1); } - PrefixOutput.destroyFile(); + PrefixOutput.destroy(); } std::cout << "Checking to see if these passes crash: " Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.54 llvm/tools/bugpoint/ExecutionDriver.cpp:1.55 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.54 Thu Apr 21 18:59:23 2005 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu Jul 7 18:21:43 2005 @@ -281,7 +281,7 @@ exit(1); // Remove the intermediate C file - OutputCFile.destroyFile(); + OutputCFile.destroy(); return "./" + SharedObjectFile; } @@ -302,9 +302,9 @@ // If we're checking the program exit code, assume anything nonzero is bad. if (CheckProgramExitCode && ProgramExitedNonzero) { - Output.destroyFile(); + Output.destroy(); if (RemoveBytecode) - sys::Path(BytecodeFile).destroyFile(); + sys::Path(BytecodeFile).destroy(); return true; } @@ -321,10 +321,11 @@ } // Remove the generated output. - Output.destroyFile(); + Output.destroy(); // Remove the bytecode file if we are supposed to. - if (RemoveBytecode) sys::Path(BytecodeFile).destroyFile(); + if (RemoveBytecode) + sys::Path(BytecodeFile).destroy(); return FilesDifferent; } Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.65 llvm/tools/bugpoint/Miscompilation.cpp:1.66 --- llvm/tools/bugpoint/Miscompilation.cpp:1.65 Sun May 8 16:54:56 2005 +++ llvm/tools/bugpoint/Miscompilation.cpp Thu Jul 7 18:21:43 2005 @@ -99,7 +99,7 @@ // If the prefix maintains the predicate by itself, only keep the prefix! if (BD.diffProgram(BytecodeResult)) { std::cout << " nope.\n"; - sys::Path(BytecodeResult).destroyFile(); + sys::Path(BytecodeResult).destroy(); return KeepPrefix; } std::cout << " yup.\n"; // No miscompilation! @@ -113,7 +113,7 @@ << BytecodeResult << "'!\n"; exit(1); } - sys::Path(BytecodeResult).destroyFile(); // No longer need the file on disk + sys::Path(BytecodeResult).destroy(); // No longer need the file on disk // Don't check if there are no passes in the suffix. if (Suffix.empty()) @@ -775,9 +775,9 @@ std::cerr << ": still failing!\n"; else std::cerr << ": didn't fail.\n"; - TestModuleBC.destroyFile(); - SafeModuleBC.destroyFile(); - sys::Path(SharedObject).destroyFile(); + TestModuleBC.destroy(); + SafeModuleBC.destroy(); + sys::Path(SharedObject).destroy(); return Result; } Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.31 llvm/tools/bugpoint/OptimizerDriver.cpp:1.32 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.31 Thu Apr 21 23:13:13 2005 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Thu Jul 7 18:21:43 2005 @@ -161,7 +161,7 @@ // If we are supposed to delete the bytecode file or if the passes crashed, // remove it now. This may fail if the file was never created, but that's ok. if (DeleteOutput || !ExitedOK) - sys::Path(OutputFilename).destroyFile(); + sys::Path(OutputFilename).destroy(); #ifndef PLATFORMINDEPENDENT if (!Quiet) { @@ -214,6 +214,6 @@ << BytecodeResult << "'!\n"; exit(1); } - sys::Path(BytecodeResult).destroyFile(); // No longer need the file on disk + sys::Path(BytecodeResult).destroy(); // No longer need the file on disk return Ret; } From reid at x10sys.com Thu Jul 7 18:22:00 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/SystemUtils.cpp ToolRunner.cpp Message-ID: <200507072322.SAA31953@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.44 -> 1.45 ToolRunner.cpp updated: 1.42 -> 1.43 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+5 -5) SystemUtils.cpp | 4 ++-- ToolRunner.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.44 llvm/lib/Support/SystemUtils.cpp:1.45 --- llvm/lib/Support/SystemUtils.cpp:1.44 Thu Jul 7 13:21:42 2005 +++ llvm/lib/Support/SystemUtils.cpp Thu Jul 7 18:21:43 2005 @@ -45,9 +45,9 @@ // if ProgramPath contains at least one / character, indicating that it is a // relative path to bugpoint itself. sys::Path Result ( ProgramPath ); - Result.elideFile(); + Result.eraseComponent(); if (!Result.isEmpty()) { - Result.appendFile(ExeName); + Result.appendComponent(ExeName); if (Result.canExecute()) return Result; } Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.42 llvm/lib/Support/ToolRunner.cpp:1.43 --- llvm/lib/Support/ToolRunner.cpp:1.42 Thu Apr 21 17:52:05 2005 +++ llvm/lib/Support/ToolRunner.cpp Thu Jul 7 18:21:43 2005 @@ -65,7 +65,7 @@ ErrorFile.close(); } - ErrorFilename.destroyFile(); + ErrorFilename.destroy(); throw ToolExecutionError(OS.str()); } @@ -176,7 +176,7 @@ void LLC::compileProgram(const std::string &Bytecode) { sys::Path OutputAsmFile; OutputAsm(Bytecode, OutputAsmFile); - OutputAsmFile.destroyFile(); + OutputAsmFile.destroy(); } int LLC::ExecuteProgram(const std::string &Bytecode, @@ -321,7 +321,7 @@ void CBE::compileProgram(const std::string &Bytecode) { sys::Path OutputCFile; OutputC(Bytecode, OutputCFile); - OutputCFile.destroyFile(); + OutputCFile.destroy(); } int CBE::ExecuteProgram(const std::string &Bytecode, From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp gccld.cpp Message-ID: <200507072322.SAA31971@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.48 -> 1.49 gccld.cpp updated: 1.100 -> 1.101 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+8 -12) GenerateCode.cpp | 12 ++++-------- gccld.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 12 deletions(-) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.48 llvm/tools/gccld/GenerateCode.cpp:1.49 --- llvm/tools/gccld/GenerateCode.cpp:1.48 Thu Apr 21 18:59:28 2005 +++ llvm/tools/gccld/GenerateCode.cpp Thu Jul 7 18:21:43 2005 @@ -152,15 +152,11 @@ static bool isBytecodeLPath(const std::string &LibPath) { bool isBytecodeLPath = false; - // Make sure the -L path has a '/' character - // because llvm-g++ passes them without the ending - // '/' char and sys::Path doesn't think it is a - // directory (see: sys::Path::isDirectory) without it - std::string dir = LibPath; - if ( dir[dir.length()-1] != '/' ) - dir.append("/"); + sys::Path LPath(LibPath); - sys::Path LPath(dir); + // Make sure its a directory + if (!LPath.isDirectory()) + return isBytecodeLPath; // Grab the contents of the -L path std::set Files; Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.100 llvm/tools/gccld/gccld.cpp:1.101 --- llvm/tools/gccld/gccld.cpp:1.100 Thu Apr 21 18:59:28 2005 +++ llvm/tools/gccld/gccld.cpp Thu Jul 7 18:21:43 2005 @@ -313,9 +313,9 @@ if (!SaveTemps) { // Remove the assembly language file. - AssemblyFile.destroyFile(); + AssemblyFile.destroy(); // Remove the bytecode language file. - sys::Path(RealBytecodeOutput).destroyFile(); + sys::Path(RealBytecodeOutput).destroy(); } } else if (NativeCBE) { @@ -345,9 +345,9 @@ if (!SaveTemps) { // Remove the assembly language file. - CFile.destroyFile(); + CFile.destroy(); // Remove the bytecode language file. - sys::Path(RealBytecodeOutput).destroyFile(); + sys::Path(RealBytecodeOutput).destroy(); } } else if (!LinkAsLibrary) { From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Path.cpp Message-ID: <200507072322.SAA31974@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Path.cpp updated: 1.18 -> 1.19 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+3 -3) Path.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/System/Path.cpp diff -u llvm/lib/System/Path.cpp:1.18 llvm/lib/System/Path.cpp:1.19 --- llvm/lib/System/Path.cpp:1.18 Thu Jul 7 13:21:42 2005 +++ llvm/lib/System/Path.cpp Thu Jul 7 18:21:43 2005 @@ -27,7 +27,7 @@ Path::GetLLVMConfigDir() { Path result; #ifdef LLVM_ETCDIR - if (result.setDirectory(LLVM_ETCDIR)) + if (result.set(LLVM_ETCDIR)) return result; #endif return GetLLVMDefaultConfigDir(); @@ -80,10 +80,10 @@ GetSystemLibraryPaths(LibPaths); for (unsigned i = 0; i < LibPaths.size(); ++i) { sys::Path FullPath(LibPaths[i]); - FullPath.appendFile("lib" + name + LTDL_SHLIB_EXT); + FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT); if (FullPath.isDynamicLibrary()) return FullPath; - FullPath.elideSuffix(); + FullPath.eraseSuffix(); FullPath.appendSuffix("a"); if (FullPath.isArchive()) return FullPath; From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200507072322.SAA32000@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.27 -> 1.28 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+3 -3) llvm-ar.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.27 llvm/tools/llvm-ar/llvm-ar.cpp:1.28 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.27 Thu Apr 21 18:59:33 2005 +++ llvm/tools/llvm-ar/llvm-ar.cpp Thu Jul 7 18:21:43 2005 @@ -293,7 +293,7 @@ void buildPaths(bool checkExistence = true) { for (unsigned i = 0; i < Members.size(); i++) { sys::Path aPath; - if (!aPath.setFile(Members[i])) + if (!aPath.set(Members[i])) throw std::string("File member name invalid: ") + Members[i]; if (checkExistence) { if (!aPath.exists()) @@ -431,7 +431,7 @@ // Make sure the intervening directories are created if (I->hasPath()) { sys::Path dirs(I->getPath()); - dirs.elideFile(); + dirs.eraseComponent(); dirs.createDirectory(/*create_parents=*/true); } @@ -669,7 +669,7 @@ // Check the path name of the archive sys::Path ArchivePath; - if (!ArchivePath.setFile(ArchiveName)) + if (!ArchivePath.set(ArchiveName)) throw std::string("Archive name invalid: ") + ArchiveName; // Create or open the archive object. From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200507072322.SAA31982@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.23 -> 1.24 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+55 -97) Path.h | 152 +++++++++++++++++++++++------------------------------------------ 1 files changed, 55 insertions(+), 97 deletions(-) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.23 llvm/include/llvm/System/Path.h:1.24 --- llvm/include/llvm/System/Path.h:1.23 Thu Jul 7 13:21:42 2005 +++ llvm/include/llvm/System/Path.h Thu Jul 7 18:21:43 2005 @@ -219,24 +219,22 @@ bool isValid() const; /// This function determines if the contents of the path name are - /// empty. That is, the path has a zero length. + /// empty. That is, the path has a zero length. This does NOT determine if + /// if the file is empty. Use the getSize method for that. /// @returns true iff the path is empty. /// @brief Determines if the path name is empty (invalid). bool isEmpty() const { return path.empty(); } - /// This function determines if the path name in this object is intended - /// to reference a legal file name (as opposed to a directory name). This - /// function does not verify anything with the file system, it merely - /// determines if the syntax of the path represents a file name or not. + /// This function determines if the object referenced by this path is + /// a file or not. This function accesses the under lying file system to + /// determine the type of entity referenced by the path. /// @returns true if this path name references a file. /// @brief Determines if the path name references a file. bool isFile() const; - /// This function determines if the path name in this object is intended - /// to reference a legal directory name (as opposed to a file name). This - /// function does not verify anything with the file system, it merely - /// determines if the syntax of the path represents a directory name or - /// not. + /// This function determines if the object referenced by this path is a + /// directory or not. This function accesses the underlying file system to + /// determine the type of entity referenced by the path. /// @returns true if the path name references a directory /// @brief Determines if the path name references a directory. bool isDirectory() const; @@ -297,35 +295,34 @@ bool isDynamicLibrary() const; /// This function determines if the path name references an existing file - /// or directory in the file system. Unlike isFile and isDirectory, this - /// function actually checks for the existence of the file or directory. - /// @returns true if the pathname references an existing file. + /// or directory in the file system. + /// @returns true if the pathname references an existing file or + /// directory. /// @brief Determines if the path is a file or directory in /// the file system. bool exists() const; /// This function determines if the path name references a readable file - /// or directory in the file system. Unlike isFile and isDirectory, this - /// function actually checks for the existence and readability (by the - /// current program) of the file or directory. + /// or directory in the file system. This function checks for + /// the existence and readability (by the current program) of the file + /// or directory. /// @returns true if the pathname references a readable file. /// @brief Determines if the path is a readable file or directory /// in the file system. bool canRead() const; /// This function determines if the path name references a writable file - /// or directory in the file system. Unlike isFile and isDirectory, this - /// function actually checks for the existence and writability (by the - /// current program) of the file or directory. + /// or directory in the file system. This function checks for the + /// existence and writability (by the current program) of the file or + /// directory. /// @returns true if the pathname references a writable file. /// @brief Determines if the path is a writable file or directory /// in the file system. bool canWrite() const; /// This function determines if the path name references an executable - /// file in the file system. Unlike isFile and isDirectory, this - /// function actually checks for the existence and executability (by - /// the current program) of the file. + /// file in the file system. This function checks for the existence and + /// executability (by the current program) of the file. /// @returns true if the pathname references an executable file. /// @brief Determines if the path is an executable file in the file /// system. @@ -338,17 +335,16 @@ /// @brief Returns the path as a std::string. const std::string& toString() const { return path; } - /// This function returns the last component of the path name. If the - /// isDirectory() function would return true then this returns the name - /// of the last directory in the path. If the isFile() function would - /// return true then this function returns the name of the file without - /// any of the preceding directories. + /// This function returns the last component of the path name. The last + /// component is the file or directory name occuring after the last + /// directory separator. /// @returns std::string containing the last component of the path name. /// @brief Returns the last component of the path name. std::string getLast() const; - /// This function strips off the path and suffix of the file name and - /// returns just the basename. + /// This function strips off the path and suffix of the file or directory + /// name and returns just the basename. For example /a/foo.bar would cause + /// this function to return "foo". /// @returns std::string containing the basename of the path /// @throws nothing /// @brief Get the base name of the path @@ -361,26 +357,20 @@ /// @brief Build a list of directory's contents. bool getDirectoryContents(std::set& paths) const; - /// This method attempts to destroy the directory named by the last in - /// the Path name. If \p remove_contents is false, an attempt will be - /// made to remove just the directory that this Path object refers to - /// (the final Path component). If \p remove_contents is true, an attempt - /// will be made to remove the entire contents of the directory, - /// recursively. + /// This method attempts to destroy the file or directory named by the + /// last component of the Path. If the Path refers to a directory and the + /// \p destroy_contents is false, an attempt will be made to remove just + /// the directory (the final Path component). If \p destroy_contents is + /// true, an attempt will be made to remove the entire contents of the + /// directory, recursively. If the Path refers to a file, the + /// \p destroy_contents parameter is ignored. /// @param destroy_contents Indicates whether the contents of a destroyed /// directory should also be destroyed (recursively). - /// @returns false if the Path does not refer to a directory, true - /// otherwise. + /// @returns true if the file/directory was destroyed, false if the path + /// refers to something that is neither a file nor a directory. /// @throws std::string if there is an error. /// @brief Removes the file or directory from the filesystem. - bool destroyDirectory( bool destroy_contents = false ) const; - - /// This method attempts to destroy the file named by the last item in the - /// Path name. - /// @returns false if the Path does not refer to a file, true otherwise. - /// @throws std::string if there is an error. - /// @brief Destroy the file this Path refers to. - bool destroyFile() const; + bool destroy( bool destroy_contents = false ) const; /// Obtain a 'C' string for the path name. /// @returns a 'C' string containing the path name. @@ -437,64 +427,32 @@ /// @brief Make the file readable; void makeExecutable(); - /// This method attempts to set the Path object to \p unverified_path - /// and interpret the name as a directory name. The \p unverified_path - /// is verified. If verification succeeds then \p unverified_path - /// is accepted as a directory and true is returned. Otherwise, - /// the Path object remains unchanged and false is returned. - /// @returns true if the path was set, false otherwise. - /// @param unverified_path The path to be set in Path object. - /// @throws nothing - /// @brief Set a full path from a std::string - bool setDirectory(const std::string& unverified_path); - - /// This method attempts to set the Path object to \p unverified_path - /// and interpret the name as a file name. The \p unverified_path - /// is verified. If verification succeeds then \p unverified_path - /// is accepted as a file name and true is returned. Otherwise, - /// the Path object remains unchanged and false is returned. + /// This method sets the Path object to \p unverified_path. This can fail + /// if the \p unverified_path does not pass the syntactic checks of the + /// isValid method. If verification fails, the Path object remains + /// unchanged and false is returned. Otherwise true is returned and the + /// Path object takes on the path value of \p unverified_path /// @returns true if the path was set, false otherwise. /// @param unverified_path The path to be set in Path object. /// @throws nothing /// @brief Set a full path from a std::string - bool setFile(const std::string& unverified_path); + bool set(const std::string& unverified_path); - /// The \p dirname is added to the end of the Path if it is a legal - /// directory name for the operating system. The precondition for this - /// function is that the Path must reference a directory name (i.e. - /// isDirectory() returns true). - /// @param dirname A string providing the directory name to - /// be added to the end of the path. - /// @returns false if the directory name could not be added + /// One path component is removed from the Path. If only one component is + /// present in the path, the Path object becomes empty. If the Path object + /// is empty, no change is made. /// @throws nothing - /// @brief Adds the name of a directory to a Path. - bool appendDirectory( const std::string& dirname ); - - /// One directory component is removed from the Path name. The Path must - /// refer to a non-root directory name (i.e. isDirectory() returns true - /// but isRootDirectory() returns false). Upon exit, the Path will - /// refer to the directory above it. - /// @throws nothing - /// @returns false if the directory name could not be removed. + /// @returns false if the path component could not be removed. /// @brief Removes the last directory component of the Path. - bool elideDirectory(); + bool eraseComponent(); - /// The \p filename is added to the end of the Path if it is a legal - /// directory name for the operating system. The precondition for this - /// function is that the Path reference a directory name (i.e. - /// isDirectory() returns true). - /// @throws nothing - /// @returns false if the file name could not be added. - /// @brief Appends the name of a file. - bool appendFile( const std::string& filename ); - - /// One file component is removed from the Path name. The Path must - /// refer to a file (i.e. isFile() returns true). Upon exit, - /// the Path will refer to the directory above it. + /// The \p component is added to the end of the Path if it is a legal + /// name for the operating system. A directory separator will be added if + /// needed. /// @throws nothing - /// @returns false if the file name could not be removed - /// @brief Removes the last file component of the path. - bool elideFile(); + /// @returns false if the path component could not be added. + /// @brief Appends one path component to the Path. + bool appendComponent( const std::string& component ); /// A period and the \p suffix are appended to the end of the pathname. /// The precondition for this function is that the Path reference a file @@ -506,7 +464,7 @@ /// @brief Adds a period and the \p suffix to the end of the pathname. bool appendSuffix(const std::string& suffix); - /// The suffix of the filename is removed. The suffix begins with and + /// The suffix of the filename is erased. The suffix begins with and /// includes the last . character in the filename after the last directory /// separator and extends until the end of the name. If no . character is /// after the last directory separator, then the file name is left @@ -515,7 +473,7 @@ /// @returns false if there was no suffix to remove, true otherwise. /// @throws nothing /// @brief Remove the suffix from a path name. - bool elideSuffix(); + bool eraseSuffix(); /// The current Path name is made unique in the file system. Upon return, /// the Path will have been changed to make a unique file in the file @@ -566,7 +524,7 @@ /// @returns false if the Path does not refer to a file, true otherwise. /// @throws std::string if there is an file system error. /// @brief Rename one file as another. - bool renameFile(const Path& newName); + bool rename(const Path& newName); /// This method sets the access time, modification time, and permission /// mode of the file associated with \p this as given by \p si. From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507072322.SAA32006@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.32 -> 1.33 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+8 -2) Path.inc | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.32 llvm/lib/System/Win32/Path.inc:1.33 --- llvm/lib/System/Win32/Path.inc:1.32 Thu Jul 7 13:21:42 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 18:21:43 2005 @@ -195,12 +195,18 @@ bool Path::isFile() const { - return (isValid() && path[path.length()-1] != '/'); + WIN32_FILE_ATTRIBUTE_DATA fi; + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + ThrowError(std::string(path) + ": Can't get status: "); + return fi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL; } bool Path::isDirectory() const { - return (isValid() && path[path.length()-1] == '/'); + WIN32_FILE_ATTRIBUTE_DATA fi; + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + ThrowError(std::string(path) + ": Can't get status: "); + return fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; } std::string From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/FileUtilities.h Message-ID: <200507072322.SAA31980@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: FileUtilities.h updated: 1.31 -> 1.32 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+1 -1) FileUtilities.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Support/FileUtilities.h diff -u llvm/include/llvm/Support/FileUtilities.h:1.31 llvm/include/llvm/Support/FileUtilities.h:1.32 --- llvm/include/llvm/Support/FileUtilities.h:1.31 Thu Apr 21 15:44:59 2005 +++ llvm/include/llvm/Support/FileUtilities.h Thu Jul 7 18:21:42 2005 @@ -45,7 +45,7 @@ ~FileRemover() { if (DeleteIt) try { - Filename.destroyFile(); + Filename.destroy(); } catch (...) {} // Ignore problems deleting the file. } From reid at x10sys.com Thu Jul 7 18:22:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:22:01 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvmc/CompilerDriver.cpp Configuration.cpp Message-ID: <200507072322.SAA32012@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvmc: CompilerDriver.cpp updated: 1.32 -> 1.33 Configuration.cpp updated: 1.22 -> 1.23 --- Log message: For PR495: http://llvm.cs.uiuc.edu/PR495 : Get rid of the difference between file paths and directory paths. The Path class now simply stores a path that can refer to either a file or a directory. This required various changes in the implementation and interface of the class with the corresponding impact to its users. Doxygen comments were also updated to reflect these changes. Interface changes are: appendDirectory -> appendComponent appendFile -> appendComponent elideDirectory -> eraseComponent elideFile -> eraseComponent elideSuffix -> eraseSuffix renameFile -> rename setDirectory -> set setFile -> set Changes pass Dejagnu and llvm-test/SingleSource tests. --- Diffs of the changes: (+24 -24) CompilerDriver.cpp | 30 +++++++++++++++--------------- Configuration.cpp | 18 +++++++++--------- 2 files changed, 24 insertions(+), 24 deletions(-) Index: llvm/tools/llvmc/CompilerDriver.cpp diff -u llvm/tools/llvmc/CompilerDriver.cpp:1.32 llvm/tools/llvmc/CompilerDriver.cpp:1.33 --- llvm/tools/llvmc/CompilerDriver.cpp:1.32 Thu Jul 7 13:21:42 2005 +++ llvm/tools/llvmc/CompilerDriver.cpp Thu Jul 7 18:21:43 2005 @@ -134,7 +134,7 @@ StringVector::const_iterator E = paths.end(); while (I != E) { sys::Path tmp; - tmp.setDirectory(*I); + tmp.set(*I); IncludePaths.push_back(tmp); ++I; } @@ -149,7 +149,7 @@ StringVector::const_iterator E = paths.end(); while (I != E) { sys::Path tmp; - tmp.setDirectory(*I); + tmp.set(*I); LibraryPaths.push_back(tmp); ++I; } @@ -188,7 +188,7 @@ void cleanup() { if (!isSet(KEEP_TEMPS_FLAG)) { if (TempDir.isDirectory() && TempDir.canWrite()) - TempDir.destroyDirectory(/*remove_contents=*/true); + TempDir.destroy(/*remove_contents=*/true); } else { std::cout << "Temporary files are in " << TempDir << "\n"; } @@ -197,7 +197,7 @@ sys::Path MakeTempFile(const std::string& basename, const std::string& suffix) { sys::Path result(TempDir); - if (!result.appendFile(basename)) + if (!result.appendComponent(basename)) throw basename + ": can't use this file name"; if (!result.appendSuffix(suffix)) throw suffix + ": can't use this file suffix"; @@ -448,13 +448,13 @@ llvm::sys::Path GetPathForLinkageItem(const std::string& link_item, bool native = false) { sys::Path fullpath; - fullpath.setFile(link_item); + fullpath.set(link_item); if (fullpath.canRead()) return fullpath; for (PathVector::iterator PI = LibraryPaths.begin(), PE = LibraryPaths.end(); PI != PE; ++PI) { - fullpath.setDirectory(PI->toString()); - fullpath.appendFile(link_item); + fullpath.set(PI->toString()); + fullpath.appendComponent(link_item); if (fullpath.canRead()) return fullpath; if (native) { @@ -463,16 +463,16 @@ fullpath.appendSuffix("bc"); if (fullpath.canRead()) return fullpath; - fullpath.elideSuffix(); + fullpath.eraseSuffix(); fullpath.appendSuffix("o"); if (fullpath.canRead()) return fullpath; fullpath = *PI; - fullpath.appendFile(std::string("lib") + link_item); + fullpath.appendComponent(std::string("lib") + link_item); fullpath.appendSuffix("a"); if (fullpath.canRead()) return fullpath; - fullpath.elideSuffix(); + fullpath.eraseSuffix(); fullpath.appendSuffix("so"); if (fullpath.canRead()) return fullpath; @@ -693,7 +693,7 @@ /// The output of the translator is an LLVM Assembly program /// We need to translate it to bytecode Action* action = new Action(); - action->program.setFile("llvm-as"); + action->program.set("llvm-as"); action->args.push_back(InFile.toString()); action->args.push_back("-o"); InFile.appendSuffix("bc"); @@ -735,7 +735,7 @@ /// The output of the optimizer is an LLVM Assembly program /// We need to translate it to bytecode with llvm-as Action* action = new Action(); - action->program.setFile("llvm-as"); + action->program.set("llvm-as"); action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); @@ -764,7 +764,7 @@ Action* action = new Action(); if (isSet(EMIT_NATIVE_FLAG)) { // Use llc to get the native assembly file - action->program.setFile("llc"); + action->program.set("llc"); action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); @@ -777,7 +777,7 @@ actions.push_back(action); } else { // Just convert back to llvm assembly with llvm-dis - action->program.setFile("llvm-dis"); + action->program.set("llvm-dis"); action->args.push_back(InFile.toString()); action->args.push_back("-f"); action->args.push_back("-o"); @@ -820,7 +820,7 @@ // Set up the linking action with llvm-ld Action* link = new Action(); - link->program.setFile("llvm-ld"); + link->program.set("llvm-ld"); // Add in the optimization level requested switch (optLevel) { Index: llvm/tools/llvmc/Configuration.cpp diff -u llvm/tools/llvmc/Configuration.cpp:1.22 llvm/tools/llvmc/Configuration.cpp:1.23 --- llvm/tools/llvmc/Configuration.cpp:1.22 Thu Jul 7 13:21:42 2005 +++ llvm/tools/llvmc/Configuration.cpp Thu Jul 7 18:21:43 2005 @@ -318,7 +318,7 @@ { std::string progname; if (parseProgramName(progname)) - action.program.setFile(progname); + action.program.set(progname); else error("Expecting a program name"); @@ -547,8 +547,8 @@ // Try the environment variable const char* conf = getenv("LLVM_CONFIG_DIR"); if (conf) { - confFile.setDirectory(conf); - confFile.appendFile(ftype); + confFile.set(conf); + confFile.appendComponent(ftype); if (!confFile.canRead()) throw std::string("Configuration file for '") + ftype + "' is not available."; @@ -556,20 +556,20 @@ // Try the user's home directory confFile = sys::Path::GetUserHomeDirectory(); if (!confFile.isEmpty()) { - confFile.appendDirectory(".llvm"); - confFile.appendDirectory("etc"); - confFile.appendFile(ftype); + confFile.appendComponent(".llvm"); + confFile.appendComponent("etc"); + confFile.appendComponent(ftype); if (!confFile.canRead()) confFile.clear(); } if (confFile.isEmpty()) { // Okay, try the LLVM installation directory confFile = sys::Path::GetLLVMConfigDir(); - confFile.appendFile(ftype); + confFile.appendComponent(ftype); if (!confFile.canRead()) { // Okay, try the "standard" place confFile = sys::Path::GetLLVMDefaultConfigDir(); - confFile.appendFile(ftype); + confFile.appendComponent(ftype); if (!confFile.canRead()) { throw std::string("Configuration file for '") + ftype + "' is not available."; @@ -579,7 +579,7 @@ } } else { confFile = configDir; - confFile.appendFile(ftype); + confFile.appendComponent(ftype); if (!confFile.canRead()) throw std::string("Configuration file for '") + ftype + "' is not available."; From reid at x10sys.com Thu Jul 7 18:35:34 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 18:35:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507072335.SAA05573@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.33 -> 1.34 --- Log message: Changes to mimic those in Unix/Path.inc in support of PR495: http://llvm.cs.uiuc.edu/PR495 . This hasn't been compiled or tested. --- Diffs of the changes: (+94 -155) Path.inc | 249 +++++++++++++++++++++++---------------------------------------- 1 files changed, 94 insertions(+), 155 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.33 llvm/lib/System/Win32/Path.inc:1.34 --- llvm/lib/System/Win32/Path.inc:1.33 Thu Jul 7 18:21:43 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 18:35:23 2005 @@ -94,7 +94,7 @@ throw std::string("Can't determine temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); // Append a subdirectory passed on our process id so multiple LLVMs don't // step on each other's toes. @@ -128,7 +128,7 @@ Path Path::GetRootDirectory() { Path result; - result.setDirectory("/"); + result.set("C:\\"); return result; } @@ -138,14 +138,14 @@ Path tmpPath; while( delim != 0 ) { std::string tmp(at, size_t(delim-at)); - if (tmpPath.setDirectory(tmp)) + if (tmpPath.set(tmp)) if (tmpPath.canRead()) Paths.push_back(tmpPath); at = delim + 1; delim = strchr(at, ';'); } if (*at != 0) - if (tmpPath.setDirectory(std::string(at))) + if (tmpPath.set(std::string(at))) if (tmpPath.canRead()) Paths.push_back(tmpPath); @@ -166,7 +166,7 @@ #ifdef LLVM_LIBDIR { Path tmpPath; - if (tmpPath.setDirectory(LLVM_LIBDIR)) + if (tmpPath.set(LLVM_LIBDIR)) if (tmpPath.canRead()) Paths.push_back(tmpPath); } @@ -186,7 +186,7 @@ const char* home = getenv("HOME"); if (home) { Path result; - if (result.setDirectory(home)) + if (result.set(home)) return result; } return GetRootDirectory(); @@ -380,58 +380,40 @@ } bool -Path::setDirectory(const std::string& a_path) { +Path::set(const std::string& a_path) { if (a_path.size() == 0) return false; - Path save(*this); + std::string save(path); path = a_path; FlipBackSlashes(path); size_t last = a_path.size() -1; - if (a_path[last] != '/') - path += '/'; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::setFile(const std::string& a_path) { - if (a_path.size() == 0) - return false; - Path save(*this); - path = a_path; - FlipBackSlashes(path); - size_t last = a_path.size() - 1; - while (last > 0 && a_path[last] == '/') - last--; - path.erase(last+1); - if (!isValid()) { - path = save.path; +Path::appendComponent(const std::string& dir) { + if (name.empty()) return false; + std::string save(path); + if (!path.empty()) { + size_t last = path.size() - 1; + if (path[last] != '/') + path += '/'; } - return true; -} - -bool -Path::appendDirectory(const std::string& dir) { - if (isFile()) - return false; - Path save(*this); - path += dir; - path += "/"; + path += name; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::elideDirectory() { - if (isFile()) - return false; +Path::eraseComponent() { size_t slashpos = path.rfind('/',path.size()); if (slashpos == 0 || slashpos == std::string::npos) return false; @@ -444,46 +426,19 @@ } bool -Path::appendFile(const std::string& file) { - if (!isDirectory()) - return false; - Path save(*this); - path += file; - if (!isValid()) { - path = save.path; - return false; - } - return true; -} - -bool -Path::elideFile() { - if (isDirectory()) - return false; - size_t slashpos = path.rfind('/',path.size()); - if (slashpos == std::string::npos) - return false; - path.erase(slashpos+1); - return true; -} - -bool Path::appendSuffix(const std::string& suffix) { - if (isDirectory()) - return false; - Path save(*this); + std::string save(path); path.append("."); path.append(suffix); if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::elideSuffix() { - if (isDirectory()) return false; +Path::eraseSuffix() { size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); if (slashpos != std::string::npos && dotpos != std::string::npos && @@ -494,12 +449,8 @@ return false; } - bool Path::createDirectory( bool create_parents) { - // Make sure we're dealing with a directory - if (!isDirectory()) return false; - // Get a writeable copy of the path name char *pathname = reinterpret_cast(_alloca(path.length()+1)); path.copy(pathname,path.length()); @@ -548,9 +499,6 @@ bool Path::createFile() { - // Make sure we're dealing with a file - if (!isFile()) return false; - // Create the file HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); @@ -562,89 +510,83 @@ } bool -Path::destroyDirectory(bool remove_contents) const { - // Make sure we're dealing with a directory - if (!isDirectory()) return false; - - // If it doesn't exist, we're done. - if (!exists()) return true; +Path::destroy(bool remove_contents) const { + if (isFile()) { + DWORD attr = GetFileAttributes(path.c_str()); + + // If it doesn't exist, we're done. + if (attr == INVALID_FILE_ATTRIBUTES) + return true; + + // Read-only files cannot be deleted on Windows. Must remove the read-only + // attribute first. + if (attr & FILE_ATTRIBUTE_READONLY) { + if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) + ThrowError(path + ": Can't destroy file: "); + } - char *pathname = reinterpret_cast(_alloca(path.length()+2)); - int lastchar = path.length() - 1 ; - path.copy(pathname,lastchar+2); - - // Make path end with '/*'. - pathname[lastchar+1] = '*'; - pathname[lastchar+2] = 0; - - if (remove_contents) { - WIN32_FIND_DATA fd; - HANDLE h = FindFirstFile(pathname, &fd); - - // It's a bad idea to alter the contents of a directory while enumerating - // its contents. So build a list of its contents first, then destroy them. - - if (h != INVALID_HANDLE_VALUE) { - std::vector list; - - do { - if (strcmp(fd.cFileName, ".") == 0) - continue; - if (strcmp(fd.cFileName, "..") == 0) - continue; - - Path aPath(path + &fd.cFileName[0]); - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - aPath.path += "/"; - list.push_back(aPath); - } while (FindNextFile(h, &fd)); - - DWORD err = GetLastError(); - FindClose(h); - if (err != ERROR_NO_MORE_FILES) { - SetLastError(err); - ThrowError(path + ": Can't read directory: "); - } + if (!DeleteFile(path.c_str())) + ThrowError(path + ": Can't destroy file: "); + return true; + } else if (isDirectory()) { - for (std::vector::iterator I = list.begin(); I != list.end(); ++I) { - Path &aPath = *I; - if (aPath.isDirectory()) - aPath.destroyDirectory(true); - else - aPath.destroyFile(); + // If it doesn't exist, we're done. + if (!exists()) + return true; + + char *pathname = reinterpret_cast(_alloca(path.length()+2)); + int lastchar = path.length() - 1 ; + path.copy(pathname,lastchar+2); + + // Make path end with '/*'. + pathname[lastchar+1] = '*'; + pathname[lastchar+2] = 0; + + if (remove_contents) { + WIN32_FIND_DATA fd; + HANDLE h = FindFirstFile(pathname, &fd); + + // It's a bad idea to alter the contents of a directory while enumerating + // its contents. So build a list of its contents first, then destroy them. + + if (h != INVALID_HANDLE_VALUE) { + std::vector list; + + do { + if (strcmp(fd.cFileName, ".") == 0) + continue; + if (strcmp(fd.cFileName, "..") == 0) + continue; + + Path aPath(path + &fd.cFileName[0]); + if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + aPath.path += "/"; + list.push_back(aPath); + } while (FindNextFile(h, &fd)); + + DWORD err = GetLastError(); + FindClose(h); + if (err != ERROR_NO_MORE_FILES) { + SetLastError(err); + ThrowError(path + ": Can't read directory: "); + } + + for (std::vector::iterator I = list.begin(); I != list.end(); + ++I) { + Path &aPath = *I; + aPath.destroy(true); + } + } else { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + ThrowError(path + ": Can't read directory: "); } - } else { - if (GetLastError() != ERROR_FILE_NOT_FOUND) - ThrowError(path + ": Can't read directory: "); } - } - pathname[lastchar] = 0; - if (!RemoveDirectory(pathname)) - ThrowError(std::string(pathname) + ": Can't destroy directory: "); - return true; -} - -bool -Path::destroyFile() const { - if (!isFile()) return false; - - DWORD attr = GetFileAttributes(path.c_str()); - - // If it doesn't exist, we're done. - if (attr == INVALID_FILE_ATTRIBUTES) + pathname[lastchar] = 0; + if (!RemoveDirectory(pathname)) + ThrowError(std::string(pathname) + ": Can't destroy directory: "); return true; - - // Read-only files cannot be deleted on Windows. Must remove the read-only - // attribute first. - if (attr & FILE_ATTRIBUTE_READONLY) { - if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) - ThrowError(path + ": Can't destroy file: "); } - - if (!DeleteFile(path.c_str())) - ThrowError(path + ": Can't destroy file: "); - return true; } bool Path::getMagicNumber(std::string& Magic, unsigned len) const { @@ -676,7 +618,8 @@ } bool -Path::renameFile(const Path& newName) { +Path::rename(const Path& newName) { + // FIXME: This should rename a directory too. if (!isFile()) return false; if (!MoveFile(path.c_str(), newName.c_str())) ThrowError("Can't move '" + path + @@ -766,10 +709,6 @@ bool Path::createTemporaryFile(bool reuse_current) { - // Make sure we're dealing with a file - if (!isFile()) - return false; - // Make this into a unique file name makeUnique( reuse_current ); From natebegeman at mac.com Thu Jul 7 19:23:37 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 7 Jul 2005 19:23:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <200507080023.TAA05812@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.43 -> 1.44 --- Log message: Add support for assembling .s files on mac os x for intel Add support for running bugpoint on mac os x for intel --- Diffs of the changes: (+1 -1) ToolRunner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.43 llvm/lib/Support/ToolRunner.cpp:1.44 --- llvm/lib/Support/ToolRunner.cpp:1.43 Thu Jul 7 18:21:43 2005 +++ llvm/lib/Support/ToolRunner.cpp Thu Jul 7 19:23:26 2005 @@ -441,7 +441,7 @@ InputFile.c_str(), // Specify the input filename... #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) "-G", // Compile a shared library, `-G' for Sparc -#elif (defined(__POWERPC__) || defined(__ppc__)) && defined(__APPLE__) +#elif defined(__APPLE__) "-single_module", // link all source files into a single module "-dynamiclib", // `-dynamiclib' for MacOS X/PowerPC "-undefined", // in data segment, rather than generating From natebegeman at mac.com Thu Jul 7 19:23:38 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 7 Jul 2005 19:23:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200507080023.TAA05816@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.77 -> 1.78 --- Log message: Add support for assembling .s files on mac os x for intel Add support for running bugpoint on mac os x for intel --- Diffs of the changes: (+0 -1) PowerPCAsmPrinter.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.77 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.78 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.77 Thu Apr 21 18:20:02 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Thu Jul 7 19:23:26 2005 @@ -44,7 +44,6 @@ struct PowerPCAsmPrinter : public AsmPrinter { std::set FnStubs, GVStubs, LinkOnceStubs; - std::set Strings; PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM), LabelNumber(0) {} From natebegeman at mac.com Thu Jul 7 19:23:38 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 7 Jul 2005 19:23:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86AsmPrinter.h Message-ID: <200507080023.TAA05824@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.1 -> 1.2 X86AsmPrinter.cpp updated: 1.140 -> 1.141 X86AsmPrinter.h updated: 1.1 -> 1.2 --- Log message: Add support for assembling .s files on mac os x for intel Add support for running bugpoint on mac os x for intel --- Diffs of the changes: (+502 -413) X86ATTAsmPrinter.cpp | 379 ++++++++++++++++++++++++++----------------------- X86AsmPrinter.cpp | 393 ++++++++++++++++++++++++++++----------------------- X86AsmPrinter.h | 143 +++++++++--------- 3 files changed, 502 insertions(+), 413 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.1 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.2 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.1 Fri Jul 1 17:44:09 2005 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Thu Jul 7 19:23:26 2005 @@ -1,171 +1,208 @@ -//===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly ----===// -// -// 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 a printer that converts from our internal representation -// of machine-dependent LLVM code to AT&T format assembly -// language. This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#include "X86ATTAsmPrinter.h" -#include "X86.h" -#include "X86TargetMachine.h" -#include "llvm/Module.h" -#include "llvm/Support/Mangler.h" -using namespace llvm; -using namespace x86; - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - setupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - printConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - O << "\t.text\n"; - emitAlignment(4); - O << "\t.globl\t" << CurrentFnName << "\n"; - if (!forCygwin && !forDarwin) - O << "\t.type\t" << CurrentFnName << ", @function\n"; - O << CurrentFnName << ":\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (I->pred_begin() != I->pred_end()) - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(II); - } - } - - // We didn't modify anything. - return false; -} - -void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { - const MRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - case MachineOperand::MO_MachineRegister: - assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Virtual registers should not make it this far!"); - O << '%'; - for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) - O << (char)tolower(*Name); - return; - - case MachineOperand::MO_SignExtendedImmed: - case MachineOperand::MO_UnextendedImmed: - O << '$' << (int)MO.getImmedValue(); - return; - case MachineOperand::MO_MachineBasicBlock: { - MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) - << "_" << MBBOp->getNumber () << "\t# " - << MBBOp->getBasicBlock ()->getName (); - return; - } - case MachineOperand::MO_PCRelativeDisp: - std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; - abort (); - return; - case MachineOperand::MO_GlobalAddress: { - if (!isCallOp) O << '$'; - O << Mang->getValueName(MO.getGlobal()); - int Offset = MO.getOffset(); - if (Offset > 0) - O << "+" << Offset; - else if (Offset < 0) - O << Offset; - return; - } - case MachineOperand::MO_ExternalSymbol: - if (!isCallOp) O << '$'; - O << GlobalPrefix << MO.getSymbolName(); - return; - default: - O << ""; return; - } -} - -void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ - assert(isMem(MI, Op) && "Invalid memory reference!"); - - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImmedValue(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - if (BaseReg.isFrameIndex()) { - O << "[frame slot #" << BaseReg.getFrameIndex(); - if (DispSpec.getImmedValue()) - O << " + " << DispSpec.getImmedValue(); - O << "]"; - return; - } else if (BaseReg.isConstantPoolIndex()) { - O << ".CPI" << CurrentFnName << "_" - << BaseReg.getConstantPoolIndex(); - if (DispSpec.getImmedValue()) - O << "+" << DispSpec.getImmedValue(); - if (IndexReg.getReg()) { - O << "(,"; - printOp(IndexReg); - if (ScaleVal != 1) - O << "," << ScaleVal; - O << ")"; - } - return; - } - - if (DispSpec.isGlobalAddress()) { - printOp(DispSpec, true); - } else { - int DispVal = DispSpec.getImmedValue(); - if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) - O << DispVal; - } - - if (IndexReg.getReg() || BaseReg.getReg()) { - O << "("; - if (BaseReg.getReg()) - printOp(BaseReg); - - if (IndexReg.getReg()) { - O << ","; - printOp(IndexReg); - if (ScaleVal != 1) - O << "," << ScaleVal; - } - - O << ")"; - } -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter.inc" - +//===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly ----===// +// +// 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 a printer that converts from our internal representation +// of machine-dependent LLVM code to AT&T format assembly +// language. This printer is the output mechanism used by `llc'. +// +//===----------------------------------------------------------------------===// + +#include "X86ATTAsmPrinter.h" +#include "X86.h" +#include "X86TargetMachine.h" +#include "llvm/Module.h" +#include "llvm/Support/Mangler.h" +using namespace llvm; +using namespace x86; + +/// runOnMachineFunction - This uses the printMachineInstruction() +/// method to print assembly for each instruction. +/// +bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + setupMachineFunction(MF); + O << "\n\n"; + + // Print out constants referenced by the function + printConstantPool(MF.getConstantPool()); + + // Print out labels for the function. + O << "\t.text\n"; + emitAlignment(4); + O << "\t.globl\t" << CurrentFnName << "\n"; + if (!forCygwin && !forDarwin) + O << "\t.type\t" << CurrentFnName << ", @function\n"; + O << CurrentFnName << ":\n"; + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + if (I->pred_begin() != I->pred_end()) + O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" + << CommentString << " " << I->getBasicBlock()->getName() << "\n"; + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printMachineInstruction(II); + } + } + + // We didn't modify anything. + return false; +} + +void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { + const MRegisterInfo &RI = *TM.getRegisterInfo(); + switch (MO.getType()) { + case MachineOperand::MO_VirtualRegister: + case MachineOperand::MO_MachineRegister: + assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && + "Virtual registers should not make it this far!"); + O << '%'; + for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) + O << (char)tolower(*Name); + return; + + case MachineOperand::MO_SignExtendedImmed: + case MachineOperand::MO_UnextendedImmed: + O << '$' << (int)MO.getImmedValue(); + return; + case MachineOperand::MO_MachineBasicBlock: { + MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); + O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) + << "_" << MBBOp->getNumber () << "\t# " + << MBBOp->getBasicBlock ()->getName (); + return; + } + case MachineOperand::MO_PCRelativeDisp: + std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; + abort (); + return; + case MachineOperand::MO_GlobalAddress: { + // Darwin block shameless ripped from PowerPCAsmPrinter.cpp + if (forDarwin) { + if (!isCallOp) O << '$'; + GlobalValue *GV = MO.getGlobal(); + std::string Name = Mang->getValueName(GV); + + // Dynamically-resolved functions need a stub for the function. Be + // wary however not to output $stub for external functions whose addresses + // are taken. Those should be emitted as $non_lazy_ptr below. + Function *F = dyn_cast(GV); + if (F && isCallOp && F->isExternal()) { + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + return; + } + + // Link-once, External, or Weakly-linked global variables need + // non-lazily-resolved stubs + if (GV->hasLinkOnceLinkage()) { + LinkOnceStubs.insert(Name); + O << "L" << Name << "$non_lazy_ptr"; + return; + } + if (GV->isExternal() || GV->hasWeakLinkage()) { + GVStubs.insert(Name); + O << "L" << Name << "$non_lazy_ptr"; + return; + } + O << Mang->getValueName(GV); + return; + } + if (!isCallOp) O << '$'; + O << Mang->getValueName(MO.getGlobal()); + int Offset = MO.getOffset(); + if (Offset > 0) + O << "+" << Offset; + else if (Offset < 0) + O << Offset; + return; + } + case MachineOperand::MO_ExternalSymbol: + if (isCallOp && forDarwin) { + std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + return; + } + if (!isCallOp) O << '$'; + O << GlobalPrefix << MO.getSymbolName(); + return; + default: + O << ""; return; + } +} + +void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ + assert(isMem(MI, Op) && "Invalid memory reference!"); + + const MachineOperand &BaseReg = MI->getOperand(Op); + int ScaleVal = MI->getOperand(Op+1).getImmedValue(); + const MachineOperand &IndexReg = MI->getOperand(Op+2); + const MachineOperand &DispSpec = MI->getOperand(Op+3); + + if (BaseReg.isFrameIndex()) { + O << "[frame slot #" << BaseReg.getFrameIndex(); + if (DispSpec.getImmedValue()) + O << " + " << DispSpec.getImmedValue(); + O << "]"; + return; + } else if (BaseReg.isConstantPoolIndex()) { + O << ".CPI" << CurrentFnName << "_" + << BaseReg.getConstantPoolIndex(); + if (DispSpec.getImmedValue()) + O << "+" << DispSpec.getImmedValue(); + if (IndexReg.getReg()) { + O << "(,"; + printOp(IndexReg); + if (ScaleVal != 1) + O << "," << ScaleVal; + O << ")"; + } + return; + } + + if (DispSpec.isGlobalAddress()) { + printOp(DispSpec, true); + } else { + int DispVal = DispSpec.getImmedValue(); + if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) + O << DispVal; + } + + if (IndexReg.getReg() || BaseReg.getReg()) { + O << "("; + if (BaseReg.getReg()) + printOp(BaseReg); + + if (IndexReg.getReg()) { + O << ","; + printOp(IndexReg); + if (ScaleVal != 1) + O << "," << ScaleVal; + } + + O << ")"; + } +} + +/// printMachineInstruction -- Print out a single X86 LLVM instruction +/// MI in Intel syntax to the current output stream. +/// +void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { + ++EmittedInsts; + // Call the autogenerated instruction printer routines. + printInstruction(MI); +} + +// Include the auto-generated portion of the assembly writer. +#include "X86GenAsmWriter.inc" + Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.140 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.141 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.140 Fri Jul 1 18:56:38 2005 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Thu Jul 7 19:23:26 2005 @@ -1,173 +1,220 @@ -//===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===// -// -// 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 the shared super class printer that converts from our internal -// representation of machine-dependent LLVM code to Intel and AT&T format -// assembly language. -// This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#include "X86ATTAsmPrinter.h" -#include "X86IntelAsmPrinter.h" -#include "X86.h" -#include "llvm/Module.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/CommandLine.h" -using namespace llvm; -using namespace x86; - -Statistic<> llvm::x86::EmittedInsts("asm-printer", - "Number of machine instrs printed"); - -enum AsmWriterFlavorTy { att, intel }; -cl::opt -AsmWriterFlavor("x86-asm-syntax", - cl::desc("Choose style of code to emit from X86 backend:"), - cl::values( - clEnumVal(att, " Emit AT&T-style assembly"), - clEnumVal(intel, " Emit Intel-style assembly"), - clEnumValEnd), - cl::init(att)); - -/// doInitialization -bool X86SharedAsmPrinter::doInitialization(Module& M) { - bool leadingUnderscore = false; - forCygwin = false; - const std::string& TT = M.getTargetTriple(); - if (TT.length() > 5) { - forCygwin = TT.find("cygwin") != std::string::npos || - TT.find("mingw") != std::string::npos; - forDarwin = TT.find("darwin") != std::string::npos; - } else if (TT.empty()) { - #if defined(__CYGWIN__) || defined(__MINGW32__) - forCygwin = true; - #elif defined(__MACOSX__) - forDarwin = true; - #elif defined(_WIN32) - leadingUnderscore = true; - #else - leadingUnderscore = false; - #endif - } - if (leadingUnderscore || forCygwin || forDarwin) - GlobalPrefix = "_"; - - if (forDarwin) - AlignmentIsInBytes = false; - - return AsmPrinter::doInitialization(M); -} - -/// printConstantPool - Print to the current output stream assembly -/// representations of the constants in the constant pool MCP. This is -/// used to print out constants which have been "spilled to memory" by -/// the code generator. -/// -void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) { - const std::vector &CP = MCP->getConstants(); - const TargetData &TD = TM.getTargetData(); - - if (CP.empty()) return; - - for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.section .rodata\n"; - emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString - << *CP[i] << "\n"; - emitGlobalConstant(CP[i]); - } -} - -bool X86SharedAsmPrinter::doFinalization(Module &M) { - const TargetData &TD = TM.getTargetData(); - std::string CurSection; - - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) - if (I->hasInitializer()) { // External global require no code - O << "\n\n"; - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignmentShift(C->getType()); - - if (C->isNullValue() && - (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || - I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(O, CurSection, ".data"); - if (!forCygwin && I->hasInternalLinkage()) - O << "\t.local " << name << "\n"; - O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()); - if (!forCygwin) - O << "," << (1 << Align); - O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << "\n"; - } else { - switch (I->getLinkage()) { - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - SwitchSection(O, CurSection, ""); - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.globl " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - if (C->isNullValue()) - SwitchSection(O, CurSection, ".bss"); - else - SwitchSection(O, CurSection, ".data"); - break; - case GlobalValue::GhostLinkage: - std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; - abort(); - } - - emitAlignment(Align); - if (!forCygwin && !forDarwin) { - O << "\t.type " << name << ", at object\n"; - O << "\t.size " << name << "," << Size << "\n"; - } - O << name << ":\t\t\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; - emitGlobalConstant(C); - } - } - - AsmPrinter::doFinalization(M); - return false; // success -} - -/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code -/// for a MachineFunction to the given output stream, using the given target -/// machine description. -/// -FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ - switch (AsmWriterFlavor) { - default: - assert(0 && "Unknown asm flavor!"); - case intel: - return new X86IntelAsmPrinter(o, tm); - case att: - return new X86ATTAsmPrinter(o, tm); - } -} +//===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===// +// +// 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 the shared super class printer that converts from our internal +// representation of machine-dependent LLVM code to Intel and AT&T format +// assembly language. +// This printer is the output mechanism used by `llc'. +// +//===----------------------------------------------------------------------===// + +#include "X86ATTAsmPrinter.h" +#include "X86IntelAsmPrinter.h" +#include "X86.h" +#include "llvm/Module.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/CommandLine.h" +using namespace llvm; +using namespace x86; + +Statistic<> llvm::x86::EmittedInsts("asm-printer", + "Number of machine instrs printed"); + +enum AsmWriterFlavorTy { att, intel }; +cl::opt +AsmWriterFlavor("x86-asm-syntax", + cl::desc("Choose style of code to emit from X86 backend:"), + cl::values( + clEnumVal(att, " Emit AT&T-style assembly"), + clEnumVal(intel, " Emit Intel-style assembly"), + clEnumValEnd), + cl::init(att)); + +/// doInitialization +bool X86SharedAsmPrinter::doInitialization(Module& M) { + bool leadingUnderscore = false; + forCygwin = false; + const std::string& TT = M.getTargetTriple(); + if (TT.length() > 5) { + forCygwin = TT.find("cygwin") != std::string::npos || + TT.find("mingw") != std::string::npos; + forDarwin = TT.find("darwin") != std::string::npos; + } else if (TT.empty()) { + #if defined(__CYGWIN__) || defined(__MINGW32__) + forCygwin = true; + #elif defined(__APPLE__) + forDarwin = true; + #elif defined(_WIN32) + leadingUnderscore = true; + #else + leadingUnderscore = false; + #endif + } + if (leadingUnderscore || forCygwin || forDarwin) + GlobalPrefix = "_"; + + if (forDarwin) + AlignmentIsInBytes = false; + + return AsmPrinter::doInitialization(M); +} + +/// printConstantPool - Print to the current output stream assembly +/// representations of the constants in the constant pool MCP. This is +/// used to print out constants which have been "spilled to memory" by +/// the code generator. +/// +void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) { + const std::vector &CP = MCP->getConstants(); + const TargetData &TD = TM.getTargetData(); + + if (CP.empty()) return; + + for (unsigned i = 0, e = CP.size(); i != e; ++i) { + if (forDarwin) + O << "\t.data\n"; + else + O << "\t.section .rodata\n"; + emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); + O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString + << *CP[i] << "\n"; + emitGlobalConstant(CP[i]); + } +} + +bool X86SharedAsmPrinter::doFinalization(Module &M) { + const TargetData &TD = TM.getTargetData(); + std::string CurSection; + + // Print out module-level global variables here. + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + if (I->hasInitializer()) { // External global require no code + O << "\n\n"; + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD.getTypeSize(C->getType()); + unsigned Align = TD.getTypeAlignmentShift(C->getType()); + + if (C->isNullValue() && + (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || + I->hasWeakLinkage() /* FIXME: Verify correct */)) { + SwitchSection(O, CurSection, ".data"); + if (!forCygwin && !forDarwin && I->hasInternalLinkage()) + O << "\t.local " << name << "\n"; + if (forDarwin && I->hasInternalLinkage()) + O << "\t.lcomm " << name << "," << Size << "," << Align; + else + O << "\t.comm " << name << "," << Size; + if (!forCygwin && !forDarwin) + O << "," << (1 << Align); + O << "\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << "\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + SwitchSection(O, CurSection, ""); + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.globl " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (C->isNullValue()) + SwitchSection(O, CurSection, ".bss"); + else + SwitchSection(O, CurSection, ".data"); + break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; + abort(); + } + + emitAlignment(Align); + if (!forCygwin && !forDarwin) { + O << "\t.type " << name << ", at object\n"; + O << "\t.size " << name << "," << Size << "\n"; + } + O << name << ":\t\t\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + emitGlobalConstant(C); + } + } + + if (forDarwin) { + // Output stubs for dynamically-linked functions + unsigned j = 1; + for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); + i != e; ++i, ++j) + { + O << "\t.symbol_stub\n"; + O << "L" << *i << "$stub:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\tjmp\t*L" << j << "$lz\n"; + O << "L" << *i << "$stub_binder:\n"; + O << "\tpushl\t$L" << j << "$lz\n"; + O << "\tjmp\tdyld_stub_binding_helper\n"; + O << "\t.section __DATA, __la_sym_ptr3,lazy_symbol_pointers\n"; + O << "L" << j << "$lz:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long\tL" << *i << "$stub_binder\n"; + } + + O << "\n"; + + // Output stubs for external global variables + if (GVStubs.begin() != GVStubs.end()) + O << ".data\n.non_lazy_symbol_pointer\n"; + for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); + i != e; ++i) { + O << "L" << *i << "$non_lazy_ptr:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long\t0\n"; + } + + // Output stubs for link-once variables + if (LinkOnceStubs.begin() != LinkOnceStubs.end()) + O << ".data\n.align 2\n"; + for (std::set::iterator i = LinkOnceStubs.begin(), + e = LinkOnceStubs.end(); i != e; ++i) { + O << "L" << *i << "$non_lazy_ptr:\n" + << "\t.long\t" << *i << '\n'; + } + } + + AsmPrinter::doFinalization(M); + return false; // success +} + +/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code +/// for a MachineFunction to the given output stream, using the given target +/// machine description. +/// +FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ + switch (AsmWriterFlavor) { + default: + assert(0 && "Unknown asm flavor!"); + case intel: + return new X86IntelAsmPrinter(o, tm); + case att: + return new X86ATTAsmPrinter(o, tm); + } +} Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.1 llvm/lib/Target/X86/X86AsmPrinter.h:1.2 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.1 Fri Jul 1 17:44:09 2005 +++ llvm/lib/Target/X86/X86AsmPrinter.h Thu Jul 7 19:23:26 2005 @@ -1,69 +1,74 @@ -//===-- X86AsmPrinter.h - Convert X86 LLVM code to Intel assembly ---------===// -// -// 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 the shared super class printer that converts from our internal -// representation of machine-dependent LLVM code to Intel and AT&T format -// assembly language. This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#ifndef X86ASMPRINTER_H -#define X86ASMPRINTER_H - -#include "X86.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/ADT/Statistic.h" - -namespace llvm { -namespace x86 { - -extern Statistic<> EmittedInsts; - -struct X86SharedAsmPrinter : public AsmPrinter { - X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { } - - bool doInitialization(Module &M); - void printConstantPool(MachineConstantPool *MCP); - bool doFinalization(Module &M); - - bool forCygwin; - bool forDarwin; - - inline static bool isScale(const MachineOperand &MO) { - return MO.isImmediate() && - (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || - MO.getImmedValue() == 4 || MO.getImmedValue() == 8); - } - - inline static bool isMem(const MachineInstr *MI, unsigned Op) { - if (MI->getOperand(Op).isFrameIndex()) return true; - if (MI->getOperand(Op).isConstantPoolIndex()) return true; - return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate()|| - MI->getOperand(Op+3).isGlobalAddress()); - } - - // SwitchSection - Switch to the specified section of the executable if we are - // not already in it! - inline static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } - } -}; - -} // end namespace x86 -} // end namespace llvm - -#endif +//===-- X86AsmPrinter.h - Convert X86 LLVM code to Intel assembly ---------===// +// +// 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 the shared super class printer that converts from our internal +// representation of machine-dependent LLVM code to Intel and AT&T format +// assembly language. This printer is the output mechanism used by `llc'. +// +//===----------------------------------------------------------------------===// + +#ifndef X86ASMPRINTER_H +#define X86ASMPRINTER_H + +#include "X86.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/ADT/Statistic.h" +#include + + +namespace llvm { +namespace x86 { + +extern Statistic<> EmittedInsts; + +struct X86SharedAsmPrinter : public AsmPrinter { + X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) + : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { } + + bool doInitialization(Module &M); + void printConstantPool(MachineConstantPool *MCP); + bool doFinalization(Module &M); + + bool forCygwin; + bool forDarwin; + + // Necessary for Darwin to print out the apprioriate types of linker stubs + std::set FnStubs, GVStubs, LinkOnceStubs; + + inline static bool isScale(const MachineOperand &MO) { + return MO.isImmediate() && + (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || + MO.getImmedValue() == 4 || MO.getImmedValue() == 8); + } + + inline static bool isMem(const MachineInstr *MI, unsigned Op) { + if (MI->getOperand(Op).isFrameIndex()) return true; + if (MI->getOperand(Op).isConstantPoolIndex()) return true; + return Op+4 <= MI->getNumOperands() && + MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && + MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate()|| + MI->getOperand(Op+3).isGlobalAddress()); + } + + // SwitchSection - Switch to the specified section of the executable if we are + // not already in it! + inline static void SwitchSection(std::ostream &OS, std::string &CurSection, + const char *NewSection) { + if (CurSection != NewSection) { + CurSection = NewSection; + if (!CurSection.empty()) + OS << "\t" << NewSection << "\n"; + } + } +}; + +} // end namespace x86 +} // end namespace llvm + +#endif From jeffc at jolt-lang.org Thu Jul 7 21:48:15 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 7 Jul 2005 21:48:15 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200507080248.VAA06317@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.24 -> 1.25 --- Log message: fix typo --- Diffs of the changes: (+1 -1) Path.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.24 llvm/include/llvm/System/Path.h:1.25 --- llvm/include/llvm/System/Path.h:1.24 Thu Jul 7 18:21:43 2005 +++ llvm/include/llvm/System/Path.h Thu Jul 7 21:48:04 2005 @@ -155,7 +155,7 @@ /// @brief Construct an empty (and invalid) path. Path() : path() {} - /// This constructor will accept a std::string as a path but if verifies + /// This constructor will accept a std::string as a path but it verifies /// that the path string has a legal syntax for the operating system on /// which it is running. This allows a path to be taken in from outside /// the program. However, if the path is not valid, the Path object will From jeffc at jolt-lang.org Thu Jul 7 21:48:53 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 7 Jul 2005 21:48:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Program.inc Signals.inc Message-ID: <200507080248.VAA06336@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.34 -> 1.35 Program.inc updated: 1.14 -> 1.15 Signals.inc updated: 1.14 -> 1.15 --- Log message: Fix VC++ breakage --- Diffs of the changes: (+10 -13) Path.inc | 13 +++++-------- Program.inc | 6 +++--- Signals.inc | 4 ++-- 3 files changed, 10 insertions(+), 13 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.34 llvm/lib/System/Win32/Path.inc:1.35 --- llvm/lib/System/Win32/Path.inc:1.34 Thu Jul 7 18:35:23 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 21:48:42 2005 @@ -99,11 +99,11 @@ // Append a subdirectory passed on our process id so multiple LLVMs don't // step on each other's toes. sprintf(pathname, "LLVM_%u", GetCurrentProcessId()); - result.appendDirectory(pathname); + result.appendComponent(pathname); // If there's a directory left over from a previous LLVM execution that // happened to have the same process id, get rid of it. - result.destroyDirectory(true); + result.destroy(true); // And finally (re-)create the empty directory. result.createDirectory(false); @@ -195,10 +195,7 @@ bool Path::isFile() const { - WIN32_FILE_ATTRIBUTE_DATA fi; - if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) - ThrowError(std::string(path) + ": Can't get status: "); - return fi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL; + return !isDirectory(); } bool @@ -395,7 +392,7 @@ } bool -Path::appendComponent(const std::string& dir) { +Path::appendComponent(const std::string& name) { if (name.empty()) return false; std::string save(path); @@ -528,7 +525,7 @@ if (!DeleteFile(path.c_str())) ThrowError(path + ": Can't destroy file: "); return true; - } else if (isDirectory()) { + } else /* isDirectory() */ { // If it doesn't exist, we're done. if (!exists()) Index: llvm/lib/System/Win32/Program.inc diff -u llvm/lib/System/Win32/Program.inc:1.14 llvm/lib/System/Win32/Program.inc:1.15 --- llvm/lib/System/Win32/Program.inc:1.14 Thu May 5 17:33:09 2005 +++ llvm/lib/System/Win32/Program.inc Thu Jul 7 21:48:42 2005 @@ -31,9 +31,9 @@ if (progName.length() == 0) // no program return Path(); Path temp; - if (!temp.setFile(progName)) // invalid name + if (!temp.set(progName)) // invalid name return Path(); - if (temp.executable()) // already executable as is + if (temp.canExecute()) // already executable as is return temp; // At this point, the file name is valid and its not executable. @@ -101,7 +101,7 @@ const char** envp, const Path** redirects, unsigned secondsToWait) { - if (!path.executable()) + if (!path.canExecute()) throw path.toString() + " is not executable"; // Windows wants a command line, not an array of args, to pass to the new Index: llvm/lib/System/Win32/Signals.inc diff -u llvm/lib/System/Win32/Signals.inc:1.14 llvm/lib/System/Win32/Signals.inc:1.15 --- llvm/lib/System/Win32/Signals.inc:1.14 Thu May 5 17:33:09 2005 +++ llvm/lib/System/Win32/Signals.inc Thu Jul 7 21:48:42 2005 @@ -123,7 +123,7 @@ if (FilesToRemove != NULL) while (!FilesToRemove->empty()) { try { - FilesToRemove->back().destroyFile(); + FilesToRemove->back().destroy(); } catch (...) { } FilesToRemove->pop_back(); @@ -132,7 +132,7 @@ if (DirectoriesToRemove != NULL) while (!DirectoriesToRemove->empty()) { try { - DirectoriesToRemove->back().destroyDirectory(true); + DirectoriesToRemove->back().destroy(true); } catch (...) { } DirectoriesToRemove->pop_back(); From reid at x10sys.com Thu Jul 7 22:09:13 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:13 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/FileUtilities.h Message-ID: <200507080309.WAA06487@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: FileUtilities.h updated: 1.32 -> 1.33 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+1 -1) FileUtilities.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Support/FileUtilities.h diff -u llvm/include/llvm/Support/FileUtilities.h:1.32 llvm/include/llvm/Support/FileUtilities.h:1.33 --- llvm/include/llvm/Support/FileUtilities.h:1.32 Thu Jul 7 18:21:42 2005 +++ llvm/include/llvm/Support/FileUtilities.h Thu Jul 7 22:08:58 2005 @@ -45,7 +45,7 @@ ~FileRemover() { if (DeleteIt) try { - Filename.destroy(); + Filename.eraseFromDisk(); } catch (...) {} // Ignore problems deleting the file. } From reid at x10sys.com Thu Jul 7 22:09:13 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:13 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvmc/CompilerDriver.cpp Message-ID: <200507080309.WAA06491@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvmc: CompilerDriver.cpp updated: 1.33 -> 1.34 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+1 -1) CompilerDriver.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvmc/CompilerDriver.cpp diff -u llvm/tools/llvmc/CompilerDriver.cpp:1.33 llvm/tools/llvmc/CompilerDriver.cpp:1.34 --- llvm/tools/llvmc/CompilerDriver.cpp:1.33 Thu Jul 7 18:21:43 2005 +++ llvm/tools/llvmc/CompilerDriver.cpp Thu Jul 7 22:08:58 2005 @@ -188,7 +188,7 @@ void cleanup() { if (!isSet(KEEP_TEMPS_FLAG)) { if (TempDir.isDirectory() && TempDir.canWrite()) - TempDir.destroy(/*remove_contents=*/true); + TempDir.eraseFromDisk(/*remove_contents=*/true); } else { std::cout << "Temporary files are in " << TempDir << "\n"; } From reid at x10sys.com Thu Jul 7 22:09:13 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:13 -0500 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp ExecutionDriver.cpp Miscompilation.cpp OptimizerDriver.cpp Message-ID: <200507080309.WAA06499@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.43 -> 1.44 ExecutionDriver.cpp updated: 1.55 -> 1.56 Miscompilation.cpp updated: 1.66 -> 1.67 OptimizerDriver.cpp updated: 1.32 -> 1.33 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+13 -13) CrashDebugger.cpp | 2 +- ExecutionDriver.cpp | 10 +++++----- Miscompilation.cpp | 10 +++++----- OptimizerDriver.cpp | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.43 llvm/tools/bugpoint/CrashDebugger.cpp:1.44 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.43 Thu Jul 7 18:21:43 2005 +++ llvm/tools/bugpoint/CrashDebugger.cpp Thu Jul 7 22:08:58 2005 @@ -67,7 +67,7 @@ << PrefixOutput << "'!\n"; exit(1); } - PrefixOutput.destroy(); + PrefixOutput.eraseFromDisk(); } std::cout << "Checking to see if these passes crash: " Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.55 llvm/tools/bugpoint/ExecutionDriver.cpp:1.56 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.55 Thu Jul 7 18:21:43 2005 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu Jul 7 22:08:58 2005 @@ -281,7 +281,7 @@ exit(1); // Remove the intermediate C file - OutputCFile.destroy(); + OutputCFile.eraseFromDisk(); return "./" + SharedObjectFile; } @@ -302,9 +302,9 @@ // If we're checking the program exit code, assume anything nonzero is bad. if (CheckProgramExitCode && ProgramExitedNonzero) { - Output.destroy(); + Output.eraseFromDisk(); if (RemoveBytecode) - sys::Path(BytecodeFile).destroy(); + sys::Path(BytecodeFile).eraseFromDisk(); return true; } @@ -321,11 +321,11 @@ } // Remove the generated output. - Output.destroy(); + Output.eraseFromDisk(); // Remove the bytecode file if we are supposed to. if (RemoveBytecode) - sys::Path(BytecodeFile).destroy(); + sys::Path(BytecodeFile).eraseFromDisk(); return FilesDifferent; } Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.66 llvm/tools/bugpoint/Miscompilation.cpp:1.67 --- llvm/tools/bugpoint/Miscompilation.cpp:1.66 Thu Jul 7 18:21:43 2005 +++ llvm/tools/bugpoint/Miscompilation.cpp Thu Jul 7 22:08:58 2005 @@ -99,7 +99,7 @@ // If the prefix maintains the predicate by itself, only keep the prefix! if (BD.diffProgram(BytecodeResult)) { std::cout << " nope.\n"; - sys::Path(BytecodeResult).destroy(); + sys::Path(BytecodeResult).eraseFromDisk(); return KeepPrefix; } std::cout << " yup.\n"; // No miscompilation! @@ -113,7 +113,7 @@ << BytecodeResult << "'!\n"; exit(1); } - sys::Path(BytecodeResult).destroy(); // No longer need the file on disk + sys::Path(BytecodeResult).eraseFromDisk(); // No longer need the file on disk // Don't check if there are no passes in the suffix. if (Suffix.empty()) @@ -775,9 +775,9 @@ std::cerr << ": still failing!\n"; else std::cerr << ": didn't fail.\n"; - TestModuleBC.destroy(); - SafeModuleBC.destroy(); - sys::Path(SharedObject).destroy(); + TestModuleBC.eraseFromDisk(); + SafeModuleBC.eraseFromDisk(); + sys::Path(SharedObject).eraseFromDisk(); return Result; } Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.32 llvm/tools/bugpoint/OptimizerDriver.cpp:1.33 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.32 Thu Jul 7 18:21:43 2005 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Thu Jul 7 22:08:58 2005 @@ -161,7 +161,7 @@ // If we are supposed to delete the bytecode file or if the passes crashed, // remove it now. This may fail if the file was never created, but that's ok. if (DeleteOutput || !ExitedOK) - sys::Path(OutputFilename).destroy(); + sys::Path(OutputFilename).eraseFromDisk(); #ifndef PLATFORMINDEPENDENT if (!Quiet) { @@ -214,6 +214,6 @@ << BytecodeResult << "'!\n"; exit(1); } - sys::Path(BytecodeResult).destroy(); // No longer need the file on disk + sys::Path(BytecodeResult).eraseFromDisk(); // No longer need the file on disk return Ret; } From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <200507080309.WAA06511@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.44 -> 1.45 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+3 -3) ToolRunner.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.44 llvm/lib/Support/ToolRunner.cpp:1.45 --- llvm/lib/Support/ToolRunner.cpp:1.44 Thu Jul 7 19:23:26 2005 +++ llvm/lib/Support/ToolRunner.cpp Thu Jul 7 22:08:58 2005 @@ -65,7 +65,7 @@ ErrorFile.close(); } - ErrorFilename.destroy(); + ErrorFilename.eraseFromDisk(); throw ToolExecutionError(OS.str()); } @@ -176,7 +176,7 @@ void LLC::compileProgram(const std::string &Bytecode) { sys::Path OutputAsmFile; OutputAsm(Bytecode, OutputAsmFile); - OutputAsmFile.destroy(); + OutputAsmFile.eraseFromDisk(); } int LLC::ExecuteProgram(const std::string &Bytecode, @@ -321,7 +321,7 @@ void CBE::compileProgram(const std::string &Bytecode) { sys::Path OutputCFile; OutputC(Bytecode, OutputCFile); - OutputCFile.destroy(); + OutputCFile.eraseFromDisk(); } int CBE::ExecuteProgram(const std::string &Bytecode, From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Path.h Message-ID: <200507080309.WAA06501@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Path.h updated: 1.25 -> 1.26 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+129 -124) Path.h | 253 +++++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 129 insertions(+), 124 deletions(-) Index: llvm/include/llvm/System/Path.h diff -u llvm/include/llvm/System/Path.h:1.25 llvm/include/llvm/System/Path.h:1.26 --- llvm/include/llvm/System/Path.h:1.25 Thu Jul 7 21:48:04 2005 +++ llvm/include/llvm/System/Path.h Thu Jul 7 22:08:58 2005 @@ -27,21 +27,28 @@ /// in the operating system's filesystem and provides various basic operations /// on it. Note that this class only represents the name of a path to a file /// or directory which may or may not be valid for a given machine's file - /// system. A Path ensures that the name it encapsulates is syntactical valid - /// for the operating system it is running on but does not ensure correctness - /// for any particular file system. A Path either references a file or a - /// directory and the distinction is consistently maintained. Most operations - /// on the class have invariants that require the Path object to be either a - /// file path or a directory path, but not both. Those operations will also - /// leave the object as either a file path or object path. There is exactly - /// one invalid Path which is the empty path. The class should never allow any - /// other syntactically invalid non-empty path name to be assigned. Empty - /// paths are required in order to indicate an error result. If the path is - /// empty, the isValid operation will return false. All operations will fail - /// if isValid is false. Operations that change the path will either return - /// false if it would cause a syntactically invalid path name (in which case - /// the Path object is left unchanged) or throw an std::string exception - /// indicating the error. + /// system. The class is patterned after the java.io.File class with various + /// extensions and several omissions (not relevant to LLVM). A Path object + /// ensures that the path it encapsulates is syntactically valid for the + /// operating system it is running on but does not ensure correctness for + /// any particular file system. That is, a syntactically valid path might + /// specify path components that do not exist in the file system and using + /// such a Path to act on the file system could produce errors. There is one + /// invalid Path value which is permitted: the empty path. The class should + /// never allow a syntactically invalid non-empty path name to be assigned. + /// Empty paths are required in order to indicate an error result in some + /// situations. If the path is empty, the isValid operation will return + /// false. All operations will fail if isValid is false. Operations that + /// change the path will either return false if it would cause a syntactically + /// invalid path name (in which case the Path object is left unchanged) or + /// throw an std::string exception indicating the error. The methods are + /// grouped into four basic categories: Path Accessors (provide information + /// about the path without accessing disk), Disk Accessors (provide + /// information about the underlying file or directory), Path Mutators + /// (change the path information, not the disk), and Disk Mutators (change + /// the disk file/directory referenced by the path). The Disk Mutator methods + /// all have the word "disk" embedded in their method name to reinforce the + /// notion that the operation modifies the file system. /// @since 1.4 /// @brief An abstraction for operating system paths. class Path { @@ -76,8 +83,8 @@ /// directory is a top level directory above which there are no more /// directories. For example, on UNIX, the root directory is /. On Windows /// it is C:\. Other operating systems may have different notions of - /// what the root directory is. - /// @throws nothing + /// what the root directory is or none at all. In that case, a consistent + /// default root directory will be used. static Path GetRootDirectory(); /// Construct a path to a unique temporary directory that is created in @@ -93,8 +100,7 @@ /// library paths suitable for linking into programs. This function *must* /// return the value of LLVM_LIB_SEARCH_PATH as the first item in \p Paths /// if that environment variable is set and it references a directory. - /// @throws nothing - /// @brief Construct a path to the first system library directory + /// @brief Construct a path to the system library directory static void GetSystemLibraryPaths(std::vector& Paths); /// Construct a vector of sys::Path that contains the "standard" bytecode @@ -116,7 +122,6 @@ /// implementation must ensure that this is a well-known (same on many /// systems) directory in which llvm configuration files exist. For /// example, on Unix, the /etc/llvm directory has been selected. - /// @throws nothing /// @brief Construct a path to the default LLVM configuration directory static Path GetLLVMDefaultConfigDir(); @@ -124,7 +129,6 @@ /// implementation must ensure that this refers to the "etc" directory of /// the LLVM installation. This is the location where configuration files /// will be located for a particular installation of LLVM on a machine. - /// @throws nothing /// @brief Construct a path to the LLVM installed configuration directory static Path GetLLVMConfigDir(); @@ -134,7 +138,6 @@ /// variable "HOME" could be used on Unix. If a given operating system /// does not have the concept of a user's home directory, this static /// constructor must provide the same result as GetRootDirectory. - /// @throws nothing /// @brief Construct a path to the current user's "home" directory static Path GetUserHomeDirectory(); @@ -151,7 +154,6 @@ /// empty one. Other invalid names are not permitted. Empty paths are /// provided so that they can be used to indicate null or error results in /// other lib/System functionality. - /// @throws nothing /// @brief Construct an empty (and invalid) path. Path() : path() {} @@ -160,7 +162,7 @@ /// which it is running. This allows a path to be taken in from outside /// the program. However, if the path is not valid, the Path object will /// be set to an empty string and an exception will be thrown. - /// @throws std::string if the path string is not legal. + /// @throws std::string if \p unverified_path is not legal. /// @param unverified_path The path to verify and assign. /// @brief Construct a Path from a string. explicit Path(const std::string& unverified_path); @@ -171,7 +173,6 @@ public: /// Makes a copy of \p that to \p this. /// @returns \p this - /// @throws nothing /// @brief Assignment Operator Path & operator = ( const Path & that ) { path = that.path; @@ -180,7 +181,6 @@ /// Compares \p this Path with \p that Path for equality. /// @returns true if \p this and \p that refer to the same thing. - /// @throws nothing /// @brief Equality Operator bool operator == (const Path& that) const { return 0 == path.compare(that.path) ; @@ -188,7 +188,6 @@ /// Compares \p this Path with \p that Path for inequality. /// @returns true if \p this and \p that refer to different things. - /// @throws nothing /// @brief Inequality Operator bool operator !=( const Path & that ) const { return 0 != path.compare( that.path ); @@ -199,14 +198,13 @@ /// std::map). The comparison is done lexicographically as defined by /// the std::string::compare method. /// @returns true if \p this path is lexicographically less than \p that. - /// @throws nothing /// @brief Less Than Operator bool operator< (const Path& that) const { return 0 > path.compare( that.path ); } /// @} - /// @name Accessors + /// @name Path Accessors /// @{ public: /// This function will use an operating system specific algorithm to @@ -225,8 +223,38 @@ /// @brief Determines if the path name is empty (invalid). bool isEmpty() const { return path.empty(); } + /// This function returns the current contents of the path as a + /// std::string. This allows the underlying path string to be manipulated. + /// @returns std::string containing the path name. + /// @brief Returns the path as a std::string. + const std::string& toString() const { return path; } + + /// This function returns the last component of the path name. The last + /// component is the file or directory name occuring after the last + /// directory separator. If no directory separator is present, the entire + /// path name is returned (i.e. same as toString). + /// @returns std::string containing the last component of the path name. + /// @brief Returns the last component of the path name. + std::string getLast() const; + + /// This function strips off the path and suffix of the file or directory + /// name and returns just the basename. For example /a/foo.bar would cause + /// this function to return "foo". + /// @returns std::string containing the basename of the path + /// @brief Get the base name of the path + std::string getBasename() const; + + /// Obtain a 'C' string for the path name. + /// @returns a 'C' string containing the path name. + /// @brief Returns the path as a C string. + const char* const c_str() const { return path.c_str(); } + + /// @} + /// @name Disk Accessors + /// @{ + public: /// This function determines if the object referenced by this path is - /// a file or not. This function accesses the under lying file system to + /// a file or not. This function accesses the underlying file system to /// determine the type of entity referenced by the path. /// @returns true if this path name references a file. /// @brief Determines if the path name references a file. @@ -328,28 +356,6 @@ /// system. bool canExecute() const; - /// This function returns the current contents of the path as a - /// std::string. This allows the underlying path string to be manipulated - /// by other software. - /// @returns std::string containing the path name. - /// @brief Returns the path as a std::string. - const std::string& toString() const { return path; } - - /// This function returns the last component of the path name. The last - /// component is the file or directory name occuring after the last - /// directory separator. - /// @returns std::string containing the last component of the path name. - /// @brief Returns the last component of the path name. - std::string getLast() const; - - /// This function strips off the path and suffix of the file or directory - /// name and returns just the basename. For example /a/foo.bar would cause - /// this function to return "foo". - /// @returns std::string containing the basename of the path - /// @throws nothing - /// @brief Get the base name of the path - std::string getBasename() const; - /// This function builds a list of paths that are the names of the /// files and directories in a directory. /// @returns false if \p this is not a directory, true otherwise @@ -357,40 +363,10 @@ /// @brief Build a list of directory's contents. bool getDirectoryContents(std::set& paths) const; - /// This method attempts to destroy the file or directory named by the - /// last component of the Path. If the Path refers to a directory and the - /// \p destroy_contents is false, an attempt will be made to remove just - /// the directory (the final Path component). If \p destroy_contents is - /// true, an attempt will be made to remove the entire contents of the - /// directory, recursively. If the Path refers to a file, the - /// \p destroy_contents parameter is ignored. - /// @param destroy_contents Indicates whether the contents of a destroyed - /// directory should also be destroyed (recursively). - /// @returns true if the file/directory was destroyed, false if the path - /// refers to something that is neither a file nor a directory. - /// @throws std::string if there is an error. - /// @brief Removes the file or directory from the filesystem. - bool destroy( bool destroy_contents = false ) const; - - /// Obtain a 'C' string for the path name. - /// @returns a 'C' string containing the path name. - /// @brief Returns the path as a C string. - const char* const c_str() const { return path.c_str(); } - - /// @} - /// @name Mutators - /// @{ - public: - /// The path name is cleared and becomes empty. This is an invalid - /// path name but is the *only* invalid path name. This is provided - /// so that path objects can be used to indicate the lack of a - /// valid path being found. - void clear() { path.clear(); } - /// This function returns status information about the file. The type of /// path (file or directory) is updated to reflect the actual contents /// of the file system. If the file does not exist, false is returned. - /// For other (hard I/O) errors, a std::string is throwing indicating the + /// For other (hard I/O) errors, a std::string is thrown indicating the /// problem. /// @throws std::string if an error occurs. /// @brief Get file status. @@ -411,37 +387,30 @@ StatusInfo info; getStatusInfo(info); return info.fileSize; } - /// This method attempts to make the file referenced by the Path object - /// available for reading so that the readable() method will return true. - /// @brief Make the file readable; - void makeReadable(); - - /// This method attempts to make the file referenced by the Path object - /// available for writing so that the writable() method will return true. - /// @brief Make the file writable; - void makeWriteable(); - - /// This method attempts to make the file referenced by the Path object - /// available for execution so that the executable() method will return - /// true. - /// @brief Make the file readable; - void makeExecutable(); + /// @} + /// @name Path Mutators + /// @{ + public: + /// The path name is cleared and becomes empty. This is an invalid + /// path name but is the *only* invalid path name. This is provided + /// so that path objects can be used to indicate the lack of a + /// valid path being found. + /// @brief Make the path empty. + void clear() { path.clear(); } /// This method sets the Path object to \p unverified_path. This can fail /// if the \p unverified_path does not pass the syntactic checks of the - /// isValid method. If verification fails, the Path object remains + /// isValid() method. If verification fails, the Path object remains /// unchanged and false is returned. Otherwise true is returned and the /// Path object takes on the path value of \p unverified_path /// @returns true if the path was set, false otherwise. /// @param unverified_path The path to be set in Path object. - /// @throws nothing /// @brief Set a full path from a std::string bool set(const std::string& unverified_path); /// One path component is removed from the Path. If only one component is /// present in the path, the Path object becomes empty. If the Path object /// is empty, no change is made. - /// @throws nothing /// @returns false if the path component could not be removed. /// @brief Removes the last directory component of the Path. bool eraseComponent(); @@ -449,7 +418,6 @@ /// The \p component is added to the end of the Path if it is a legal /// name for the operating system. A directory separator will be added if /// needed. - /// @throws nothing /// @returns false if the path component could not be added. /// @brief Appends one path component to the Path. bool appendComponent( const std::string& component ); @@ -460,7 +428,6 @@ /// action is taken and the function returns false. If the path would /// become invalid for the host operating system, false is returned. /// @returns false if the suffix could not be added, true if it was. - /// @throws nothing /// @brief Adds a period and the \p suffix to the end of the pathname. bool appendSuffix(const std::string& suffix); @@ -471,7 +438,6 @@ /// unchanged (i.e. it was already without a suffix) but the function /// returns false. /// @returns false if there was no suffix to remove, true otherwise. - /// @throws nothing /// @brief Remove the suffix from a path name. bool eraseSuffix(); @@ -483,30 +449,57 @@ /// @brief Make the current path name unique in the file system. void makeUnique( bool reuse_current = true ); + /// @} + /// @name Disk Mutators + /// @{ + public: + /// This method attempts to make the file referenced by the Path object + /// available for reading so that the canRead() method will return true. + /// @brief Make the file readable; + void makeReadableOnDisk(); + + /// This method attempts to make the file referenced by the Path object + /// available for writing so that the canWrite() method will return true. + /// @brief Make the file writable; + void makeWriteableOnDisk(); + + /// This method attempts to make the file referenced by the Path object + /// available for execution so that the canExecute() method will return + /// true. + /// @brief Make the file readable; + void makeExecutableOnDisk(); + + /// This method allows the last modified time stamp and permission bits + /// to be set on the disk object referenced by the Path. + /// @throws std::string if an error occurs. + /// @returns true + /// @brief Set the status information. + bool setStatusInfoOnDisk(const StatusInfo& si) const; + /// This method attempts to create a directory in the file system with the /// same name as the Path object. The \p create_parents parameter controls /// whether intermediate directories are created or not. if \p /// create_parents is true, then an attempt will be made to create all - /// intermediate directories. If \p create_parents is false, then only the - /// final directory component of the Path name will be created. The - /// created directory will have no entries. + /// intermediate directories, as needed. If \p create_parents is false, + /// then only the final directory component of the Path name will be + /// created. The created directory will have no entries. /// @returns false if the Path does not reference a directory, true /// otherwise. /// @param create_parents Determines whether non-existent directory /// components other than the last one (the "parents") are created or not. /// @throws std::string if an error occurs. /// @brief Create the directory this Path refers to. - bool createDirectory( bool create_parents = false ); + bool createDirectoryOnDisk( bool create_parents = false ); /// This method attempts to create a file in the file system with the same /// name as the Path object. The intermediate directories must all exist - /// at the time this method is called. Use createDirectories to + /// at the time this method is called. Use createDirectoriesOnDisk to /// accomplish that. The created file will be empty upon return from this /// function. /// @returns false if the Path does not reference a file, true otherwise. /// @throws std::string if an error occurs. /// @brief Create the file this Path refers to. - bool createFile(); + bool createFileOnDisk(); /// This is like createFile except that it creates a temporary file. A /// unique temporary file name is generated based on the contents of @@ -514,24 +507,37 @@ /// file is created. Note that this will both change the Path object /// *and* create the corresponding file. This function will ensure that /// the newly generated temporary file name is unique in the file system. - /// @throws std::string if there is an error + /// @param reuse_current When set to true, this parameter indicates that + /// if the current file name does not exist then it will be used without + /// modification. + /// @returns true if successful, false if the file couldn't be created. + /// @throws std::string if there is a hard error creating the temp file + /// name. /// @brief Create a unique temporary file - bool createTemporaryFile(bool reuse_current = false); - + bool createTemporaryFileOnDisk(bool reuse_current = false); - /// This method renames the file referenced by \p this as \p newName. Both - /// files must exist before making this call. - /// @returns false if the Path does not refer to a file, true otherwise. + /// This method renames the file referenced by \p this as \p newName. The + /// file referenced by \p this must exist. The file referenced by + /// \p newName does not need to exist. + /// @returns true /// @throws std::string if there is an file system error. /// @brief Rename one file as another. - bool rename(const Path& newName); + bool renamePathOnDisk(const Path& newName); - /// This method sets the access time, modification time, and permission - /// mode of the file associated with \p this as given by \p si. - /// @returns false if the Path does not refer to a file, true otherwise. - /// @throws std::string if the file could not be modified - /// @brief Set file times and mode. - bool setStatusInfo(const StatusInfo& si ) const ; + /// This method attempts to destroy the file or directory named by the + /// last component of the Path. If the Path refers to a directory and the + /// \p destroy_contents is false, an attempt will be made to remove just + /// the directory (the final Path component). If \p destroy_contents is + /// true, an attempt will be made to remove the entire contents of the + /// directory, recursively. If the Path refers to a file, the + /// \p destroy_contents parameter is ignored. + /// @param destroy_contents Indicates whether the contents of a destroyed + /// directory should also be destroyed (recursively). + /// @returns true if the file/directory was destroyed, false if the path + /// refers to something that is neither a file nor a directory. + /// @throws std::string if there is an error. + /// @brief Removes the file or directory from the filesystem. + bool eraseFromDisk( bool destroy_contents = false ) const; /// @} /// @name Data @@ -568,5 +574,4 @@ } - #endif From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507080309.WAA06509@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.35 -> 1.36 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+19 -12) Path.inc | 31 +++++++++++++++++++------------ 1 files changed, 19 insertions(+), 12 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.35 llvm/lib/System/Win32/Path.inc:1.36 --- llvm/lib/System/Win32/Path.inc:1.35 Thu Jul 7 21:48:42 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 22:08:58 2005 @@ -103,10 +103,10 @@ // If there's a directory left over from a previous LLVM execution that // happened to have the same process id, get rid of it. - result.destroy(true); + result.eraseFromDisk(true); // And finally (re-)create the empty directory. - result.createDirectory(false); + result.createDirectoryOnDisk(false); TempDirectory = new Path(result); return *TempDirectory; } @@ -206,6 +206,13 @@ return fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; } +bool +Path::isHidden() const { + // FIXME: implement this correctly for Win32. It should check the hidden file + // attribute. + return false; +} + std::string Path::getBasename() const { // Find the last slash @@ -322,11 +329,11 @@ return true; } -void Path::makeReadable() { +void Path::makeReadableOnDisk() { // All files are readable on Windows (ignoring security attributes). } -void Path::makeWriteable() { +void Path::makeWriteableOnDisk() { DWORD attr = GetFileAttributes(path.c_str()); // If it doesn't exist, we're done. @@ -339,7 +346,7 @@ } } -void Path::makeExecutable() { +void Path::makeExecutableOnDisk() { // All files are executable on Windows (ignoring security attributes). } @@ -447,7 +454,7 @@ } bool -Path::createDirectory( bool create_parents) { +Path::createDirectoryOnDisk( bool create_parents) { // Get a writeable copy of the path name char *pathname = reinterpret_cast(_alloca(path.length()+1)); path.copy(pathname,path.length()); @@ -495,7 +502,7 @@ } bool -Path::createFile() { +Path::createFileOnDisk() { // Create the file HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); @@ -507,7 +514,7 @@ } bool -Path::destroy(bool remove_contents) const { +Path::eraseFromDisk(bool remove_contents) const { if (isFile()) { DWORD attr = GetFileAttributes(path.c_str()); @@ -571,7 +578,7 @@ for (std::vector::iterator I = list.begin(); I != list.end(); ++I) { Path &aPath = *I; - aPath.destroy(true); + aPath.eraseFromDisk(true); } } else { if (GetLastError() != ERROR_FILE_NOT_FOUND) @@ -615,7 +622,7 @@ } bool -Path::rename(const Path& newName) { +Path::renamePathOnDisk(const Path& newName) { // FIXME: This should rename a directory too. if (!isFile()) return false; if (!MoveFile(path.c_str(), newName.c_str())) @@ -625,7 +632,7 @@ } bool -Path::setStatusInfo(const StatusInfo& si) const { +Path::setStatusInfoOnDisk(const StatusInfo& si) const { if (!isFile()) return false; HANDLE h = CreateFile(path.c_str(), @@ -705,7 +712,7 @@ } bool -Path::createTemporaryFile(bool reuse_current) { +Path::createTemporaryFileOnDisk(bool reuse_current) { // Make this into a unique file name makeUnique( reuse_current ); From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200507080309.WAA06533@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.101 -> 1.102 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+7 -7) gccld.cpp | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.101 llvm/tools/gccld/gccld.cpp:1.102 --- llvm/tools/gccld/gccld.cpp:1.101 Thu Jul 7 18:21:43 2005 +++ llvm/tools/gccld/gccld.cpp Thu Jul 7 22:08:58 2005 @@ -313,9 +313,9 @@ if (!SaveTemps) { // Remove the assembly language file. - AssemblyFile.destroy(); + AssemblyFile.eraseFromDisk(); // Remove the bytecode language file. - sys::Path(RealBytecodeOutput).destroy(); + sys::Path(RealBytecodeOutput).eraseFromDisk(); } } else if (NativeCBE) { @@ -345,21 +345,21 @@ if (!SaveTemps) { // Remove the assembly language file. - CFile.destroy(); + CFile.eraseFromDisk(); // Remove the bytecode language file. - sys::Path(RealBytecodeOutput).destroy(); + sys::Path(RealBytecodeOutput).eraseFromDisk(); } } else if (!LinkAsLibrary) { EmitShellScript(argv); // Make the bytecode file readable and directly executable in LLEE - sys::Path(RealBytecodeOutput).makeExecutable(); - sys::Path(RealBytecodeOutput).makeReadable(); + sys::Path(RealBytecodeOutput).makeExecutableOnDisk(); + sys::Path(RealBytecodeOutput).makeReadableOnDisk(); } // Make the output, whether native or script, executable as well... - sys::Path(OutputFilename).makeExecutable(); + sys::Path(OutputFilename).makeExecutableOnDisk(); } catch (const char*msg) { std::cerr << argv[0] << ": " << msg << "\n"; From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200507080309.WAA06521@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.25 -> 1.26 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+5 -5) llvm-ld.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.25 llvm/tools/llvm-ld/llvm-ld.cpp:1.26 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.25 Thu Jul 7 18:21:43 2005 +++ llvm/tools/llvm-ld/llvm-ld.cpp Thu Jul 7 22:08:58 2005 @@ -480,7 +480,7 @@ gcc, envp); // Remove the assembly language file. - AssemblyFile.destroy(); + AssemblyFile.eraseFromDisk(); } else if (NativeCBE) { sys::Path CFile (OutputFilename); CFile.appendSuffix("cbe.c"); @@ -505,18 +505,18 @@ GenerateNative(OutputFilename, CFile.toString(), Libraries, gcc, envp); // Remove the assembly language file. - CFile.destroy(); + CFile.eraseFromDisk(); } else { EmitShellScript(argv); } // Make the script executable... - sys::Path(OutputFilename).makeExecutable(); + sys::Path(OutputFilename).makeExecutableOnDisk(); // Make the bytecode file readable and directly executable in LLEE as well - sys::Path(RealBytecodeOutput).makeExecutable(); - sys::Path(RealBytecodeOutput).makeReadable(); + sys::Path(RealBytecodeOutput).makeExecutableOnDisk(); + sys::Path(RealBytecodeOutput).makeReadableOnDisk(); } return 0; From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200507080309.WAA06531@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.28 -> 1.29 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+2 -2) llvm-ar.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.28 llvm/tools/llvm-ar/llvm-ar.cpp:1.29 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.28 Thu Jul 7 18:21:43 2005 +++ llvm/tools/llvm-ar/llvm-ar.cpp Thu Jul 7 22:08:58 2005 @@ -432,7 +432,7 @@ if (I->hasPath()) { sys::Path dirs(I->getPath()); dirs.eraseComponent(); - dirs.createDirectory(/*create_parents=*/true); + dirs.createDirectoryOnDisk(/*create_parents=*/true); } // Open up a file stream for writing @@ -455,7 +455,7 @@ // If we're supposed to retain the original modification times, etc. do so // now. if (OriginalDates) - I->getPath().setStatusInfo(I->getStatusInfo()); + I->getPath().setStatusInfoOnDisk(I->getStatusInfo()); } } } From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Signals.inc Message-ID: <200507080309.WAA06527@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.37 -> 1.38 Signals.inc updated: 1.8 -> 1.9 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+19 -10) Path.inc | 27 ++++++++++++++++++--------- Signals.inc | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.37 llvm/lib/System/Unix/Path.inc:1.38 --- llvm/lib/System/Unix/Path.inc:1.37 Thu Jul 7 18:21:43 2005 +++ llvm/lib/System/Unix/Path.inc Thu Jul 7 22:08:58 2005 @@ -246,6 +246,15 @@ return S_ISDIR(buf.st_mode); } +bool +Path::isHidden() const { + size_t slash = path.rfind('/'); + return (slash != std::string::npos && + slash < path.length()-1 && + path[slash+1] == '.') || + (!path.empty() && slash == std::string::npos && path[0] == '.'); +} + std::string Path::getBasename() const { // Find the last slash @@ -388,17 +397,17 @@ return true; } -void Path::makeReadable() { +void Path::makeReadableOnDisk() { if (!AddPermissionBits(path,0444)) ThrowErrno(path + ": can't make file readable"); } -void Path::makeWriteable() { +void Path::makeWriteableOnDisk() { if (!AddPermissionBits(path,0222)) ThrowErrno(path + ": can't make file writable"); } -void Path::makeExecutable() { +void Path::makeExecutableOnDisk() { if (!AddPermissionBits(path,0111)) ThrowErrno(path + ": can't make file executable"); } @@ -511,7 +520,7 @@ } bool -Path::createDirectory( bool create_parents) { +Path::createDirectoryOnDisk( bool create_parents) { // Get a writeable copy of the path name char pathname[MAXPATHLEN]; path.copy(pathname,MAXPATHLEN); @@ -549,7 +558,7 @@ } bool -Path::createFile() { +Path::createFileOnDisk() { // Create the file int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR); if (fd < 0) @@ -560,7 +569,7 @@ } bool -Path::createTemporaryFile(bool reuse_current) { +Path::createTemporaryFileOnDisk(bool reuse_current) { // Make this into a unique file name makeUnique( reuse_current ); @@ -574,7 +583,7 @@ } bool -Path::destroy(bool remove_contents) const { +Path::eraseFromDisk(bool remove_contents) const { // Make sure we're dealing with a directory if (isFile()) { if (0 != unlink(path.c_str())) @@ -604,7 +613,7 @@ } bool -Path::rename(const Path& newName) { +Path::renamePathOnDisk(const Path& newName) { if (0 != ::rename(path.c_str(), newName.c_str())) ThrowErrno(std::string("can't rename '") + path + "' as '" + newName.toString() + "' "); @@ -612,7 +621,7 @@ } bool -Path::setStatusInfo(const StatusInfo& si) const { +Path::setStatusInfoOnDisk(const StatusInfo& si) const { struct utimbuf utb; utb.actime = si.modTime.toPosixTime(); utb.modtime = utb.actime; Index: llvm/lib/System/Unix/Signals.inc diff -u llvm/lib/System/Unix/Signals.inc:1.8 llvm/lib/System/Unix/Signals.inc:1.9 --- llvm/lib/System/Unix/Signals.inc:1.8 Thu Jul 7 18:21:43 2005 +++ llvm/lib/System/Unix/Signals.inc Thu Jul 7 22:08:58 2005 @@ -112,7 +112,7 @@ if (DirectoriesToRemove != 0) while (!DirectoriesToRemove->empty()) { - DirectoriesToRemove->back().destroy(true); + DirectoriesToRemove->back().eraseFromDisk(true); DirectoriesToRemove->pop_back(); } From reid at x10sys.com Thu Jul 7 22:09:14 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 7 Jul 2005 22:09:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Message-ID: <200507080309.WAA06517@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: ArchiveWriter.cpp updated: 1.19 -> 1.20 --- Log message: Final Changes For PR495: http://llvm.cs.uiuc.edu/PR495 : This chagne just renames some sys::Path methods to ensure they are not misused. The Path documentation now divides methods into two dimensions: Path/Disk and accessor/mutator. Path accessors and mutators only operate on the Path object itself without making any disk accesses. Disk accessors and mutators will also access or modify the file system. Because of the potentially destructive nature of disk mutators, it was decided that all such methods should end in the work "Disk" to ensure the user recognizes that the change will occur on the file system. This patch makes that change. The method name changes are: makeReadable -> makeReadableOnDisk makeWriteable -> makeWriteableOnDisk makeExecutable -> makeExecutableOnDisk setStatusInfo -> setStatusInfoOnDisk createDirectory -> createDirectoryOnDisk createFile -> createFileOnDisk createTemporaryFile -> createTemporaryFileOnDisk destroy -> eraseFromDisk rename -> renamePathOnDisk These changes pass the Linux Deja Gnu tests. --- Diffs of the changes: (+4 -4) ArchiveWriter.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Bytecode/Archive/ArchiveWriter.cpp diff -u llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.19 llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.20 --- llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:1.19 Thu Jul 7 18:21:43 2005 +++ llvm/lib/Bytecode/Archive/ArchiveWriter.cpp Thu Jul 7 22:08:58 2005 @@ -374,7 +374,7 @@ // Create a temporary file to store the archive in sys::Path TmpArchive = archPath; - TmpArchive.createTemporaryFile(); + TmpArchive.createTemporaryFileOnDisk(); // Make sure the temporary gets removed if we crash sys::RemoveFileOnSignal(TmpArchive); @@ -450,17 +450,17 @@ // Close up shop FinalFile.close(); arch.close(); - TmpArchive.destroy(); + TmpArchive.eraseFromDisk(); } else { // We don't have to insert the symbol table, so just renaming the temp // file to the correct name will suffice. - TmpArchive.rename(archPath); + TmpArchive.renamePathOnDisk(archPath); } } catch (...) { // Make sure we clean up. if (TmpArchive.exists()) - TmpArchive.destroy(); + TmpArchive.eraseFromDisk(); throw; } } From jeffc at jolt-lang.org Thu Jul 7 23:49:27 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 7 Jul 2005 23:49:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Message-ID: <200507080449.XAA10262@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.38 -> 1.39 --- Log message: Fix eraseSuffix() --- Diffs of the changes: (+6 -10) Path.inc | 16 ++++++---------- 1 files changed, 6 insertions(+), 10 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.38 llvm/lib/System/Unix/Path.inc:1.39 --- llvm/lib/System/Unix/Path.inc:1.38 Thu Jul 7 22:08:58 2005 +++ llvm/lib/System/Unix/Path.inc Thu Jul 7 23:49:16 2005 @@ -504,19 +504,15 @@ bool Path::eraseSuffix() { - std::string save(path); size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); - if (slashpos != std::string::npos && - dotpos != std::string::npos && - dotpos > slashpos) { - path.erase(dotpos, path.size()-dotpos); - } - if (!isValid()) { - path = save; - return false; + if (dotpos != std::string::npos) { + if (slashpos == std::string::npos || dotpos > slashpos) { + path.erase(dotpos, path.size()-dotpos); + return true; + } } - return true; + return false; } bool From jeffc at jolt-lang.org Thu Jul 7 23:50:20 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 7 Jul 2005 23:50:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Signals.inc Message-ID: <200507080450.XAA12643@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.36 -> 1.37 Signals.inc updated: 1.15 -> 1.16 --- Log message: Make Win32 implementation conform to new paradigm --- Diffs of the changes: (+61 -50) Path.inc | 107 +++++++++++++++++++++++++++++++++--------------------------- Signals.inc | 4 +- 2 files changed, 61 insertions(+), 50 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.36 llvm/lib/System/Win32/Path.inc:1.37 --- llvm/lib/System/Win32/Path.inc:1.36 Thu Jul 7 22:08:58 2005 +++ llvm/lib/System/Win32/Path.inc Thu Jul 7 23:50:08 2005 @@ -43,9 +43,18 @@ // and followed by something. size_t len = path.size(); size_t pos = path.rfind(':',len); + size_t rootslash = 0; if (pos != std::string::npos) { if (pos != 1 || !isalpha(path[0]) || len < 3) return false; + rootslash = 2; + } + + // Look for a UNC path, and if found adjust our notion of the root slash. + if (len > 3 && path[0] == '/' && path[1] == '/') { + rootslash = path.find('/', 2); + if (rootslash == std::string::npos) + rootslash = 0; } // Check for illegal characters. @@ -54,6 +63,10 @@ "\027\030\031\032\033\034\035\036\037") != std::string::npos) return false; + + // Remove trailing slash, unless it's a root slash. + if (len > rootslash+1 && path[len-1] == '/') + path.erase(--len); // Check each component for legality. for (pos = 0; pos < len; ++pos) { @@ -136,7 +149,7 @@ const char* at = path; const char* delim = strchr(at, ';'); Path tmpPath; - while( delim != 0 ) { + while (delim != 0) { std::string tmp(at, size_t(delim-at)); if (tmpPath.set(tmp)) if (tmpPath.canRead()) @@ -144,17 +157,17 @@ at = delim + 1; delim = strchr(at, ';'); } + if (*at != 0) if (tmpPath.set(std::string(at))) if (tmpPath.canRead()) Paths.push_back(tmpPath); - } void Path::GetSystemLibraryPaths(std::vector& Paths) { - Paths.push_back(sys::Path("C:\\WINDOWS\\SYSTEM32\\")); - Paths.push_back(sys::Path("C:\\WINDOWS\\")); + Paths.push_back(sys::Path("C:\\WINDOWS\\SYSTEM32")); + Paths.push_back(sys::Path("C:\\WINDOWS")); } void @@ -177,7 +190,7 @@ Path Path::GetLLVMDefaultConfigDir() { // TODO: this isn't going to fly on Windows - return Path("/etc/llvm/"); + return Path("/etc/llvm"); } Path @@ -208,9 +221,10 @@ bool Path::isHidden() const { - // FIXME: implement this correctly for Win32. It should check the hidden file - // attribute. - return false; + WIN32_FILE_ATTRIBUTE_DATA fi; + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + ThrowError(std::string(path) + ": Can't get status: "); + return fi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN; } std::string @@ -276,15 +290,10 @@ if (pos == std::string::npos) return path; - // If the last character is a slash - if (pos == path.length()-1) { - // Find the second to last slash - size_t pos2 = path.rfind('/', pos-1); - if (pos2 == std::string::npos) - return path.substr(0,pos); - else - return path.substr(pos2+1,pos-pos2-1); - } + // If the last character is a slash, we have a root directory + if (pos == path.length()-1) + return path; + // Return everything after the last slash return path.substr(pos+1); } @@ -307,10 +316,6 @@ info.modTime.fromWin32Time(ft); info.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - if (info.isDir && path[path.length() - 1] != '/') - path += '/'; - else if (!info.isDir && path[path.length() - 1] == '/') - path.erase(path.length() - 1); } static bool AddPermissionBits(const std::string& Filename, int bits) { @@ -357,7 +362,13 @@ result.clear(); WIN32_FIND_DATA fd; - std::string searchpath = path + "*"; + std::string searchpath = path; + if (path.size() == 0 || searchpath[path.size()-1] == '/') + searchpath += "*"; + else + searchpath += "/*"; + + HANDLE h = FindFirstFile(searchpath.c_str(), &fd); if (h == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) @@ -368,9 +379,8 @@ do { if (fd.cFileName[0] == '.') continue; - Path aPath(path + &fd.cFileName[0]); - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - aPath.path += "/"; + Path aPath(path); + aPath.appendComponent(&fd.cFileName[0]); result.insert(aPath); } while (FindNextFile(h, &fd)); @@ -390,7 +400,6 @@ std::string save(path); path = a_path; FlipBackSlashes(path); - size_t last = a_path.size() -1; if (!isValid()) { path = save; return false; @@ -419,11 +428,7 @@ bool Path::eraseComponent() { size_t slashpos = path.rfind('/',path.size()); - if (slashpos == 0 || slashpos == std::string::npos) - return false; - if (slashpos == path.size() - 1) - slashpos = path.rfind('/',slashpos-1); - if (slashpos == std::string::npos) + if (slashpos == path.size() - 1 || slashpos == std::string::npos) return false; path.erase(slashpos); return true; @@ -445,20 +450,28 @@ Path::eraseSuffix() { size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); - if (slashpos != std::string::npos && dotpos != std::string::npos && - dotpos > slashpos) { - path.erase(dotpos, path.size()-dotpos); - return true; + if (dotpos != std::string::npos) { + if (slashpos == std::string::npos || dotpos > slashpos) { + path.erase(dotpos, path.size()-dotpos); + return true; + } } return false; } bool -Path::createDirectoryOnDisk( bool create_parents) { +Path::createDirectoryOnDisk(bool create_parents) { // Get a writeable copy of the path name - char *pathname = reinterpret_cast(_alloca(path.length()+1)); - path.copy(pathname,path.length()); - pathname[path.length()] = 0; + size_t len = path.length(); + char *pathname = reinterpret_cast(_alloca(len+2)); + path.copy(pathname, len); + pathname[len] = 0; + + // Make sure it ends with a slash. + if (len == 0 || pathname[len - 1] != '/') { + pathname[len] = '/'; + pathname[++len] = 0; + } // Determine starting point for initial / search. char *next = pathname; @@ -493,7 +506,7 @@ } } else { // Drop trailing slash. - pathname[path.size()-1] = 0; + pathname[len-1] = 0; if (!CreateDirectory(pathname, NULL)) { ThrowError(std::string(pathname) + ": Can't create directory: "); } @@ -533,16 +546,17 @@ ThrowError(path + ": Can't destroy file: "); return true; } else /* isDirectory() */ { - // If it doesn't exist, we're done. if (!exists()) return true; - char *pathname = reinterpret_cast(_alloca(path.length()+2)); + char *pathname = reinterpret_cast(_alloca(path.length()+3)); int lastchar = path.length() - 1 ; - path.copy(pathname,lastchar+2); + path.copy(pathname, lastchar+1); // Make path end with '/*'. + if (pathname[lastchar] != '/') + pathname[++lastchar] = '/'; pathname[lastchar+1] = '*'; pathname[lastchar+2] = 0; @@ -562,9 +576,8 @@ if (strcmp(fd.cFileName, "..") == 0) continue; - Path aPath(path + &fd.cFileName[0]); - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - aPath.path += "/"; + Path aPath(path); + aPath.appendComponent(&fd.cFileName[0]); list.push_back(aPath); } while (FindNextFile(h, &fd)); @@ -623,8 +636,6 @@ bool Path::renamePathOnDisk(const Path& newName) { - // FIXME: This should rename a directory too. - if (!isFile()) return false; if (!MoveFile(path.c_str(), newName.c_str())) ThrowError("Can't move '" + path + "' to '" + newName.path + "': "); Index: llvm/lib/System/Win32/Signals.inc diff -u llvm/lib/System/Win32/Signals.inc:1.15 llvm/lib/System/Win32/Signals.inc:1.16 --- llvm/lib/System/Win32/Signals.inc:1.15 Thu Jul 7 21:48:42 2005 +++ llvm/lib/System/Win32/Signals.inc Thu Jul 7 23:50:08 2005 @@ -123,7 +123,7 @@ if (FilesToRemove != NULL) while (!FilesToRemove->empty()) { try { - FilesToRemove->back().destroy(); + FilesToRemove->back().eraseFromDisk(); } catch (...) { } FilesToRemove->pop_back(); @@ -132,7 +132,7 @@ if (DirectoriesToRemove != NULL) while (!DirectoriesToRemove->empty()) { try { - DirectoriesToRemove->back().destroy(true); + DirectoriesToRemove->back().eraseFromDisk(true); } catch (...) { } DirectoriesToRemove->pop_back(); From jeffc at jolt-lang.org Fri Jul 8 00:02:24 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 8 Jul 2005 00:02:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Message-ID: <200507080502.AAA13144@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.39 -> 1.40 --- Log message: Stamp out tabs --- Diffs of the changes: (+1 -1) Path.inc | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.39 llvm/lib/System/Unix/Path.inc:1.40 --- llvm/lib/System/Unix/Path.inc:1.39 Thu Jul 7 23:49:16 2005 +++ llvm/lib/System/Unix/Path.inc Fri Jul 8 00:02:13 2005 @@ -509,7 +509,7 @@ if (dotpos != std::string::npos) { if (slashpos == std::string::npos || dotpos > slashpos) { path.erase(dotpos, path.size()-dotpos); - return true; + return true; } } return false; From jeffc at jolt-lang.org Fri Jul 8 00:02:24 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 8 Jul 2005 00:02:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507080502.AAA13148@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.37 -> 1.38 --- Log message: Stamp out tabs --- Diffs of the changes: (+18 -19) Path.inc | 37 ++++++++++++++++++------------------- 1 files changed, 18 insertions(+), 19 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.37 llvm/lib/System/Win32/Path.inc:1.38 --- llvm/lib/System/Win32/Path.inc:1.37 Thu Jul 7 23:50:08 2005 +++ llvm/lib/System/Win32/Path.inc Fri Jul 8 00:02:13 2005 @@ -49,7 +49,7 @@ return false; rootslash = 2; } - + // Look for a UNC path, and if found adjust our notion of the root slash. if (len > 3 && path[0] == '/' && path[1] == '/') { rootslash = path.find('/', 2); @@ -63,7 +63,7 @@ "\027\030\031\032\033\034\035\036\037") != std::string::npos) return false; - + // Remove trailing slash, unless it's a root slash. if (len > rootslash+1 && path[len-1] == '/') path.erase(--len); @@ -157,14 +157,14 @@ at = delim + 1; delim = strchr(at, ';'); } - + if (*at != 0) if (tmpPath.set(std::string(at))) if (tmpPath.canRead()) Paths.push_back(tmpPath); } -void +void Path::GetSystemLibraryPaths(std::vector& Paths) { Paths.push_back(sys::Path("C:\\WINDOWS\\SYSTEM32")); Paths.push_back(sys::Path("C:\\WINDOWS")); @@ -246,7 +246,7 @@ return false; } -bool +bool Path::isBytecodeFile() const { std::string actualMagic; if (!getMagicNumber(actualMagic, 4)) @@ -364,11 +364,10 @@ WIN32_FIND_DATA fd; std::string searchpath = path; if (path.size() == 0 || searchpath[path.size()-1] == '/') - searchpath += "*"; + searchpath += "*"; else searchpath += "/*"; - - + HANDLE h = FindFirstFile(searchpath.c_str(), &fd); if (h == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) @@ -414,7 +413,7 @@ std::string save(path); if (!path.empty()) { size_t last = path.size() - 1; - if (path[last] != '/') + if (path[last] != '/') path += '/'; } path += name; @@ -453,7 +452,7 @@ if (dotpos != std::string::npos) { if (slashpos == std::string::npos || dotpos > slashpos) { path.erase(dotpos, path.size()-dotpos); - return true; + return true; } } return false; @@ -466,7 +465,7 @@ char *pathname = reinterpret_cast(_alloca(len+2)); path.copy(pathname, len); pathname[len] = 0; - + // Make sure it ends with a slash. if (len == 0 || pathname[len - 1] != '/') { pathname[len] = '/'; @@ -547,7 +546,7 @@ return true; } else /* isDirectory() */ { // If it doesn't exist, we're done. - if (!exists()) + if (!exists()) return true; char *pathname = reinterpret_cast(_alloca(path.length()+3)); @@ -576,8 +575,8 @@ if (strcmp(fd.cFileName, "..") == 0) continue; - Path aPath(path); - aPath.appendComponent(&fd.cFileName[0]); + Path aPath(path); + aPath.appendComponent(&fd.cFileName[0]); list.push_back(aPath); } while (FindNextFile(h, &fd)); @@ -588,7 +587,7 @@ ThrowError(path + ": Can't read directory: "); } - for (std::vector::iterator I = list.begin(); I != list.end(); + for (std::vector::iterator I = list.begin(); I != list.end(); ++I) { Path &aPath = *I; aPath.eraseFromDisk(true); @@ -637,7 +636,7 @@ bool Path::renamePathOnDisk(const Path& newName) { if (!MoveFile(path.c_str(), newName.c_str())) - ThrowError("Can't move '" + path + + ThrowError("Can't move '" + path + "' to '" + newName.path + "': "); return true; } @@ -693,16 +692,16 @@ return true; } -void +void sys::CopyFile(const sys::Path &Dest, const sys::Path &Src) { // Can't use CopyFile macro defined in Windows.h because it would mess up the // above line. We use the expansion it would have in a non-UNICODE build. if (!::CopyFileA(Src.c_str(), Dest.c_str(), false)) - ThrowError("Can't copy '" + Src.toString() + + ThrowError("Can't copy '" + Src.toString() + "' to '" + Dest.toString() + "': "); } -void +void Path::makeUnique(bool reuse_current) { if (reuse_current && !exists()) return; // File doesn't exist already, just use it! From lattner at cs.uiuc.edu Fri Jul 8 00:47:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Jul 2005 00:47:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp Message-ID: <200507080547.AAA14451@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ELFWriter.cpp updated: 1.2 -> 1.3 --- Log message: Add support for emitting a .data section and .bss section. Add support for emitting external and .bss symbols. --- Diffs of the changes: (+67 -22) ELFWriter.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 67 insertions(+), 22 deletions(-) Index: llvm/lib/CodeGen/ELFWriter.cpp diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.2 llvm/lib/CodeGen/ELFWriter.cpp:1.3 --- llvm/lib/CodeGen/ELFWriter.cpp:1.2 Thu Jul 7 02:02:20 2005 +++ llvm/lib/CodeGen/ELFWriter.cpp Fri Jul 8 00:47:00 2005 @@ -96,9 +96,22 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV, ELFSection &DataSection, ELFSection &BSSSection) { - // If this is an external global, emit it... - assert(GV->hasInitializer() && "FIXME: unimp"); + // If this is an external global, emit it now. TODO: Note that it would be + // better to ignore the symbol here and only add it to the symbol table if + // referenced. + if (!GV->hasInitializer()) { + ELFSym ExternalSym(GV); + ExternalSym.SetBind(ELFSym::STB_GLOBAL); + ExternalSym.SetType(ELFSym::STT_NOTYPE); + ExternalSym.SectionIdx = ELFSection::SHN_UNDEF; + SymbolTable.push_back(ExternalSym); + return; + } + const Type *GVType = (const Type*)GV->getType(); + unsigned Align = TM.getTargetData().getTypeAlignment(GVType); + unsigned Size = TM.getTargetData().getTypeSize(GVType); + // If this global has a zero initializer, it is part of the .bss or common // section. if (GV->getInitializer()->isNullValue()) { @@ -108,9 +121,8 @@ if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) { ELFSym CommonSym(GV); // Value for common symbols is the alignment required. - const Type *GVType = (const Type*)GV->getType(); - CommonSym.Value = TM.getTargetData().getTypeAlignment(GVType); - CommonSym.Size = TM.getTargetData().getTypeSize(GVType); + CommonSym.Value = Align; + CommonSym.Size = Size; CommonSym.SetBind(ELFSym::STB_GLOBAL); CommonSym.SetType(ELFSym::STT_OBJECT); // TODO SOMEDAY: add ELF visibility. @@ -119,7 +131,40 @@ return; } - // FIXME: Implement the .bss section. + // Otherwise, this symbol is part of the .bss section. Emit it now. + + // Handle alignment. Ensure section is aligned at least as much as required + // by this symbol. + BSSSection.Align = std::max(BSSSection.Align, Align); + + // Within the section, emit enough virtual padding to get us to an alignment + // boundary. + if (Align) + BSSSection.Size = (BSSSection.Size + Align - 1) & ~(Align-1); + + ELFSym BSSSym(GV); + BSSSym.Value = BSSSection.Size; + BSSSym.Size = Size; + BSSSym.SetType(ELFSym::STT_OBJECT); + + switch (GV->getLinkage()) { + default: // weak/linkonce handled above + assert(0 && "Unexpected linkage type!"); + case GlobalValue::AppendingLinkage: // FIXME: This should be improved! + case GlobalValue::ExternalLinkage: + BSSSym.SetBind(ELFSym::STB_GLOBAL); + break; + case GlobalValue::InternalLinkage: + BSSSym.SetBind(ELFSym::STB_LOCAL); + break; + } + + // Set the idx of the .bss section + BSSSym.SectionIdx = &BSSSection-&SectionList[0]; + SymbolTable.push_back(BSSSym); + + // Reserve space in the .bss section for this symbol. + BSSSection.Size += Size; return; } @@ -143,26 +188,26 @@ // Okay, the ELF header and .text sections have been completed, build the // .data, .bss, and "common" sections next. - ELFSection DataSection(".data", OutputBuffer.size()); - ELFSection BSSSection (".bss"); + SectionList.push_back(ELFSection(".data", OutputBuffer.size())); + SectionList.push_back(ELFSection(".bss")); + ELFSection &DataSection = *(SectionList.end()-2); + ELFSection &BSSSection = SectionList.back(); for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) EmitGlobal(I, DataSection, BSSSection); - // If the .data section is nonempty, add it to our list. - if (DataSection.Size) { - DataSection.Align = 4; // FIXME: Compute! - // FIXME: Set the right flags and stuff. - SectionList.push_back(DataSection); - } - - // If the .bss section is nonempty, add it to our list. - if (BSSSection.Size) { - BSSSection.Offset = OutputBuffer.size(); - BSSSection.Align = 4; // FIXME: Compute! - // FIXME: Set the right flags and stuff. - SectionList.push_back(BSSSection); - } + // Finish up the data section. + DataSection.Type = ELFSection::SHT_PROGBITS; + DataSection.Flags = ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC; + + // The BSS Section logically starts at the end of the Data Section (adjusted + // to the required alignment of the BSSSection). + BSSSection.Offset = DataSection.Offset+DataSection.Size; + BSSSection.Type = ELFSection::SHT_NOBITS; + BSSSection.Flags = ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC; + if (BSSSection.Align) + BSSSection.Offset = (BSSSection.Offset+BSSSection.Align-1) & + ~(BSSSection.Align-1); // Emit the symbol table now, if non-empty. EmitSymbolTable(); From reid at x10sys.com Fri Jul 8 01:03:01 2005 From: reid at x10sys.com (Reid Spencer) Date: Thu, 07 Jul 2005 23:03:01 -0700 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc In-Reply-To: <200507080449.XAA10262@zion.cs.uiuc.edu> References: <200507080449.XAA10262@zion.cs.uiuc.edu> Message-ID: <1120802581.725.80.camel@bashful.x10sys.com> Jeff, The contract the Path class makes with its users is that it will never permit a syntactically invalid path to be constructed. With this patch you have violated that guarantee. What was the objective of this patch? Reid. On Thu, 2005-07-07 at 23:49 -0500, Jeff Cohen wrote: > > Changes in directory llvm/lib/System/Unix: > > Path.inc updated: 1.38 -> 1.39 > --- > Log message: > > Fix eraseSuffix() > > --- > Diffs of the changes: (+6 -10) > > Path.inc | 16 ++++++---------- > 1 files changed, 6 insertions(+), 10 deletions(-) > > > Index: llvm/lib/System/Unix/Path.inc > diff -u llvm/lib/System/Unix/Path.inc:1.38 llvm/lib/System/Unix/Path.inc:1.39 > --- llvm/lib/System/Unix/Path.inc:1.38 Thu Jul 7 22:08:58 2005 > +++ llvm/lib/System/Unix/Path.inc Thu Jul 7 23:49:16 2005 > @@ -504,19 +504,15 @@ > > bool > Path::eraseSuffix() { > - std::string save(path); > size_t dotpos = path.rfind('.',path.size()); > size_t slashpos = path.rfind('/',path.size()); > - if (slashpos != std::string::npos && > - dotpos != std::string::npos && > - dotpos > slashpos) { > - path.erase(dotpos, path.size()-dotpos); > - } > - if (!isValid()) { > - path = save; > - return false; > + if (dotpos != std::string::npos) { > + if (slashpos == std::string::npos || dotpos > slashpos) { > + path.erase(dotpos, path.size()-dotpos); > + return true; > + } > } > - return true; > + return false; > } > > bool > > > > _______________________________________________ > 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/20050707/eddf61f8/attachment.bin From reid at x10sys.com Fri Jul 8 01:53:37 2005 From: reid at x10sys.com (Reid Spencer) Date: Fri, 8 Jul 2005 01:53:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Message-ID: <200507080653.BAA15022@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.40 -> 1.41 --- Log message: Two changes: 1. Use isValid() to check validity of the resulting path name in the eraseSuffix even though we can't think of a case where eraseSuffix could possibly cause an invalid path name. 2. Rewrite isValid() to not use the deprecated realpath function any more. It now just uses isascii to make sure all the characters are legit. --- Diffs of the changes: (+11 -7) Path.inc | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.40 llvm/lib/System/Unix/Path.inc:1.41 --- llvm/lib/System/Unix/Path.inc:1.40 Fri Jul 8 00:02:13 2005 +++ llvm/lib/System/Unix/Path.inc Fri Jul 8 01:53:26 2005 @@ -68,17 +68,18 @@ bool Path::isValid() const { + // Check some obvious things if (path.empty()) return false; else if (path.length() >= MAXPATHLEN) return false; -#if defined(HAVE_REALPATH) - char pathname[MAXPATHLEN]; - if (0 == realpath(path.c_str(), pathname)) - if (errno != EACCES && errno != EIO && errno != ENOENT && errno != ENOTDIR) - return false; -#endif - return true; + + // Check that the characters are ascii chars + size_t len = path.length(); + unsigned i = 0; + while (i < len && isascii(path[i])) + ++i; + return i >= len; } Path @@ -504,6 +505,7 @@ bool Path::eraseSuffix() { + std::string save = path; size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); if (dotpos != std::string::npos) { @@ -512,6 +514,8 @@ return true; } } + if (!isValid()) + path = save; return false; } From reid at x10sys.com Fri Jul 8 11:49:04 2005 From: reid at x10sys.com (Reid Spencer) Date: Fri, 8 Jul 2005 11:49:04 -0500 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200507081649.LAA12596@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.49 -> 1.50 --- Log message: Make sure we don't error out if an invalid path is used, just simply exit from isBytecodeLPath with "false". --- Diffs of the changes: (+12 -1) GenerateCode.cpp | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.49 llvm/tools/gccld/GenerateCode.cpp:1.50 --- llvm/tools/gccld/GenerateCode.cpp:1.49 Thu Jul 7 18:21:43 2005 +++ llvm/tools/gccld/GenerateCode.cpp Fri Jul 8 11:48:52 2005 @@ -154,9 +154,20 @@ sys::Path LPath(LibPath); + // Make sure it exists + if (!LPath.exists()) + return isBytecodeLPath; + // Make sure its a directory - if (!LPath.isDirectory()) + try + { + if (!LPath.isDirectory()) + return isBytecodeLPath; + } + catch (std::string& xcptn) + { return isBytecodeLPath; + } // Grab the contents of the -L path std::set Files; From reid at x10sys.com Fri Jul 8 12:46:21 2005 From: reid at x10sys.com (Reid Spencer) Date: Fri, 8 Jul 2005 12:46:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Message-ID: <200507081746.MAA12808@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.41 -> 1.42 --- Log message: Ensure that functions like isDirectory don't fail if the file doesn't exist but just return false instead. --- Diffs of the changes: (+13 -1) Path.inc | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.41 llvm/lib/System/Unix/Path.inc:1.42 --- llvm/lib/System/Unix/Path.inc:1.41 Fri Jul 8 01:53:26 2005 +++ llvm/lib/System/Unix/Path.inc Fri Jul 8 12:46:10 2005 @@ -231,6 +231,8 @@ bool Path::isFile() const { + if (!exists()) + return false; struct stat buf; if (0 != stat(path.c_str(), &buf)) { ThrowErrno(path + ": can't determine type of path object: "); @@ -240,6 +242,8 @@ bool Path::isDirectory() const { + if (!exists()) + return false; struct stat buf; if (0 != stat(path.c_str(), &buf)) { ThrowErrno(path + ": can't determine type of path object: "); @@ -249,6 +253,8 @@ bool Path::isHidden() const { + if (!exists()) + return false; size_t slash = path.rfind('/'); return (slash != std::string::npos && slash < path.length()-1 && @@ -269,6 +275,8 @@ } bool Path::hasMagicNumber(const std::string &Magic) const { + if (!isFile()) + return false; size_t len = Magic.size(); assert(len < 1024 && "Request for magic string too long"); char* buf = (char*) alloca(1 + len); @@ -303,6 +311,8 @@ bool Path::isBytecodeFile() const { + if (!isFile()) + return false; char buffer[ 4]; buffer[0] = 0; int fd = ::open(path.c_str(),O_RDONLY); @@ -334,11 +344,13 @@ bool Path::canExecute() const { + if (0 != access(path.c_str(), R_OK | X_OK )) + return false; struct stat st; int r = stat(path.c_str(), &st); if (r != 0 || !S_ISREG(st.st_mode)) return false; - return 0 == access(path.c_str(), R_OK | X_OK ); + return true; } std::string From reid at x10sys.com Fri Jul 8 12:46:21 2005 From: reid at x10sys.com (Reid Spencer) Date: Fri, 8 Jul 2005 12:46:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507081746.MAA12804@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.38 -> 1.39 --- Log message: Ensure that functions like isDirectory don't fail if the file doesn't exist but just return false instead. --- Diffs of the changes: (+6 -0) Path.inc | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.38 llvm/lib/System/Win32/Path.inc:1.39 --- llvm/lib/System/Win32/Path.inc:1.38 Fri Jul 8 00:02:13 2005 +++ llvm/lib/System/Win32/Path.inc Fri Jul 8 12:46:10 2005 @@ -213,6 +213,8 @@ bool Path::isDirectory() const { + if (!exists()) + return false; WIN32_FILE_ATTRIBUTE_DATA fi; if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) ThrowError(std::string(path) + ": Can't get status: "); @@ -221,6 +223,8 @@ bool Path::isHidden() const { + if (!exists()) + return false; WIN32_FILE_ATTRIBUTE_DATA fi; if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) ThrowError(std::string(path) + ": Can't get status: "); @@ -248,6 +252,8 @@ bool Path::isBytecodeFile() const { + if (!isFile()) + return false; std::string actualMagic; if (!getMagicNumber(actualMagic, 4)) return false; From jeffc at jolt-lang.org Sat Jul 9 13:42:13 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 9 Jul 2005 13:42:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Message-ID: <200507091842.NAA20496@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Path.inc updated: 1.42 -> 1.43 --- Log message: 1. Fix bug in getBaseName where it mishandles suffixes 2. Fix bug in eraseSuffix where it allows /path/.suffix to become /path/ --- Diffs of the changes: (+6 -2) Path.inc | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/System/Unix/Path.inc diff -u llvm/lib/System/Unix/Path.inc:1.42 llvm/lib/System/Unix/Path.inc:1.43 --- llvm/lib/System/Unix/Path.inc:1.42 Fri Jul 8 12:46:10 2005 +++ llvm/lib/System/Unix/Path.inc Sat Jul 9 13:42:02 2005 @@ -271,7 +271,11 @@ else slash++; - return path.substr(slash, path.rfind('.')); + size_t dot = path.rfind('.'); + if (dot == std::string::npos || dot < slash) + return path.substr(slash); + else + return path.substr(slash, dot - slash); } bool Path::hasMagicNumber(const std::string &Magic) const { @@ -521,7 +525,7 @@ size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); if (dotpos != std::string::npos) { - if (slashpos == std::string::npos || dotpos > slashpos) { + if (slashpos == std::string::npos || dotpos > slashpos+1) { path.erase(dotpos, path.size()-dotpos); return true; } From jeffc at jolt-lang.org Sat Jul 9 13:43:00 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 9 Jul 2005 13:43:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/Path.inc Message-ID: <200507091843.NAA20509@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: Path.inc updated: 1.39 -> 1.40 --- Log message: Fix bugs also fixed in Unix version, plus other general cleanup. --- Diffs of the changes: (+61 -17) Path.inc | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 61 insertions(+), 17 deletions(-) Index: llvm/lib/System/Win32/Path.inc diff -u llvm/lib/System/Win32/Path.inc:1.39 llvm/lib/System/Win32/Path.inc:1.40 --- llvm/lib/System/Win32/Path.inc:1.39 Fri Jul 8 12:46:10 2005 +++ llvm/lib/System/Win32/Path.inc Sat Jul 9 13:42:49 2005 @@ -25,6 +25,16 @@ // We need to undo a macro defined in Windows.h, otherwise we won't compile: #undef CopyFile +// Windows happily accepts either forward or backward slashes, though any path +// returned by a Win32 API will have backward slashes. As LLVM code basically +// assumes forward slashes are used, backward slashs are converted where they +// can be introduced into a path. +// +// Another invariant is that a path ends with a slash if and only if the path +// is a root directory. Any other use of a trailing slash is stripped. Unlike +// in Unix, Windows has a rather complicated notion of a root path and this +// invariant helps simply the code. + static void FlipBackSlashes(std::string& s) { for (size_t i = 0; i < s.size(); i++) if (s[i] == '\\') @@ -141,7 +151,7 @@ Path Path::GetRootDirectory() { Path result; - result.set("C:\\"); + result.set("C:/"); return result; } @@ -166,8 +176,8 @@ void Path::GetSystemLibraryPaths(std::vector& Paths) { - Paths.push_back(sys::Path("C:\\WINDOWS\\SYSTEM32")); - Paths.push_back(sys::Path("C:\\WINDOWS")); + Paths.push_back(sys::Path("C:/WINDOWS/SYSTEM32")); + Paths.push_back(sys::Path("C:/WINDOWS")); } void @@ -208,27 +218,41 @@ bool Path::isFile() const { - return !isDirectory(); + WIN32_FILE_ATTRIBUTE_DATA fi; + BOOL rc = GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi); + if (rc) + return !(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + else if (GetLastError() != ERROR_NOT_FOUND) + ThrowError(std::string(path) + ": Can't get status: "); + return false; } bool Path::isDirectory() const { - if (!exists()) - return false; WIN32_FILE_ATTRIBUTE_DATA fi; - if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + BOOL rc = GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi); + if (rc) + return fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + else if (GetLastError() != ERROR_NOT_FOUND) ThrowError(std::string(path) + ": Can't get status: "); - return fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + return false; } bool Path::isHidden() const { - if (!exists()) - return false; WIN32_FILE_ATTRIBUTE_DATA fi; - if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + BOOL rc = GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi); + if (rc) + return fi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN; + else if (GetLastError() != ERROR_NOT_FOUND) ThrowError(std::string(path) + ": Can't get status: "); - return fi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN; + return false; +} + +bool +Path::isRootDirectory() const { + size_t len = path.size(); + return len > 0 && path[len-1] == '/'; } std::string @@ -240,7 +264,11 @@ else slash++; - return path.substr(slash, path.rfind('.')); + size_t dot = path.rfind('.'); + if (dot == std::string::npos || dot < slash) + return path.substr(slash); + else + return path.substr(slash, dot - slash); } bool Path::hasMagicNumber(const std::string &Magic) const { @@ -435,7 +463,12 @@ size_t slashpos = path.rfind('/',path.size()); if (slashpos == path.size() - 1 || slashpos == std::string::npos) return false; + std::string save(path); path.erase(slashpos); + if (!isValid()) { + path = save; + return false; + } return true; } @@ -456,8 +489,13 @@ size_t dotpos = path.rfind('.',path.size()); size_t slashpos = path.rfind('/',path.size()); if (dotpos != std::string::npos) { - if (slashpos == std::string::npos || dotpos > slashpos) { + if (slashpos == std::string::npos || dotpos > slashpos+1) { + std::string save(path); path.erase(dotpos, path.size()-dotpos); + if (!isValid()) { + path = save; + return false; + } return true; } } @@ -550,7 +588,7 @@ if (!DeleteFile(path.c_str())) ThrowError(path + ": Can't destroy file: "); return true; - } else /* isDirectory() */ { + } else if (isDirectory()) { // If it doesn't exist, we're done. if (!exists()) return true; @@ -608,6 +646,9 @@ if (!RemoveDirectory(pathname)) ThrowError(std::string(pathname) + ": Can't destroy directory: "); return true; + } else { + // It appears the path doesn't exist. + return false; } } @@ -649,6 +690,7 @@ bool Path::setStatusInfoOnDisk(const StatusInfo& si) const { + // FIXME: should work on directories also. if (!isFile()) return false; HANDLE h = CreateFile(path.c_str(), @@ -717,7 +759,9 @@ unsigned offset = path.size(); path.copy(FNBuffer, offset); - // Find a numeric suffix that isn't used by an existing file. + // Find a numeric suffix that isn't used by an existing file. Assume there + // won't be more than 1 million files with the same prefix. Probably a safe + // bet. static unsigned FCounter = 0; do { sprintf(FNBuffer+offset, "-%06u", FCounter); @@ -730,7 +774,7 @@ bool Path::createTemporaryFileOnDisk(bool reuse_current) { // Make this into a unique file name - makeUnique( reuse_current ); + makeUnique(reuse_current); // Now go and create it HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, From lattner at cs.uiuc.edu Sat Jul 9 19:07:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:07:05 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h SelectionDAGNodes.h Message-ID: <200507100007.TAA01130@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.27 -> 1.28 SelectionDAGNodes.h updated: 1.41 -> 1.42 --- Log message: Introduce a new VTSDNode class with the ultimate goal of eliminating the MVTSDNode class. This class is used to provide an operand to operators that require an extra type. We start by converting FP_ROUND_INREG and SIGN_EXTEND_INREG over to using it. --- Diffs of the changes: (+26 -10) SelectionDAG.h | 2 ++ SelectionDAGNodes.h | 34 ++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.27 llvm/include/llvm/CodeGen/SelectionDAG.h:1.28 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.27 Sat May 14 02:36:02 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Sat Jul 9 19:06:54 2005 @@ -100,6 +100,7 @@ SDOperand getConstantPool(unsigned CPIdx, MVT::ValueType VT); SDOperand getBasicBlock(MachineBasicBlock *MBB); SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); + SDOperand getValueType(MVT::ValueType); SDOperand getCopyToReg(SDOperand Chain, SDOperand N, unsigned Reg) { // Note: these are auto-CSE'd because the caller doesn't make requests that @@ -225,6 +226,7 @@ std::map FrameIndices; std::map ConstantPoolIndices; std::map BBNodes; + std::vector ValueTypeNodes; std::map > >, SDNode*> OneResultNodes; Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.41 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.42 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.41 Sat May 14 01:19:11 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sat Jul 9 19:06:54 2005 @@ -55,7 +55,7 @@ // Various leaf nodes. Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool, - BasicBlock, ExternalSymbol, + BasicBlock, ExternalSymbol, VALUETYPE, // CopyToReg - This node has chain and child nodes, and an associated // register number. The instruction selector must guarantee that the value @@ -148,8 +148,8 @@ // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to // sign extend a small value in a large integer register (e.g. sign // extending the low 8 bits of a 32-bit register to fill the top 24 bits - // with the 7th bit). The size of the smaller type is indicated by the - // ExtraValueType in the MVTSDNode for the operator. + // with the 7th bit). The size of the smaller type is indicated by the 1th + // operand, a ValueType node. SIGN_EXTEND_INREG, // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned @@ -164,8 +164,8 @@ // FP_ROUND_INREG - This operator takes a floating point register, and // rounds it to a floating point value. It then promotes it and returns it // in a register of the same size. This operation effectively just discards - // excess precision. The type to round down to is specified by the - // ExtraValueType in the MVTSDNode (currently always 64->32->64). + // excess precision. The type to round down to is specified by the 1th + // operation, a VTSDNode (currently always 64->32->64). FP_ROUND_INREG, // FP_EXTEND - Extend a smaller FP type into a larger FP type. @@ -843,6 +843,25 @@ } }; +/// VTSDNode - This class is used to represent MVT::ValueType's, which are used +/// to parameterize some operations. +class VTSDNode : public SDNode { + MVT::ValueType ValueType; +protected: + friend class SelectionDAG; + VTSDNode(MVT::ValueType VT) + : SDNode(ISD::VALUETYPE, MVT::Other), ValueType(VT) {} +public: + + MVT::ValueType getVT() const { return ValueType; } + + static bool classof(const VTSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::VALUETYPE; + } +}; + + /// MVTSDNode - This class is used for operators that require an extra /// value-type to be kept with the node. class MVTSDNode : public SDNode { @@ -871,8 +890,6 @@ static bool classof(const MVTSDNode *) { return true; } static bool classof(const SDNode *N) { return - N->getOpcode() == ISD::SIGN_EXTEND_INREG || - N->getOpcode() == ISD::FP_ROUND_INREG || N->getOpcode() == ISD::EXTLOAD || N->getOpcode() == ISD::SEXTLOAD || N->getOpcode() == ISD::ZEXTLOAD || @@ -931,9 +948,6 @@ } }; - - - } // end llvm namespace #endif From lattner at cs.uiuc.edu Sat Jul 9 19:07:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:07:22 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200507100007.TAA01145@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.135 -> 1.136 SelectionDAG.cpp updated: 1.122 -> 1.123 --- Log message: Introduce a new VTSDNode class with the ultimate goal of eliminating the MVTSDNode class. This class is used to provide an operand to operators that require an extra type. We start by converting FP_ROUND_INREG and SIGN_EXTEND_INREG over to using it. --- Diffs of the changes: (+109 -79) LegalizeDAG.cpp | 47 +++++++++++------- SelectionDAG.cpp | 141 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 109 insertions(+), 79 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.135 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.136 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.135 Tue Jul 5 14:52:39 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jul 9 19:07:11 2005 @@ -539,7 +539,7 @@ SDOperand ValRes; if (Node->getOpcode() == ISD::SEXTLOAD) ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), - Result, SrcVT); + Result, DAG.getValueType(SrcVT)); else ValRes = DAG.getZeroExtendInReg(Result, SrcVT); AddLegalizedOperand(SDOperand(Node, 0), ValRes); @@ -808,8 +808,10 @@ case ISD::SETGT: case ISD::SETLT: case ISD::SETLE: - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, VT); + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + DAG.getValueType(VT)); + Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, + DAG.getValueType(VT)); break; } @@ -1403,7 +1405,8 @@ // NOTE: Any extend would work here... Result = DAG.getNode(ISD::ZERO_EXTEND, Op.getValueType(), Result); Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), - Result, Node->getOperand(0).getValueType()); + Result, + DAG.getValueType(Node->getOperand(0).getValueType())); break; case ISD::TRUNCATE: Result = PromoteOp(Node->getOperand(0)); @@ -1424,7 +1427,8 @@ case ISD::SINT_TO_FP: Result = PromoteOp(Node->getOperand(0)); Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), - Result, Node->getOperand(0).getValueType()); + Result, + DAG.getValueType(Node->getOperand(0).getValueType())); Result = DAG.getNode(ISD::SINT_TO_FP, Op.getValueType(), Result); break; case ISD::UINT_TO_FP: @@ -1439,7 +1443,7 @@ case ISD::FP_ROUND_INREG: case ISD::SIGN_EXTEND_INREG: { Tmp1 = LegalizeOp(Node->getOperand(0)); - MVT::ValueType ExtraVT = cast(Node)->getExtraValueType(); + MVT::ValueType ExtraVT = cast(Node->getOperand(1))->getVT(); // If this operation is not supported, convert it to a shl/shr or load/store // pair. @@ -1593,7 +1597,7 @@ // The high bits are not guaranteed to be anything. Insert an extend. if (Node->getOpcode() == ISD::SIGN_EXTEND) Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result, - Node->getOperand(0).getValueType()); + DAG.getValueType(Node->getOperand(0).getValueType())); else Result = DAG.getZeroExtendInReg(Result, Node->getOperand(0).getValueType()); @@ -1610,7 +1614,8 @@ case Legal: // Input is legal? Do an FP_ROUND_INREG. Result = LegalizeOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); break; } break; @@ -1628,7 +1633,8 @@ Result = PromoteOp(Node->getOperand(0)); if (Node->getOpcode() == ISD::SINT_TO_FP) Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), - Result, Node->getOperand(0).getValueType()); + Result, + DAG.getValueType(Node->getOperand(0).getValueType())); else Result = DAG.getZeroExtendInReg(Result, Node->getOperand(0).getValueType()); @@ -1640,7 +1646,8 @@ Node->getOperand(0)); // Round if we cannot tolerate excess precision. if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); break; } break; @@ -1679,7 +1686,8 @@ assert(Tmp1.getValueType() == NVT); Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1); if(NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); break; case ISD::AND: @@ -1702,7 +1710,8 @@ // FIXME: Why would we need to round FP ops more than integer ones? // Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C)) if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); break; case ISD::SDIV: @@ -1711,14 +1720,17 @@ Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); if (MVT::isInteger(NVT)) { - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, VT); + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + DAG.getValueType(VT)); + Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, + DAG.getValueType(VT)); } Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); // Perform FP_ROUND: this is probably overly pessimistic. if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT); + Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + DAG.getValueType(VT)); break; case ISD::UDIV: @@ -1740,7 +1752,8 @@ case ISD::SRA: // The input value must be properly sign extended. Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, VT); + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + DAG.getValueType(VT)); Tmp2 = LegalizeOp(Node->getOperand(1)); Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Tmp2); break; @@ -2520,7 +2533,7 @@ In = PromoteOp(Node->getOperand(0)); // Emit the appropriate sign_extend_inreg to get the value we want. In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), In, - Node->getOperand(0).getValueType()); + DAG.getValueType(Node->getOperand(0).getValueType())); break; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.122 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.123 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.122 Wed Jun 29 13:54:02 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jul 9 19:07:11 2005 @@ -220,7 +220,9 @@ case ISD::ExternalSymbol: ExternalSymbols.erase(cast(N)->getSymbol()); break; - + case ISD::VALUETYPE: + ValueTypeNodes[cast(N)->getVT()] = 0; + break; case ISD::LOAD: Loads.erase(std::make_pair(N->getOperand(1), std::make_pair(N->getOperand(0), @@ -234,8 +236,6 @@ N->getValueType(0)))); break; case ISD::TRUNCSTORE: - case ISD::SIGN_EXTEND_INREG: - case ISD::FP_ROUND_INREG: case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { @@ -374,6 +374,17 @@ return SDOperand(N, 0); } +SDOperand SelectionDAG::getValueType(MVT::ValueType VT) { + if ((unsigned)VT >= ValueTypeNodes.size()) + ValueTypeNodes.resize(VT+1); + if (ValueTypeNodes[VT] == 0) { + ValueTypeNodes[VT] = new VTSDNode(VT); + AllNodes.push_back(ValueTypeNodes[VT]); + } + + return SDOperand(ValueTypeNodes[VT], 0); +} + SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) { SDNode *&N = ExternalSymbols[Sym]; if (N) return SDOperand(N, 0); @@ -864,6 +875,22 @@ assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) && VT != MVT::i1 && "Shifts only work on integers"); break; + case ISD::FP_ROUND_INREG: { + MVT::ValueType EVT = cast(N2)->getVT(); + assert(VT == N1.getValueType() && "Not an inreg round!"); + assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) && + "Cannot FP_ROUND_INREG integer types"); + assert(EVT <= VT && "Not rounding down!"); + break; + } + case ISD::SIGN_EXTEND_INREG: { + MVT::ValueType EVT = cast(N2)->getVT(); + assert(VT == N1.getValueType() && "Not an inreg extend!"); + assert(MVT::isInteger(VT) && MVT::isInteger(EVT) && + "Cannot *_EXTEND_INREG FP types"); + assert(EVT <= VT && "Not extending!"); + } + default: break; } #endif @@ -918,6 +945,10 @@ case ISD::SRA: // sra -1, X -> -1 if (N1C->isAllOnesValue()) return N1; break; + case ISD::SIGN_EXTEND_INREG: // SIGN_EXTEND_INREG N1C, EVT + // Extending a constant? Just return the extended constant. + SDOperand Tmp = getNode(ISD::TRUNCATE, cast(N2)->getVT(), N1); + return getNode(ISD::SIGN_EXTEND, VT, Tmp); } } @@ -1026,7 +1057,7 @@ // If we are masking out the part of our input that was extended, just // mask the input to the extension directly. unsigned ExtendBits = - MVT::getSizeInBits(cast(N1)->getExtraValueType()); + MVT::getSizeInBits(cast(N1.getOperand(1))->getVT()); if ((C2 & (~0ULL << ExtendBits)) == 0) return getNode(ISD::AND, VT, N1.getOperand(0), N2); } @@ -1072,7 +1103,7 @@ ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); ConstantFPSDNode *N2CFP = dyn_cast(N2.Val); - if (N1CFP) + if (N1CFP) { if (N2CFP) { double C1 = N1CFP->getValue(), C2 = N2CFP->getValue(); switch (Opcode) { @@ -1095,6 +1126,11 @@ } } + if (Opcode == ISD::FP_ROUND_INREG) + return getNode(ISD::FP_EXTEND, VT, + getNode(ISD::FP_ROUND, cast(N2)->getVT(), N1)); + } + // Finally, fold operations that do not require constants. switch (Opcode) { case ISD::TokenFactor: @@ -1199,6 +1235,42 @@ if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B return getNode(ISD::ADD, VT, N1, N2.getOperand(0)); break; + case ISD::FP_ROUND_INREG: + if (cast(N2)->getVT() == VT) return N1; // Not actually rounding. + break; + case ISD::SIGN_EXTEND_INREG: { + MVT::ValueType EVT = cast(N2)->getVT(); + if (EVT == VT) return N1; // Not actually extending + + // If we are sign extending an extension, use the original source. + if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) + if (cast(N1.getOperand(1))->getVT() <= EVT) + return N1; + + // If we are sign extending a sextload, return just the load. + if (N1.getOpcode() == ISD::SEXTLOAD) + if (cast(N1)->getExtraValueType() <= EVT) + return N1; + + // If we are extending the result of a setcc, and we already know the + // contents of the top bits, eliminate the extension. + if (N1.getOpcode() == ISD::SETCC && + TLI.getSetCCResultContents() == + TargetLowering::ZeroOrNegativeOneSetCCResult) + return N1; + + // If we are sign extending the result of an (and X, C) operation, and we + // know the extended bits are zeros already, don't do the extend. + if (N1.getOpcode() == ISD::AND) + if (ConstantSDNode *N1C = dyn_cast(N1.getOperand(1))) { + uint64_t Mask = N1C->getValue(); + unsigned NumBits = MVT::getSizeInBits(EVT); + if ((Mask & (~0ULL << (NumBits-1))) == 0) + return N1; + } + break; + } + // FIXME: figure out how to safely handle things like // int foo(int x) { return 1 << (x & 255); } // int bar() { return foo(256); } @@ -1207,7 +1279,7 @@ case ISD::SRL: case ISD::SRA: if (N2.getOpcode() == ISD::SIGN_EXTEND_INREG && - cast(N2)->getExtraValueType() != MVT::i1) + cast(N2.getOperand(1))->getVT() != MVT::i1) return getNode(Opcode, VT, N1, N2.getOperand(0)); else if (N2.getOpcode() == ISD::AND) if (ConstantSDNode *AndRHS = dyn_cast(N2.getOperand(1))) { @@ -1450,7 +1522,7 @@ case ISD::SRL_PARTS: case ISD::SHL_PARTS: if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG && - cast(N3)->getExtraValueType() != MVT::i1) + cast(N3.getOperand(1))->getVT() != MVT::i1) return getNode(Opcode, VT, N1, N2, N3.getOperand(0)); else if (N3.getOpcode() == ISD::AND) if (ConstantSDNode *AndRHS = dyn_cast(N3.getOperand(1))) { @@ -1477,61 +1549,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, MVT::ValueType EVT) { - - switch (Opcode) { - default: assert(0 && "Bad opcode for this accessor!"); - case ISD::FP_ROUND_INREG: - assert(VT == N1.getValueType() && "Not an inreg round!"); - assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) && - "Cannot FP_ROUND_INREG integer types"); - if (EVT == VT) return N1; // Not actually rounding - assert(EVT < VT && "Not rounding down!"); - - if (isa(N1)) - return getNode(ISD::FP_EXTEND, VT, getNode(ISD::FP_ROUND, EVT, N1)); - break; - case ISD::SIGN_EXTEND_INREG: - assert(VT == N1.getValueType() && "Not an inreg extend!"); - assert(MVT::isInteger(VT) && MVT::isInteger(EVT) && - "Cannot *_EXTEND_INREG FP types"); - if (EVT == VT) return N1; // Not actually extending - assert(EVT < VT && "Not extending!"); - - // Extending a constant? Just return the extended constant. - if (ConstantSDNode *N1C = dyn_cast(N1.Val)) { - SDOperand Tmp = getNode(ISD::TRUNCATE, EVT, N1); - return getNode(ISD::SIGN_EXTEND, VT, Tmp); - } - - // If we are sign extending an extension, use the original source. - if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) - if (cast(N1)->getExtraValueType() <= EVT) - return N1; - - // If we are sign extending a sextload, return just the load. - if (N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG) - if (cast(N1)->getExtraValueType() <= EVT) - return N1; - - // If we are extending the result of a setcc, and we already know the - // contents of the top bits, eliminate the extension. - if (N1.getOpcode() == ISD::SETCC && - TLI.getSetCCResultContents() == - TargetLowering::ZeroOrNegativeOneSetCCResult) - return N1; - - // If we are sign extending the result of an (and X, C) operation, and we - // know the extended bits are zeros already, don't do the extend. - if (N1.getOpcode() == ISD::AND) - if (ConstantSDNode *N1C = dyn_cast(N1.getOperand(1))) { - uint64_t Mask = N1C->getValue(); - unsigned NumBits = MVT::getSizeInBits(EVT); - if ((Mask & (~0ULL << (NumBits-1))) == 0) - return N1; - } - break; - } - EVTStruct NN; NN.Opcode = Opcode; NN.VT = VT; From lattner at cs.uiuc.edu Sat Jul 9 19:28:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:28:36 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h SelectionDAGNodes.h Message-ID: <200507100028.TAA11421@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.28 -> 1.29 SelectionDAGNodes.h updated: 1.42 -> 1.43 --- Log message: Move TRUNCSTORE to using a VTSDNode operand instead of being a MVTSDNode. Also update some comments that Andrew forgot to update when he changed loads/stores. --- Diffs of the changes: (+9 -15) SelectionDAG.h | 6 +++--- SelectionDAGNodes.h | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.28 llvm/include/llvm/CodeGen/SelectionDAG.h:1.29 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.28 Sat Jul 9 19:06:54 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Sat Jul 9 19:28:25 2005 @@ -171,6 +171,9 @@ SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4); SDOperand getNode(unsigned Opcode, MVT::ValueType VT, + SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, + SDOperand N5); + SDOperand getNode(unsigned Opcode, MVT::ValueType VT, std::vector &Children); SDOperand getNode(unsigned Opcode, std::vector &ResultTys, std::vector &Ops); @@ -183,9 +186,6 @@ SDOperand N, MVT::ValueType EVT); SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3, MVT::ValueType EVT); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, - SDOperand N2, SDOperand N3, SDOperand N4, - MVT::ValueType EVT); /// getLoad - Loads are not normal binary operators: their result type is not Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.42 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.43 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.42 Sat Jul 9 19:06:54 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sat Jul 9 19:28:25 2005 @@ -176,7 +176,8 @@ FNEG, FABS, FSQRT, FSIN, FCOS, // Other operators. LOAD and STORE have token chains as their first - // operand, then the same operands as an LLVM load/store instruction. + // operand, then the same operands as an LLVM load/store instruction, then a + // SRCVALUE node that provides alias analysis information. LOAD, STORE, // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators are instances of the @@ -197,9 +198,9 @@ // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a // value and stores it to memory in one operation. This can be used for - // either integer or floating point operands, and the stored type - // represented as the 'extra' value type in the MVTSDNode representing the - // operator. This node has the same three operands as a standard store. + // either integer or floating point operands. The first four operands of + // this are the same as a standard store. The fifth is the ValueType to + // store it as (which will be smaller than the source value). TRUNCSTORE, // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned @@ -877,12 +878,6 @@ : SDNode(Opc, Op0, Op1, Op2), ExtraValueType(EVT) { setValueTypes(VT1, VT2); } - - MVTSDNode(unsigned Opc, MVT::ValueType VT, - SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3, MVT::ValueType EVT) - : SDNode(Opc, Op0, Op1, Op2, Op3), ExtraValueType(EVT) { - setValueTypes(VT); - } public: MVT::ValueType getExtraValueType() const { return ExtraValueType; } @@ -892,8 +887,7 @@ return N->getOpcode() == ISD::EXTLOAD || N->getOpcode() == ISD::SEXTLOAD || - N->getOpcode() == ISD::ZEXTLOAD || - N->getOpcode() == ISD::TRUNCSTORE; + N->getOpcode() == ISD::ZEXTLOAD; } }; From lattner at cs.uiuc.edu Sat Jul 9 19:29:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200507100029.TAA11439@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.136 -> 1.137 SelectionDAG.cpp updated: 1.123 -> 1.124 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+38 -46) LegalizeDAG.cpp | 7 ++--- SelectionDAG.cpp | 77 +++++++++++++++++++++++++------------------------------ 2 files changed, 38 insertions(+), 46 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.136 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.137 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.136 Sat Jul 9 19:07:11 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jul 9 19:29:03 2005 @@ -679,7 +679,7 @@ Tmp3 = PromoteOp(Node->getOperand(1)); Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp3, Tmp2, Node->getOperand(3), - Node->getOperand(1).getValueType()); + DAG.getValueType(Node->getOperand(1).getValueType())); break; case Expand: @@ -718,8 +718,7 @@ if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) || Tmp3 != Node->getOperand(2)) Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3, - Node->getOperand(3), - cast(Node)->getExtraValueType()); + Node->getOperand(3), Node->getOperand(4)); break; case Promote: case Expand: @@ -1482,7 +1481,7 @@ SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, DAG.getEntryNode(), Node->getOperand(0), StackSlot, - DAG.getSrcValue(NULL), ExtraVT); + DAG.getSrcValue(NULL), DAG.getValueType(ExtraVT)); Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), Result, StackSlot, DAG.getSrcValue(NULL), ExtraVT); } else { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.123 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.124 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.123 Sat Jul 9 19:07:11 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jul 9 19:29:03 2005 @@ -235,7 +235,6 @@ cast(N)->getCondition(), N->getValueType(0)))); break; - case ISD::TRUNCSTORE: case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { @@ -1465,6 +1464,20 @@ return getNode(Opcode, VT, Ops); } +SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, + SDOperand N1, SDOperand N2, SDOperand N3, + SDOperand N4, SDOperand N5) { + std::vector Ops; + Ops.reserve(5); + Ops.push_back(N1); + Ops.push_back(N2); + Ops.push_back(N3); + Ops.push_back(N4); + Ops.push_back(N5); + return getNode(Opcode, VT, Ops); +} + + SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { assert((!V || isa(V->getType())) && "SrcValue is not a pointer?"); @@ -1496,6 +1509,27 @@ else // Unconditional branch to false dest. return getNode(ISD::BR, MVT::Other, Ops[0], Ops[3]); break; + + case ISD::TRUNCSTORE: { + assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!"); + MVT::ValueType EVT = cast(Ops[4])->getVT(); +#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store + // If this is a truncating store of a constant, convert to the desired type + // and store it instead. + if (isa(Ops[0])) { + SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1); + if (isa(Op)) + N1 = Op; + } + // Also for ConstantFP? +#endif + if (Ops[0].getValueType() == EVT) // Normal store? + return getNode(ISD::STORE, VT, Ops[0], Ops[1], Ops[2], Ops[3]); + assert(Ops[1].getValueType() > EVT && "Not a truncation?"); + assert(MVT::isInteger(Ops[1].getValueType()) == MVT::isInteger(EVT) && + "Can't do FP-INT conversion!"); + break; + } } // Memoize nodes. @@ -1596,47 +1630,6 @@ return SDOperand(N, 0); } -SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, - SDOperand N2, SDOperand N3, SDOperand N4, - MVT::ValueType EVT) { - switch (Opcode) { - default: assert(0 && "Bad opcode for this accessor!"); - case ISD::TRUNCSTORE: -#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store - // If this is a truncating store of a constant, convert to the desired type - // and store it instead. - if (isa(N1)) { - SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1); - if (isa(Op)) - N1 = Op; - } - // Also for ConstantFP? -#endif - if (N1.getValueType() == EVT) // Normal store? - return getNode(ISD::STORE, VT, N1, N2, N3, N4); - assert(N2.getValueType() > EVT && "Not a truncation?"); - assert(MVT::isInteger(N2.getValueType()) == MVT::isInteger(EVT) && - "Can't do FP-INT conversion!"); - break; - } - - EVTStruct NN; - NN.Opcode = Opcode; - NN.VT = VT; - NN.EVT = EVT; - NN.Ops.push_back(N1); - NN.Ops.push_back(N2); - NN.Ops.push_back(N3); - NN.Ops.push_back(N4); - - SDNode *&N = MVTSDNodes[NN]; - if (N) return SDOperand(N, 0); - N = new MVTSDNode(Opcode, VT, N1, N2, N3, N4, EVT); - AllNodes.push_back(N); - return SDOperand(N, 0); -} - - /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. From lattner at cs.uiuc.edu Sat Jul 9 19:29:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200507100029.TAA11459@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.148 -> 1.149 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+6 -4) AlphaISelPattern.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.148 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.149 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.148 Thu Jul 7 14:52:58 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Sat Jul 9 19:29:16 2005 @@ -419,7 +419,7 @@ DAG.getConstant(8, MVT::i64)); return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, DAG.getConstant(VarArgsOffset, MVT::i64), SA2, - DAG.getSrcValue(VAListV, 8), MVT::i32); + DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32)); } std::pair AlphaTargetLowering:: @@ -457,7 +457,8 @@ DAG.getConstant(8, MVT::i64)); SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Result.getValue(1), NewOffset, - Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); + Tmp, DAG.getSrcValue(VAListV, 8), + DAG.getValueType(MVT::i32)); Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); return std::make_pair(Result, Update); @@ -478,7 +479,8 @@ SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, DAG.getConstant(8, MVT::i64)); return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), - Val, NPD, DAG.getSrcValue(DestV, 8), MVT::i32); + Val, NPD, DAG.getSrcValue(DestV, 8), + DAG.getValueType(MVT::i32)); } namespace { @@ -2283,7 +2285,7 @@ case MVT::f32: Opc = Alpha::STS; break; } } else { //ISD::TRUNCSTORE - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(4))->getVT()) { default: assert(0 && "unknown Type in store"); case MVT::i1: //FIXME: DAG does not promote this load case MVT::i8: Opc = Alpha::STB; break; From lattner at cs.uiuc.edu Sat Jul 9 19:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200507100029.TAA11475@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.47 -> 1.48 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+1 -1) IA64ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.47 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.48 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.47 Tue Jul 5 14:58:53 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Sat Jul 9 19:29:18 2005 @@ -2361,7 +2361,7 @@ case MVT::f64: Opc = IA64::STF8; break; } } else { // truncstore - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(4))->getVT()) { default: assert(0 && "unknown type in truncstore"); case MVT::i1: Opc = IA64::ST1; isBool=true; break; //FIXME: DAG does not promote this load? From lattner at cs.uiuc.edu Sat Jul 9 19:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507100029.TAA11489@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.147 -> 1.148 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+4 -5) X86ISelPattern.cpp | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.147 llvm/lib/Target/X86/X86ISelPattern.cpp:1.148 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.147 Thu Jul 7 12:12:53 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sat Jul 9 19:29:18 2005 @@ -4009,7 +4009,7 @@ StoreVT = Chain.getOperand(1).getValueType(); break; case ISD::TRUNCSTORE: // FLOAT store - StoreVT = cast(Chain)->getExtraValueType(); + StoreVT = cast(Chain.getOperand(4))->getVT(); break; } @@ -4043,7 +4043,7 @@ FIN); assert(Chain.getOpcode() == ISD::TRUNCSTORE); return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, InChain, Chain.getOperand(1), - FIN, DAG.getSrcValue(NULL), StoreVT); + FIN, DAG.getSrcValue(NULL), DAG.getValueType(StoreVT)); } @@ -4366,10 +4366,9 @@ SelectExpr(N.getValue(0)); return; - case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety - // On X86, we can represent all types except for Bool and Float natively. + case ISD::TRUNCSTORE: { // truncstore chain, val, ptr, SRCVALUE, storety X86AddressMode AM; - MVT::ValueType StoredTy = cast(Node)->getExtraValueType(); + MVT::ValueType StoredTy = cast(N.getOperand(4))->getVT(); assert((StoredTy == MVT::i1 || StoredTy == MVT::f32 || StoredTy == MVT::i16 /*FIXME: THIS IS JUST FOR TESTING!*/) && "Unsupported TRUNCSTORE for this target!"); From lattner at cs.uiuc.edu Sat Jul 9 19:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC64ISelPattern.cpp Message-ID: <200507100029.TAA11481@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.97 -> 1.98 PPC64ISelPattern.cpp updated: 1.23 -> 1.24 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+2 -2) PPC32ISelPattern.cpp | 2 +- PPC64ISelPattern.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.97 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.98 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.97 Tue Jul 5 14:58:53 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Jul 9 19:29:18 2005 @@ -2530,7 +2530,7 @@ case MVT::f32: Opc = PPC::STFS; break; } } else { //ISD::TRUNCSTORE - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(4))->getVT()) { default: assert(0 && "unknown Type in store"); case MVT::i1: case MVT::i8: Opc = PPC::STB; break; Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.23 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.24 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.23 Wed Jun 22 16:04:42 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Sat Jul 9 19:29:18 2005 @@ -1593,7 +1593,7 @@ case MVT::f32: Opc = PPC::STFS; break; } } else { //ISD::TRUNCSTORE - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(4))->getVT()) { default: assert(0 && "unknown Type in store"); case MVT::i1: //FIXME: DAG does not promote this load case MVT::i8: Opc= PPC::STB; break; From lattner at cs.uiuc.edu Sat Jul 9 19:29:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 19:29:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp Message-ID: <200507100029.TAA11485@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelPattern.cpp updated: 1.2 -> 1.3 --- Log message: Change TRUNCSTORE to use a VTSDNode operand instead of being an MVTSTDNode --- Diffs of the changes: (+1 -1) SparcV8ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.2 llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.3 --- llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.2 Mon Jun 27 18:59:51 2005 +++ llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp Sat Jul 9 19:29:18 2005 @@ -489,7 +489,7 @@ Tmp2 = SelectExpr(Address); unsigned VT = opcode == ISD::STORE ? - Value.getValueType() : cast(Node)->getExtraValueType(); + Value.getValueType() : cast(Node->getOperand(4))->getVT(); switch(VT) { default: assert(0 && "unknown Type in store"); case MVT::f64: Opc = V8::STDFrr; break; From lattner at cs.uiuc.edu Sat Jul 9 20:55:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:55:25 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h SelectionDAGNodes.h Message-ID: <200507100155.UAA30817@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.29 -> 1.30 SelectionDAGNodes.h updated: 1.43 -> 1.44 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. --- Diffs of the changes: (+8 -59) SelectionDAG.h | 29 +++-------------------------- SelectionDAGNodes.h | 38 +++++--------------------------------- 2 files changed, 8 insertions(+), 59 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.29 llvm/include/llvm/CodeGen/SelectionDAG.h:1.30 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.29 Sat Jul 9 19:28:25 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Sat Jul 9 20:55:14 2005 @@ -178,21 +178,14 @@ SDOperand getNode(unsigned Opcode, std::vector &ResultTys, std::vector &Ops); - // getNode - These versions take an extra value type for extending and - // truncating loads, stores, rounds, extends etc. - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, - SDOperand N2, MVT::ValueType EVT); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - SDOperand N, MVT::ValueType EVT); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, - SDOperand N2, SDOperand N3, MVT::ValueType EVT); - /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV); + SDOperand getExtLoad(unsigned Opcode, MVT::ValueType VT, SDOperand Chain, + SDOperand Ptr, SDOperand SV, MVT::ValueType EVT); // getSrcValue - construct a node to track a Value* through the backend SDOperand getSrcValue(const Value* I, int offset = 0); @@ -227,6 +220,7 @@ std::map ConstantPoolIndices; std::map BBNodes; std::vector ValueTypeNodes; + std::map ExternalSymbols; std::map > >, SDNode*> OneResultNodes; @@ -234,23 +228,6 @@ std::pair, std::vector > >, SDNode*> ArbitraryNodes; - - std::map ExternalSymbols; - struct EVTStruct { - unsigned Opcode; - MVT::ValueType VT, EVT; - std::vector Ops; - bool operator<(const EVTStruct &RHS) const { - if (Opcode < RHS.Opcode) return true; - if (Opcode > RHS.Opcode) return false; - if (VT < RHS.VT) return true; - if (VT > RHS.VT) return false; - if (EVT < RHS.EVT) return true; - if (EVT > RHS.EVT) return false; - return Ops < RHS.Ops; - } - }; - std::map MVTSDNodes; }; template <> struct GraphTraits : public GraphTraits { Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.43 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.44 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.43 Sat Jul 9 19:28:25 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sat Jul 9 20:55:14 2005 @@ -180,11 +180,11 @@ // SRCVALUE node that provides alias analysis information. LOAD, STORE, - // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators are instances of the - // MVTSDNode. All of these load a value from memory and extend them to a - // larger value (e.g. load a byte into a word register). All three of these - // have two operands, a chain and a pointer to load from. The extra value - // type is the source type being loaded. + // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from + // memory and extend them to a larger value (e.g. load a byte into a word + // register). All three of these have four operands, a token chain, a + // pointer to load from, a SRCVALUE for alias analysis, and a VALUETYPE node + // indicating the type to load. // // SEXTLOAD loads the integer operand and sign extends it to a larger // integer result type. @@ -863,34 +863,6 @@ }; -/// MVTSDNode - This class is used for operators that require an extra -/// value-type to be kept with the node. -class MVTSDNode : public SDNode { - MVT::ValueType ExtraValueType; -protected: - friend class SelectionDAG; - MVTSDNode(unsigned Opc, MVT::ValueType VT1, SDOperand Op0, MVT::ValueType EVT) - : SDNode(Opc, Op0), ExtraValueType(EVT) { - setValueTypes(VT1); - } - MVTSDNode(unsigned Opc, MVT::ValueType VT1, MVT::ValueType VT2, - SDOperand Op0, SDOperand Op1, SDOperand Op2, MVT::ValueType EVT) - : SDNode(Opc, Op0, Op1, Op2), ExtraValueType(EVT) { - setValueTypes(VT1, VT2); - } -public: - - MVT::ValueType getExtraValueType() const { return ExtraValueType; } - - static bool classof(const MVTSDNode *) { return true; } - static bool classof(const SDNode *N) { - return - N->getOpcode() == ISD::EXTLOAD || - N->getOpcode() == ISD::SEXTLOAD || - N->getOpcode() == ISD::ZEXTLOAD; - } -}; - class SDNodeIterator : public forward_iterator { SDNode *Node; unsigned Operand; From lattner at cs.uiuc.edu Sat Jul 9 20:55:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:55:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGPrinter.cpp Message-ID: <200507100155.UAA31046@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.137 -> 1.138 SelectionDAG.cpp updated: 1.124 -> 1.125 SelectionDAGPrinter.cpp updated: 1.11 -> 1.12 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. --- Diffs of the changes: (+60 -90) LegalizeDAG.cpp | 42 +++++++++---------- SelectionDAG.cpp | 106 +++++++++++++++++------------------------------- SelectionDAGPrinter.cpp | 2 3 files changed, 60 insertions(+), 90 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.137 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.138 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.137 Sat Jul 9 19:29:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jul 9 20:55:33 2005 @@ -317,8 +317,8 @@ SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(LLVMC), TLI.getPointerTy()); if (Extend) { - Result = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), CPIdx, - DAG.getSrcValue(NULL), MVT::f32); + Result = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), + CPIdx, DAG.getSrcValue(NULL), MVT::f32); } else { Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); @@ -495,13 +495,13 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - MVT::ValueType SrcVT = cast(Node)->getExtraValueType(); + MVT::ValueType SrcVT = cast(Node->getOperand(3))->getVT(); switch (TLI.getOperationAction(Node->getOpcode(), SrcVT)) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Promote: assert(SrcVT == MVT::i1 && "Can only promote EXTLOAD from i1 -> i8!"); - Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), MVT::i8); + Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), MVT::i8); // Since loads produce two values, make sure to remember that we legalized // both of them. AddLegalizedOperand(SDOperand(Node, 0), Result); @@ -511,8 +511,8 @@ case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), SrcVT); + Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), SrcVT); else Result = SDOperand(Node, 0); @@ -534,8 +534,8 @@ "EXTLOAD should always be supported!"); // Turn the unsupported load into an EXTLOAD followed by an explicit // zero/sign extend inreg. - Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), SrcVT); + Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), SrcVT); SDOperand ValRes; if (Node->getOpcode() == ISD::SEXTLOAD) ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), @@ -1362,8 +1362,9 @@ else { assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion"); FudgeInReg = - LegalizeOp(DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), - CPIdx, DAG.getSrcValue(NULL), MVT::f32)); + LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, + DAG.getEntryNode(), CPIdx, + DAG.getSrcValue(NULL), MVT::f32)); } Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg); break; @@ -1451,7 +1452,7 @@ case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, - ExtraVT); + DAG.getValueType(ExtraVT)); break; case TargetLowering::Expand: // If this is an integer extend and shifts are supported, do that. @@ -1482,8 +1483,9 @@ Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, DAG.getEntryNode(), Node->getOperand(0), StackSlot, DAG.getSrcValue(NULL), DAG.getValueType(ExtraVT)); - Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), - Result, StackSlot, DAG.getSrcValue(NULL), ExtraVT); + Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), + Result, StackSlot, DAG.getSrcValue(NULL), + ExtraVT); } else { assert(0 && "Unknown op"); } @@ -1768,11 +1770,11 @@ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. // FIXME: When the DAG combiner exists, change this to use EXTLOAD! if (MVT::isInteger(NVT)) - Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), - VT); + Result = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); else - Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), - VT); + Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); @@ -2277,8 +2279,8 @@ DAG.getSrcValue(NULL)); else { assert(DestTy == MVT::f64 && "Unexpected conversion"); - FudgeInReg = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), - CPIdx, DAG.getSrcValue(NULL), MVT::f32); + FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), + CPIdx, DAG.getSrcValue(NULL), MVT::f32); } return DAG.getNode(ISD::ADD, DestTy, SignedConv, FudgeInReg); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.124 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.125 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.124 Sat Jul 9 19:29:03 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jul 9 20:55:33 2005 @@ -235,18 +235,6 @@ cast(N)->getCondition(), N->getValueType(0)))); break; - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: { - EVTStruct NN; - NN.Opcode = N->getOpcode(); - NN.VT = N->getValueType(0); - NN.EVT = cast(N)->getExtraValueType(); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - NN.Ops.push_back(N->getOperand(i)); - MVTSDNodes.erase(NN); - break; - } default: if (N->getNumOperands() == 1) UnaryOps.erase(std::make_pair(N->getOpcode(), @@ -795,7 +783,7 @@ TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; case ISD::ZEXTLOAD: - SrcBits = MVT::getSizeInBits(cast(Op)->getExtraValueType()); + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::ZERO_EXTEND: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); @@ -1248,7 +1236,7 @@ // If we are sign extending a sextload, return just the load. if (N1.getOpcode() == ISD::SEXTLOAD) - if (cast(N1)->getExtraValueType() <= EVT) + if (cast(N1.getOperand(3))->getVT() <= EVT) return N1; // If we are extending the result of a setcc, and we already know the @@ -1335,6 +1323,22 @@ return SDOperand(N, 0); } + +SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, SDOperand SV, + MVT::ValueType EVT) { + std::vector Ops; + Ops.reserve(4); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(SV); + Ops.push_back(getValueType(EVT)); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(Opcode, VTs, Ops); +} + SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3) { // Perform various simplifications. @@ -1547,11 +1551,29 @@ if (ResultTys.size() == 1) return getNode(Opcode, ResultTys[0], Ops); + switch (Opcode) { + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: { + MVT::ValueType EVT = cast(Ops[3])->getVT(); + assert(Ops.size() == 4 && ResultTys.size() == 2 && "Bad *EXTLOAD!"); + // If they are asking for an extending load from/to the same thing, return a + // normal load. + if (ResultTys[0] == EVT) + return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]); + assert(EVT < ResultTys[0] && + "Should only be an extending load, not truncating!"); + assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) && + "Cannot sign/zero extend a FP load!"); + assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) && + "Cannot convert from FP to Int or Int -> FP!"); + break; + } + // FIXME: figure out how to safely handle things like // int foo(int x) { return 1 << (x & 255); } // int bar() { return foo(256); } #if 0 - switch (Opcode) { case ISD::SRA_PARTS: case ISD::SRL_PARTS: case ISD::SHL_PARTS: @@ -1567,8 +1589,8 @@ return getNode(Opcode, VT, N1, N2, N3.getOperand(0)); } break; - } #endif + } // Memoize the node. SDNode *&N = ArbitraryNodes[std::make_pair(Opcode, std::make_pair(ResultTys, @@ -1580,56 +1602,6 @@ return SDOperand(N, 0); } - -SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, - MVT::ValueType EVT) { - EVTStruct NN; - NN.Opcode = Opcode; - NN.VT = VT; - NN.EVT = EVT; - NN.Ops.push_back(N1); - - SDNode *&N = MVTSDNodes[NN]; - if (N) return SDOperand(N, 0); - N = new MVTSDNode(Opcode, VT, N1, EVT); - AllNodes.push_back(N); - return SDOperand(N, 0); -} - -SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, - SDOperand N2, SDOperand N3, MVT::ValueType EVT) { - switch (Opcode) { - default: assert(0 && "Bad opcode for this accessor!"); - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: - // If they are asking for an extending load from/to the same thing, return a - // normal load. - if (VT == EVT) - return getLoad(VT, N1, N2, N3); - assert(EVT < VT && "Should only be an extending load, not truncating!"); - assert((Opcode == ISD::EXTLOAD || MVT::isInteger(VT)) && - "Cannot sign/zero extend a FP load!"); - assert(MVT::isInteger(VT) == MVT::isInteger(EVT) && - "Cannot convert from FP to Int or Int -> FP!"); - break; - } - - EVTStruct NN; - NN.Opcode = Opcode; - NN.VT = VT; - NN.EVT = EVT; - NN.Ops.push_back(N1); - NN.Ops.push_back(N2); - NN.Ops.push_back(N3); - - SDNode *&N = MVTSDNodes[NN]; - if (N) return SDOperand(N, 0); - N = new MVTSDNode(Opcode, VT, MVT::Other, N1, N2, N3, EVT); - AllNodes.push_back(N); - return SDOperand(N, 0); -} - /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. @@ -1836,8 +1808,6 @@ } else if (const ExternalSymbolSDNode *ES = dyn_cast(this)) { std::cerr << "'" << ES->getSymbol() << "'"; - } else if (const MVTSDNode *M = dyn_cast(this)) { - std::cerr << " - Ty = " << MVT::getValueTypeString(M->getExtraValueType()); } else if (const SrcValueSDNode *M = dyn_cast(this)) { if (M->getValue()) std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.11 llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.12 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.11 Sun May 8 23:08:27 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Sat Jul 9 20:55:33 2005 @@ -88,8 +88,6 @@ } else if (const ExternalSymbolSDNode *ES = dyn_cast(Node)) { Op += "'" + std::string(ES->getSymbol()) + "'"; - } else if (const MVTSDNode *M = dyn_cast(Node)) { - Op = Op + " ty=" + MVT::getValueTypeString(M->getExtraValueType()); } else if (const SrcValueSDNode *M = dyn_cast(Node)) { if (M->getValue()) Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">"; From lattner at cs.uiuc.edu Sat Jul 9 20:56:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:56:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200507100156.UAA31177@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.149 -> 1.150 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. Also, remove some uses of dyn_cast that should really be cast (which is cheaper in a release build). --- Diffs of the changes: (+18 -21) AlphaISelPattern.cpp | 39 ++++++++++++++++++--------------------- 1 files changed, 18 insertions(+), 21 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.149 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.150 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.149 Sat Jul 9 19:29:16 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Sat Jul 9 20:56:07 2005 @@ -429,8 +429,8 @@ DAG.getSrcValue(VAListV)); SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, DAG.getConstant(8, MVT::i64)); - SDOperand Offset = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), - Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); + SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), + Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); if (ArgTy->isFloatingPoint()) { @@ -444,11 +444,11 @@ SDOperand Result; if (ArgTy == Type::IntTy) - Result = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1), DataPtr, - DAG.getSrcValue(NULL), MVT::i32); + Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1), + DataPtr, DAG.getSrcValue(NULL), MVT::i32); else if (ArgTy == Type::UIntTy) - Result = DAG.getNode(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), DataPtr, - DAG.getSrcValue(NULL), MVT::i32); + Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), + DataPtr, DAG.getSrcValue(NULL), MVT::i32); else Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr, DAG.getSrcValue(NULL)); @@ -474,8 +474,8 @@ Val, DestP, DAG.getSrcValue(DestV)); SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, DAG.getConstant(8, MVT::i64)); - Val = DAG.getNode(ISD::SEXTLOAD, MVT::i64, Result, NP, - DAG.getSrcValue(SrcV, 8), MVT::i32); + Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, + DAG.getSrcValue(SrcV, 8), MVT::i32); SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, DAG.getConstant(8, MVT::i64)); return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), @@ -1252,7 +1252,7 @@ case MVT::f32: Opc = Alpha::LDS; break; } else - switch (cast(Node)->getExtraValueType()) { + switch (cast(Node->getOperand(3))->getVT()) { default: Node->dump(); assert(0 && "Bad sign extend!"); case MVT::i32: Opc = Alpha::LDL; assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; @@ -1279,7 +1279,8 @@ .addImm(getUID()); BuildMI(BB, GetRelVersion(Opc), 2, Result) .addGlobalAddress(GASD->getGlobal()).addReg(Tmp1); - } else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { + } else if (ConstantPoolSDNode *CP = + dyn_cast(Address)) { AlphaLowering.restoreGP(BB); has_sym = true; Tmp1 = MakeReg(MVT::i64); @@ -1473,8 +1474,7 @@ } //Alpha has instructions for a bunch of signed 32 bit stuff - if( dyn_cast(Node)->getExtraValueType() == MVT::i32) - { + if(cast(Node->getOperand(1))->getVT() == MVT::i32) { switch (N.getOperand(0).getOpcode()) { case ISD::ADD: case ISD::SUB: @@ -1485,7 +1485,7 @@ //FIXME: first check for Scaled Adds and Subs! ConstantSDNode* CSD = NULL; if(!isMul && N.getOperand(0).getOperand(0).getOpcode() == ISD::SHL && - (CSD = dyn_cast(N.getOperand(0).getOperand(0).getOperand(1))) && + (CSD = cast(N.getOperand(0).getOperand(0).getOperand(1))) && (CSD->getValue() == 2 || CSD->getValue() == 3)) { bool use4 = CSD->getValue() == 2; @@ -1495,7 +1495,7 @@ 2,Result).addReg(Tmp1).addReg(Tmp2); } else if(isAdd && N.getOperand(0).getOperand(1).getOpcode() == ISD::SHL && - (CSD = dyn_cast(N.getOperand(0).getOperand(1).getOperand(1))) && + (CSD = cast(N.getOperand(0).getOperand(1).getOperand(1))) && (CSD->getValue() == 2 || CSD->getValue() == 3)) { bool use4 = CSD->getValue() == 2; @@ -1524,10 +1524,8 @@ } } //Every thing else fall though too, including unhandled opcodes above Tmp1 = SelectExpr(N.getOperand(0)); - MVTSDNode* MVN = dyn_cast(Node); //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; - switch(MVN->getExtraValueType()) - { + switch(cast(Node->getOperand(1))->getVT()) { default: Node->dump(); assert(0 && "Sign Extend InReg not there yet"); @@ -1636,7 +1634,7 @@ SDOperand Chain = N.getOperand(0); Select(Chain); - unsigned r = dyn_cast(Node)->getReg(); + unsigned r = cast(Node)->getReg(); //std::cerr << "CopyFromReg " << Result << " = " << r << "\n"; if (MVT::isFloatingPoint(N.getValue(0).getValueType())) BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r); @@ -1943,8 +1941,7 @@ SDOperand CC = N.getOperand(0); SetCCSDNode* SetCC = dyn_cast(CC.Val); - if (CC.getOpcode() == ISD::SETCC && - !MVT::isInteger(SetCC->getOperand(0).getValueType())) + if (SetCC && !MVT::isInteger(SetCC->getOperand(0).getValueType())) { //FP Setcc -> Select yay! @@ -2296,7 +2293,7 @@ int i, j, k; if (EnableAlphaLSMark) - getValueInfo(dyn_cast(N.getOperand(3))->getValue(), + getValueInfo(cast(N.getOperand(3))->getValue(), i, j, k); GlobalAddressSDNode *GASD = dyn_cast(Address); From lattner at cs.uiuc.edu Sat Jul 9 20:56:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:56:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200507100156.UAA31194@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.48 -> 1.49 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. Also, remove some uses of dyn_cast that should really be cast (which is cheaper in a release build). --- Diffs of the changes: (+3 -4) IA64ISelPattern.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.48 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.49 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.48 Sat Jul 9 19:29:18 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Sat Jul 9 20:56:13 2005 @@ -1815,9 +1815,7 @@ case ISD::SIGN_EXTEND_INREG: { Tmp1 = SelectExpr(N.getOperand(0)); - MVTSDNode* MVN = dyn_cast(Node); - switch(MVN->getExtraValueType()) - { + switch(cast(Node->getOperand(1))->getVT()) { default: Node->dump(); assert(0 && "don't know how to sign extend this type"); @@ -1963,7 +1961,8 @@ case MVT::f64: Opc = IA64::LDF8; break; } } else { // this is an EXTLOAD or ZEXTLOAD - MVT::ValueType TypeBeingLoaded = cast(Node)->getExtraValueType(); + MVT::ValueType TypeBeingLoaded = + cast(Node->getOperand(3))->getVT(); switch (TypeBeingLoaded) { default: assert(0 && "Cannot extload/zextload this type!"); // FIXME: bools? From lattner at cs.uiuc.edu Sat Jul 9 20:56:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:56:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200507100156.UAA31198@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.148 -> 1.149 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. Also, remove some uses of dyn_cast that should really be cast (which is cheaper in a release build). --- Diffs of the changes: (+8 -8) X86ISelPattern.cpp | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.148 llvm/lib/Target/X86/X86ISelPattern.cpp:1.149 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.148 Sat Jul 9 19:29:18 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sat Jul 9 20:56:13 2005 @@ -1934,7 +1934,7 @@ if (isa(Op.getOperand(1))) return false; } else if (FloatPromoteOk && Op.getOpcode() == ISD::EXTLOAD && - cast(Op)->getExtraValueType() == MVT::f32) { + cast(Op.getOperand(3))->getVT() == MVT::f32) { // FIXME: currently can't fold constant pool indexes. if (isa(Op.getOperand(1))) return false; @@ -3377,7 +3377,7 @@ if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(1))) if (Node->getValueType(0) == MVT::f64) { - assert(cast(Node)->getExtraValueType() == MVT::f32 && + assert(cast(Node->getOperand(3))->getVT() == MVT::f32 && "Bad EXTLOAD!"); addConstantPoolReference(BuildMI(BB, X86::FLD32m, 4, Result), CP->getIndex()); @@ -3397,12 +3397,12 @@ switch (Node->getValueType(0)) { default: assert(0 && "Unknown type to sign extend to."); case MVT::f64: - assert(cast(Node)->getExtraValueType() == MVT::f32 && + assert(cast(Node->getOperand(3))->getVT() == MVT::f32 && "Bad EXTLOAD!"); addFullAddress(BuildMI(BB, X86::FLD32m, 5, Result), AM); break; case MVT::i32: - switch (cast(Node)->getExtraValueType()) { + switch (cast(Node->getOperand(3))->getVT()) { default: assert(0 && "Bad zero extend!"); case MVT::i1: @@ -3415,12 +3415,12 @@ } break; case MVT::i16: - assert(cast(Node)->getExtraValueType() <= MVT::i8 && + assert(cast(Node->getOperand(3))->getVT() <= MVT::i8 && "Bad zero extend!"); addFullAddress(BuildMI(BB, X86::MOVSX16rm8, 5, Result), AM); break; case MVT::i8: - assert(cast(Node)->getExtraValueType() == MVT::i1 && + assert(cast(Node->getOperand(3))->getVT() == MVT::i1 && "Bad zero extend!"); addFullAddress(BuildMI(BB, X86::MOV8rm, 5, Result), AM); break; @@ -3448,7 +3448,7 @@ case MVT::i8: assert(0 && "Cannot sign extend from bool!"); default: assert(0 && "Unknown type to sign extend to."); case MVT::i32: - switch (cast(Node)->getExtraValueType()) { + switch (cast(Node->getOperand(3))->getVT()) { default: case MVT::i1: assert(0 && "Cannot sign extend from bool!"); case MVT::i8: @@ -3460,7 +3460,7 @@ } break; case MVT::i16: - assert(cast(Node)->getExtraValueType() == MVT::i8 && + assert(cast(Node->getOperand(3))->getVT() == MVT::i8 && "Cannot sign extend from bool!"); addFullAddress(BuildMI(BB, X86::MOVSX16rm8, 5, Result), AM); break; From lattner at cs.uiuc.edu Sat Jul 9 20:56:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:56:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp Message-ID: <200507100156.UAA31208@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelPattern.cpp updated: 1.3 -> 1.4 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. Also, remove some uses of dyn_cast that should really be cast (which is cheaper in a release build). --- Diffs of the changes: (+1 -1) SparcV8ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.3 llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.4 --- llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp:1.3 Sat Jul 9 19:29:18 2005 +++ llvm/lib/Target/SparcV8/SparcV8ISelPattern.cpp Sat Jul 9 20:56:13 2005 @@ -340,7 +340,7 @@ SDOperand Address = N.getOperand(1); Select(Chain); unsigned Adr = SelectExpr(Address); - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(3))->getVT()) { case MVT::i32: Opc = V8::LD; case MVT::i16: Opc = opcode == ISD::ZEXTLOAD ? V8::LDUH : V8::LDSH; break; case MVT::i8: Opc = opcode == ISD::ZEXTLOAD ? V8::LDUB : V8::LDSB; break; From lattner at cs.uiuc.edu Sat Jul 9 20:56:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Jul 2005 20:56:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC64ISelPattern.cpp Message-ID: <200507100156.UAA31204@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.98 -> 1.99 PPC64ISelPattern.cpp updated: 1.24 -> 1.25 --- Log message: Change *EXTLOAD to use an VTSDNode operand instead of being an MVTSDNode. This is the last MVTSDNode. This allows us to eliminate a bunch of special case code for handling MVTSDNodes. Also, remove some uses of dyn_cast that should really be cast (which is cheaper in a release build). --- Diffs of the changes: (+4 -4) PPC32ISelPattern.cpp | 4 ++-- PPC64ISelPattern.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.98 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.99 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.98 Sat Jul 9 19:29:18 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Jul 9 20:56:13 2005 @@ -1690,7 +1690,7 @@ case ISD::ZEXTLOAD: case ISD::SEXTLOAD: { MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? - Node->getValueType(0) : cast(Node)->getExtraValueType(); + Node->getValueType(0) : cast(Node->getOperand(3))->getVT(); bool sext = (ISD::SEXTLOAD == opcode); // Make sure we generate both values. @@ -1828,7 +1828,7 @@ case ISD::SIGN_EXTEND: case ISD::SIGN_EXTEND_INREG: Tmp1 = SelectExpr(N.getOperand(0)); - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(1))->getVT()) { default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break; case MVT::i16: BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1); Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.24 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.25 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.24 Sat Jul 9 19:29:18 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Sat Jul 9 20:56:13 2005 @@ -1030,7 +1030,7 @@ case ISD::ZEXTLOAD: case ISD::SEXTLOAD: { MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? - Node->getValueType(0) : cast(Node)->getExtraValueType(); + Node->getValueType(0) : cast(Node->getOperand(3))->getVT(); bool sext = (ISD::SEXTLOAD == opcode); // Make sure we generate both values. @@ -1166,7 +1166,7 @@ case ISD::SIGN_EXTEND: case ISD::SIGN_EXTEND_INREG: Tmp1 = SelectExpr(N.getOperand(0)); - switch(cast(Node)->getExtraValueType()) { + switch(cast(Node->getOperand(1))->getVT()) { default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break; case MVT::i32: BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1); From lattner at cs.uiuc.edu Sun Jul 10 21:49:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Jul 2005 21:49:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200507110249.VAA10590@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.69 -> 1.70 --- Log message: fix long lines --- Diffs of the changes: (+4 -3) ExecutionEngine.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.69 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.70 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.69 Thu May 12 01:01:28 2005 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Sun Jul 10 21:49:16 2005 @@ -464,7 +464,7 @@ case Type::ArrayTyID: { const ConstantArray *CPA = cast(Init); unsigned ElementSize = - getTargetData().getTypeSize(cast(CPA->getType())->getElementType()); + getTargetData().getTypeSize(CPA->getType()->getElementType()); for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); return; @@ -494,7 +494,8 @@ // Loop over all of the global variables in the program, allocating the memory // to hold them. - for (Module::const_global_iterator I = getModule().global_begin(), E = getModule().global_end(); + Module &M = getModule(); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isExternal()) { // Get the type of the global... @@ -518,7 +519,7 @@ // Now that all of the globals are set up in memory, loop through them all and // initialize their contents. - for (Module::const_global_iterator I = getModule().global_begin(), E = getModule().global_end(); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isExternal()) EmitGlobalVariable(I); From lattner at cs.uiuc.edu Sun Jul 10 22:11:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Jul 2005 22:11:21 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ELFWriter.h Message-ID: <200507110311.WAA11798@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ELFWriter.h updated: 1.2 -> 1.3 --- Log message: add a name mangler object --- Diffs of the changes: (+5 -0) ELFWriter.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/CodeGen/ELFWriter.h diff -u llvm/include/llvm/CodeGen/ELFWriter.h:1.2 llvm/include/llvm/CodeGen/ELFWriter.h:1.3 --- llvm/include/llvm/CodeGen/ELFWriter.h:1.2 Thu Jul 7 02:00:37 2005 +++ llvm/include/llvm/CodeGen/ELFWriter.h Sun Jul 10 22:11:10 2005 @@ -18,6 +18,7 @@ namespace llvm { class GlobalVariable; + class Mangler; /// ELFWriter - This class implements the common target-independent code for /// writing ELF files. Targets should derive a class from this to @@ -35,6 +36,10 @@ /// TargetMachine &TM; + /// Mang - The object used to perform name mangling for this module. + /// + Mangler *Mang; + //===------------------------------------------------------------------===// // Properties to be set by the derived class ctor, used to configure the // ELFWriter. From lattner at cs.uiuc.edu Sun Jul 10 22:11:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Jul 2005 22:11:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ELFWriter.cpp Message-ID: <200507110311.WAA12496@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ELFWriter.cpp updated: 1.3 -> 1.4 --- Log message: Use a name mangler object to uniquify names and remove nonstandard characters from them. --- Diffs of the changes: (+8 -2) ELFWriter.cpp | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/ELFWriter.cpp diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.3 llvm/lib/CodeGen/ELFWriter.cpp:1.4 --- llvm/lib/CodeGen/ELFWriter.cpp:1.3 Fri Jul 8 00:47:00 2005 +++ llvm/lib/CodeGen/ELFWriter.cpp Sun Jul 10 22:11:47 2005 @@ -35,6 +35,7 @@ #include "llvm/CodeGen/ELFWriter.h" #include "llvm/Module.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Mangler.h" using namespace llvm; ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { @@ -48,6 +49,8 @@ // doInitialization - Emit the file header and all of the global variables for // the module to the ELF file. bool ELFWriter::doInitialization(Module &M) { + Mang = new Mangler(M); + outbyte(0x7F); // EI_MAG0 outbyte('E'); // EI_MAG1 outbyte('L'); // EI_MAG2 @@ -225,6 +228,9 @@ // Free the output buffer. std::vector().swap(OutputBuffer); + + // Release the name mangler object. + delete Mang; Mang = 0; return false; } @@ -246,8 +252,8 @@ SymbolTable[0].NameIdx = 0; unsigned Index = 1; for (unsigned i = 1, e = SymbolTable.size(); i != e; ++i) { - // FIXME: USE A MANGLER!! - const std::string &Name = SymbolTable[i].GV->getName(); + // Use the name mangler to uniquify the LLVM symbol. + std::string Name = Mang->getValueName(SymbolTable[i].GV); if (Name.empty()) { SymbolTable[i].NameIdx = 0; From lattner at cs.uiuc.edu Sun Jul 10 23:21:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Jul 2005 23:21:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h Message-ID: <200507110421.XAA31261@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.33 -> 1.34 --- Log message: Remove prototype for non-existant function --- Diffs of the changes: (+0 -6) X86.h | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.33 llvm/lib/Target/X86/X86.h:1.34 --- llvm/lib/Target/X86/X86.h:1.33 Wed Jul 6 13:59:03 2005 +++ llvm/lib/Target/X86/X86.h Sun Jul 10 23:20:55 2005 @@ -51,12 +51,6 @@ /// FunctionPass *createX86PeepholeOptimizerPass(); -/// createX86FloatingPointKiller - This function returns a pass which -/// kills every floating point register at the end of each basic block -/// because our FloatingPointStackifier cannot handle them. -/// -FunctionPass *createX86FloatingPointKillerPass(); - /// createX86FloatingPointStackifierPass - This function returns a pass which /// converts floating point register references and pseudo instructions into /// floating point stack references and physical instructions. From lattner at cs.uiuc.edu Sun Jul 10 23:49:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Jul 2005 23:49:44 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineConstantPool.h Message-ID: <200507110449.XAA03661@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineConstantPool.h updated: 1.5 -> 1.6 --- Log message: add a helper method --- Diffs of the changes: (+4 -0) MachineConstantPool.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/CodeGen/MachineConstantPool.h diff -u llvm/include/llvm/CodeGen/MachineConstantPool.h:1.5 llvm/include/llvm/CodeGen/MachineConstantPool.h:1.6 --- llvm/include/llvm/CodeGen/MachineConstantPool.h:1.5 Thu Apr 21 15:38:00 2005 +++ llvm/include/llvm/CodeGen/MachineConstantPool.h Sun Jul 10 23:49:33 2005 @@ -46,6 +46,10 @@ return Constants.size()-1; } + /// isEmpty - Return true if this constant pool contains no constants. + /// + bool isEmpty() const { return Constants.empty(); } + const std::vector &getConstants() const { return Constants; } /// print - Used by the MachineFunction printer to print information about