From evan.cheng at apple.com Mon Nov 24 00:41:36 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 Nov 2008 06:41:36 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59949 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200811240641.mAO6fag4010847@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 24 00:41:36 2008 New Revision: 59949 URL: http://llvm.org/viewvc/llvm-project?rev=59949&view=rev Log: Minor clean up. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=59949&r1=59948&r2=59949&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Mon Nov 24 00:41:36 2008 @@ -124,7 +124,7 @@ if [ ! -d "/usr/include/c++/$LIBSTDCXX_VERSION" ]; then LIBSTDCXX_VERSION=4.0.0 fi -#NON_ARM_CONFIGFLAGS="--with-gxx-include-dir=\${prefix}/include/c++/$LIBSTDCXX_VERSION" +NON_ARM_CONFIGFLAGS="--with-gxx-include-dir=/usr/include/c++/$LIBSTDCXX_VERSION" # LLVM LOCAL end DARWIN_VERS=`uname -r | sed 's/\..*//'` @@ -164,7 +164,6 @@ --enable-languages=$LANGUAGES \ --program-prefix=llvm- \ --program-transform-name=/^[cg][^.-]*$/s/$/-$MAJ_VERS/ \ - --with-gxx-include-dir=/usr/include/c++/$LIBSTDCXX_VERSION \ --with-slibdir=/usr/lib \ --build=$BUILD-apple-darwin$DARWIN_VERS" From evan.cheng at apple.com Mon Nov 24 00:42:06 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 Nov 2008 06:42:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59950 - /llvm-gcc-4.2/trunk/gcc/Makefile.in Message-ID: <200811240642.mAO6g7RD010873@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 24 00:42:06 2008 New Revision: 59950 URL: http://llvm.org/viewvc/llvm-project?rev=59950&view=rev Log: Also pull in arm backend. Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/Makefile.in?rev=59950&r1=59949&r2=59950&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/Makefile.in (original) +++ llvm-gcc-4.2/trunk/gcc/Makefile.in Mon Nov 24 00:42:06 2008 @@ -1155,7 +1155,7 @@ # If in BUILD_LLVM_INTO_A_DYLIB mode, always link in the x86/ppc backends. # See below for more details. ifdef BUILD_LLVM_INTO_A_DYLIB -LLVMTARGETOBJ := $(sort $(LLVMTARGETOBJ) x86 powerpc) +LLVMTARGETOBJ := $(sort $(LLVMTARGETOBJ) x86 powerpc arm) endif # We use llvm-config to determine the libraries that we need to link in our From evan.cheng at apple.com Mon Nov 24 01:09:49 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 Nov 2008 07:09:49 -0000 Subject: [llvm-commits] [llvm] r59952 - in /llvm/trunk/lib/CodeGen/SelectionDAG: FastISel.cpp LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200811240709.mAO79nYH011666@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 24 01:09:49 2008 New Revision: 59952 URL: http://llvm.org/viewvc/llvm-project?rev=59952&view=rev Log: Eliminate some unused variable compile time warnings. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=59952&r1=59951&r2=59952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon Nov 24 01:09:49 2008 @@ -401,6 +401,7 @@ bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg, RC, RC); assert(InsertedCopy && "Can't copy address registers!"); + InsertedCopy = InsertedCopy; UpdateValueMap(I, ResultReg); return true; } @@ -434,6 +435,7 @@ bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg, RC, RC); assert(InsertedCopy && "Can't copy address registers!"); + InsertedCopy = InsertedCopy; UpdateValueMap(I, ResultReg); } else { unsigned ResultReg = Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=59952&r1=59951&r2=59952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 24 01:09:49 2008 @@ -114,12 +114,14 @@ void AddPromotedOperand(SDValue From, SDValue To) { bool isNew = PromotedNodes.insert(std::make_pair(From, To)).second; assert(isNew && "Got into the map somehow?"); + isNew = isNew; // If someone requests legalization of the new node, return itself. LegalizedNodes.insert(std::make_pair(To, To)); } void AddWidenedOperand(SDValue From, SDValue To) { bool isNew = WidenNodes.insert(std::make_pair(From, To)).second; assert(isNew && "Got into the map somehow?"); + isNew = isNew; // If someone requests legalization of the new node, return itself. LegalizedNodes.insert(std::make_pair(To, To)); } @@ -7163,6 +7165,7 @@ bool isNew = ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second; assert(isNew && "Value already expanded?!?"); + isNew = isNew; } /// SplitVectorOp - Given an operand of vector type, break it down into @@ -7509,6 +7512,7 @@ bool isNew = SplitNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second; assert(isNew && "Value already split?!?"); + isNew = isNew; } @@ -7676,6 +7680,7 @@ Result = LegalizeOp(Result); bool isNew = ScalarizedNodes.insert(std::make_pair(Op, Result)).second; assert(isNew && "Value already scalarized?"); + isNew = isNew; return Result; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=59952&r1=59951&r2=59952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Nov 24 01:09:49 2008 @@ -1212,9 +1212,11 @@ } SDValue SelectionDAG::getMemOperand(const MachineMemOperand &MO) { +#ifndef NDEBUG const Value *v = MO.getValue(); assert((!v || isa(v->getType())) && "SrcValue is not a pointer?"); +#endif FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::MEMOPERAND, getVTList(MVT::Other), 0, 0); From edwintorok at gmail.com Mon Nov 24 01:25:54 2008 From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=) Date: Mon, 24 Nov 2008 09:25:54 +0200 Subject: [llvm-commits] [llvm] r59940 - in /llvm/trunk: docs/LangRef.html lib/Analysis/BasicAliasAnalysis.cpp In-Reply-To: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> References: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> Message-ID: <492A5702.3070403@gmail.com> On 2008-11-24 07:00, Nick Lewycky wrote: > Author: nicholas > Date: Sun Nov 23 23:00:44 2008 > New Revision: 59940 > > URL: http://llvm.org/viewvc/llvm-project?rev=59940&view=rev > Log: > Seriously strengthen the guarantee offered by noalias on a function's return > value. It must now be as if the pointer were allocated and has not escaped to > the caller. Thanks to Dan Gohman for pointing out the error in the original > and helping devise this definition. > > malloc(0) is allowed to return a unique pointer, instead of NULL. Does this code handle that? Best regards, --Edwin From evan.cheng at apple.com Mon Nov 24 01:34:46 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 Nov 2008 07:34:46 -0000 Subject: [llvm-commits] [llvm] r59953 - in /llvm/trunk: ./ include/llvm/Target/ lib/Target/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PIC16/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ lib/Target/XCore/ Message-ID: <200811240734.mAO7Yl4n012468@zion.cs.uiuc.edu> Author: evancheng Date: Mon Nov 24 01:34:46 2008 New Revision: 59953 URL: http://llvm.org/viewvc/llvm-project?rev=59953&view=rev Log: Move target independent td files from lib/Target/ to include/llvm/Target so they can be distributed along with the header files. Added: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetCallingConv.td llvm/trunk/include/llvm/Target/TargetSchedule.td llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Removed: llvm/trunk/lib/Target/Target.td llvm/trunk/lib/Target/TargetCallingConv.td llvm/trunk/lib/Target/TargetSchedule.td llvm/trunk/lib/Target/TargetSelectionDAG.td Modified: llvm/trunk/Makefile.rules llvm/trunk/lib/Target/ARM/ARM.td llvm/trunk/lib/Target/Alpha/Alpha.td llvm/trunk/lib/Target/CellSPU/SPU.td llvm/trunk/lib/Target/IA64/IA64.td llvm/trunk/lib/Target/Mips/Mips.td llvm/trunk/lib/Target/PIC16/PIC16.td llvm/trunk/lib/Target/PowerPC/PPC.td llvm/trunk/lib/Target/Sparc/Sparc.td llvm/trunk/lib/Target/X86/X86.td llvm/trunk/lib/Target/XCore/XCore.td Modified: llvm/trunk/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.rules?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/Makefile.rules (original) +++ llvm/trunk/Makefile.rules Mon Nov 24 01:34:46 2008 @@ -1259,9 +1259,10 @@ ifdef TARGET TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) \ - $(LLVM_SRC_ROOT)/lib/Target/Target.td \ - $(LLVM_SRC_ROOT)/lib/Target/TargetCallingConv.td \ - $(LLVM_SRC_ROOT)/lib/Target/TargetSelectionDAG.td \ + $(LLVM_SRC_ROOT)/include/llvm/Target/Target.td \ + $(LLVM_SRC_ROOT)/include/llvm/Target/TargetCallingConv.td \ + $(LLVM_SRC_ROOT)/include/llvm/Target/TargetSchedule.td \ + $(LLVM_SRC_ROOT)/include/llvm/Target/TargetSelectionDAG.td \ $(LLVM_SRC_ROOT)/include/llvm/CodeGen/ValueTypes.td) \ $(wildcard $(LLVM_SRC_ROOT)/include/llvm/Intrinsics*.td) INCFiles := $(filter %.inc,$(BUILT_SOURCES)) Added: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=59953&view=auto ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (added) +++ llvm/trunk/include/llvm/Target/Target.td Mon Nov 24 01:34:46 2008 @@ -0,0 +1,499 @@ +//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the target-independent interfaces which should be +// implemented by each target which is using a TableGen based code generator. +// +//===----------------------------------------------------------------------===// + +// Include all information about LLVM intrinsics. +include "llvm/Intrinsics.td" + +//===----------------------------------------------------------------------===// +// Register file description - These classes are used to fill in the target +// description classes. + +class RegisterClass; // Forward def + +// Register - You should define one instance of this class for each register +// in the target machine. String n will become the "name" of the register. +class Register { + string Namespace = ""; + string AsmName = n; + + // SpillSize - If this value is set to a non-zero value, it is the size in + // bits of the spill slot required to hold this register. If this value is + // set to zero, the information is inferred from any register classes the + // register belongs to. + int SpillSize = 0; + + // SpillAlignment - This value is used to specify the alignment required for + // spilling the register. Like SpillSize, this should only be explicitly + // specified if the register is not in a register class. + int SpillAlignment = 0; + + // Aliases - A list of registers that this register overlaps with. A read or + // modification of this register can potentially read or modify the aliased + // registers. + list Aliases = []; + + // SubRegs - A list of registers that are parts of this register. Note these + // are "immediate" sub-registers and the registers within the list do not + // themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX], + // not [AX, AH, AL]. + list SubRegs = []; + + // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. + // These values can be determined by locating the .h file in the + // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The + // order of these names correspond to the enumeration used by gcc. A value of + // -1 indicates that the gcc number is undefined and -2 that register number + // is invalid for this mode/flavour. + list DwarfNumbers = []; +} + +// RegisterWithSubRegs - This can be used to define instances of Register which +// need to specify sub-registers. +// List "subregs" specifies which registers are sub-registers to this one. This +// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc. +// This allows the code generator to be careful not to put two values with +// overlapping live ranges into registers which alias. +class RegisterWithSubRegs subregs> : Register { + let SubRegs = subregs; +} + +// SubRegSet - This can be used to define a specific mapping of registers to +// indices, for use as named subregs of a particular physical register. Each +// register in 'subregs' becomes an addressable subregister at index 'n' of the +// corresponding register in 'regs'. +class SubRegSet regs, list subregs> { + int index = n; + + list From = regs; + list To = subregs; +} + +// RegisterClass - Now that all of the registers are defined, and aliases +// between registers are defined, specify which registers belong to which +// register classes. This also defines the default allocation order of +// registers by register allocators. +// +class RegisterClass regTypes, int alignment, + list regList> { + string Namespace = namespace; + + // RegType - Specify the list ValueType of the registers in this register + // class. Note that all registers in a register class must have the same + // ValueTypes. This is a list because some targets permit storing different + // types in same register, for example vector values with 128-bit total size, + // but different count/size of items, like SSE on x86. + // + list RegTypes = regTypes; + + // Size - Specify the spill size in bits of the registers. A default value of + // zero lets tablgen pick an appropriate size. + int Size = 0; + + // Alignment - Specify the alignment required of the registers when they are + // stored or loaded to memory. + // + int Alignment = alignment; + + // CopyCost - This value is used to specify the cost of copying a value + // between two registers in this register class. The default value is one + // meaning it takes a single instruction to perform the copying. A negative + // value means copying is extremely expensive or impossible. + int CopyCost = 1; + + // MemberList - Specify which registers are in this class. If the + // allocation_order_* method are not specified, this also defines the order of + // allocation used by the register allocator. + // + list MemberList = regList; + + // SubClassList - Specify which register classes correspond to subregisters + // of this class. The order should be by subregister set index. + list SubRegClassList = []; + + // MethodProtos/MethodBodies - These members can be used to insert arbitrary + // code into a generated register class. The normal usage of this is to + // overload virtual methods. + code MethodProtos = [{}]; + code MethodBodies = [{}]; +} + + +//===----------------------------------------------------------------------===// +// DwarfRegNum - This class provides a mapping of the llvm register enumeration +// to the register numbering used by gcc and gdb. These values are used by a +// debug information writer (ex. DwarfWriter) to describe where values may be +// located during execution. +class DwarfRegNum Numbers> { + // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. + // These values can be determined by locating the .h file in the + // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The + // order of these names correspond to the enumeration used by gcc. A value of + // -1 indicates that the gcc number is undefined and -2 that register number is + // invalid for this mode/flavour. + list DwarfNumbers = Numbers; +} + +//===----------------------------------------------------------------------===// +// Pull in the common support for scheduling +// +include "llvm/Target/TargetSchedule.td" + +class Predicate; // Forward def + +//===----------------------------------------------------------------------===// +// Instruction set description - These classes correspond to the C++ classes in +// the Target/TargetInstrInfo.h file. +// +class Instruction { + string Namespace = ""; + + dag OutOperandList; // An dag containing the MI def operand list. + dag InOperandList; // An dag containing the MI use operand list. + string AsmString = ""; // The .s format to print the instruction with. + + // Pattern - Set to the DAG pattern for this instruction, if we know of one, + // otherwise, uninitialized. + list Pattern; + + // The follow state will eventually be inferred automatically from the + // instruction pattern. + + list Uses = []; // Default to using no non-operand registers + list Defs = []; // Default to modifying no non-operand registers + + // Predicates - List of predicates which will be turned into isel matching + // code. + list Predicates = []; + + // Code size. + int CodeSize = 0; + + // Added complexity passed onto matching pattern. + int AddedComplexity = 0; + + // These bits capture information about the high-level semantics of the + // instruction. + bit isReturn = 0; // Is this instruction a return instruction? + bit isBranch = 0; // Is this instruction a branch instruction? + bit isIndirectBranch = 0; // Is this instruction an indirect branch? + bit isBarrier = 0; // Can control flow fall through this instruction? + bit isCall = 0; // Is this instruction a call instruction? + bit isSimpleLoad = 0; // Is this just a load instruction? + bit mayLoad = 0; // Is it possible for this inst to read memory? + bit mayStore = 0; // Is it possible for this inst to write memory? + bit isTwoAddress = 0; // Is this a two address instruction? + bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? + bit isCommutable = 0; // Is this 3 operand instruction commutable? + bit isTerminator = 0; // Is this part of the terminator for a basic block? + bit isReMaterializable = 0; // Is this instruction re-materializable? + bit isPredicable = 0; // Is this instruction predicable? + bit hasDelaySlot = 0; // Does this instruction have an delay slot? + bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help. + bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? + bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? + bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. + + // Side effect flags - When set, the flags have these meanings: + // + // hasSideEffects - The instruction has side effects that are not + // captured by any operands of the instruction or other flags. + // + // mayHaveSideEffects - Some instances of the instruction can have side + // effects. The virtual method "isReallySideEffectFree" is called to + // determine this. Load instructions are an example of where this is + // useful. In general, loads always have side effects. However, loads from + // constant pools don't. Individual back ends make this determination. + // + // neverHasSideEffects - Set on an instruction with no pattern if it has no + // side effects. + bit hasSideEffects = 0; + bit mayHaveSideEffects = 0; + bit neverHasSideEffects = 0; + + InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. + + string Constraints = ""; // OperandConstraint, e.g. $src = $dst. + + /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not + /// be encoded into the output machineinstr. + string DisableEncoding = ""; +} + +/// Predicates - These are extra conditionals which are turned into instruction +/// selector matching code. Currently each predicate is just a string. +class Predicate { + string CondString = cond; +} + +/// NoHonorSignDependentRounding - This predicate is true if support for +/// sign-dependent-rounding is not enabled. +def NoHonorSignDependentRounding + : Predicate<"!HonorSignDependentRoundingFPMath()">; + +class Requires preds> { + list Predicates = preds; +} + +/// ops definition - This is just a simple marker used to identify the operands +/// list for an instruction. outs and ins are identical both syntatically and +/// semantically, they are used to define def operands and use operands to +/// improve readibility. This should be used like this: +/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar. +def ops; +def outs; +def ins; + +/// variable_ops definition - Mark this instruction as taking a variable number +/// of operands. +def variable_ops; + +/// ptr_rc definition - Mark this operand as being a pointer value whose +/// register class is resolved dynamically via a callback to TargetInstrInfo. +/// FIXME: We should probably change this to a class which contain a list of +/// flags. But currently we have but one flag. +def ptr_rc; + +/// unknown definition - Mark this operand as being of unknown type, causing +/// it to be resolved by inference in the context it is used. +def unknown; + +/// Operand Types - These provide the built-in operand types that may be used +/// by a target. Targets can optionally provide their own operand types as +/// needed, though this should not be needed for RISC targets. +class Operand { + ValueType Type = ty; + string PrintMethod = "printOperand"; + dag MIOperandInfo = (ops); +} + +def i1imm : Operand; +def i8imm : Operand; +def i16imm : Operand; +def i32imm : Operand; +def i64imm : Operand; + +def f32imm : Operand; +def f64imm : Operand; + +/// zero_reg definition - Special node to stand for the zero register. +/// +def zero_reg; + +/// PredicateOperand - This can be used to define a predicate operand for an +/// instruction. OpTypes specifies the MIOperandInfo for the operand, and +/// AlwaysVal specifies the value of this predicate when set to "always +/// execute". +class PredicateOperand + : Operand { + let MIOperandInfo = OpTypes; + dag DefaultOps = AlwaysVal; +} + +/// OptionalDefOperand - This is used to define a optional definition operand +/// for an instruction. DefaultOps is the register the operand represents if none +/// is supplied, e.g. zero_reg. +class OptionalDefOperand + : Operand { + let MIOperandInfo = OpTypes; + dag DefaultOps = defaultops; +} + + +// InstrInfo - This class should only be instantiated once to provide parameters +// which are global to the the target machine. +// +class InstrInfo { + // If the target wants to associate some target-specific information with each + // instruction, it should provide these two lists to indicate how to assemble + // the target specific information into the 32 bits available. + // + list TSFlagsFields = []; + list TSFlagsShifts = []; + + // Target can specify its instructions in either big or little-endian formats. + // For instance, while both Sparc and PowerPC are big-endian platforms, the + // Sparc manual specifies its instructions in the format [31..0] (big), while + // PowerPC specifies them using the format [0..31] (little). + bit isLittleEndianEncoding = 0; +} + +// Standard Instructions. +def PHI : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops variable_ops); + let AsmString = "PHINODE"; + let Namespace = "TargetInstrInfo"; +} +def INLINEASM : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops variable_ops); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; +} +def DBG_LABEL : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops i32imm:$id); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let hasCtrlDep = 1; +} +def EH_LABEL : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops i32imm:$id); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let hasCtrlDep = 1; +} +def GC_LABEL : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops i32imm:$id); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let hasCtrlDep = 1; +} +def DECLARE : Instruction { + let OutOperandList = (ops); + let InOperandList = (ops variable_ops); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let hasCtrlDep = 1; +} +def EXTRACT_SUBREG : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$supersrc, i32imm:$subidx); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; +} +def INSERT_SUBREG : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; + let Constraints = "$supersrc = $dst"; +} +def IMPLICIT_DEF : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; + let isReMaterializable = 1; + let isAsCheapAsAMove = 1; +} +def SUBREG_TO_REG : Instruction { + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; + let neverHasSideEffects = 1; +} + +//===----------------------------------------------------------------------===// +// AsmWriter - This class can be implemented by targets that need to customize +// the format of the .s file writer. +// +// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax +// on X86 for example). +// +class AsmWriter { + // AsmWriterClassName - This specifies the suffix to use for the asmwriter + // class. Generated AsmWriter classes are always prefixed with the target + // name. + string AsmWriterClassName = "AsmPrinter"; + + // InstFormatName - AsmWriters can specify the name of the format string to + // print instructions with. + string InstFormatName = "AsmString"; + + // Variant - AsmWriters can be of multiple different variants. Variants are + // used to support targets that need to emit assembly code in ways that are + // mostly the same for different targets, but have minor differences in + // syntax. If the asmstring contains {|} characters in them, this integer + // will specify which alternative to use. For example "{x|y|z}" with Variant + // == 1, will expand to "y". + int Variant = 0; +} +def DefaultAsmWriter : AsmWriter; + + +//===----------------------------------------------------------------------===// +// Target - This class contains the "global" target information +// +class Target { + // InstructionSet - Instruction set description for this target. + InstrInfo InstructionSet; + + // AssemblyWriters - The AsmWriter instances available for this target. + list AssemblyWriters = [DefaultAsmWriter]; +} + +//===----------------------------------------------------------------------===// +// SubtargetFeature - A characteristic of the chip set. +// +class SubtargetFeature i = []> { + // Name - Feature name. Used by command line (-mattr=) to determine the + // appropriate target chip. + // + string Name = n; + + // Attribute - Attribute to be set by feature. + // + string Attribute = a; + + // Value - Value the attribute to be set to by feature. + // + string Value = v; + + // Desc - Feature description. Used by command line (-mattr=) to display help + // information. + // + string Desc = d; + + // Implies - Features that this feature implies are present. If one of those + // features isn't set, then this one shouldn't be set either. + // + list Implies = i; +} + +//===----------------------------------------------------------------------===// +// Processor chip sets - These values represent each of the chip sets supported +// by the scheduler. Each Processor definition requires corresponding +// instruction itineraries. +// +class Processor f> { + // Name - Chip set name. Used by command line (-mcpu=) to determine the + // appropriate target chip. + // + string Name = n; + + // ProcItin - The scheduling information for the target processor. + // + ProcessorItineraries ProcItin = pi; + + // Features - list of + list Features = f; +} + +//===----------------------------------------------------------------------===// +// Pull in the common support for calling conventions. +// +include "llvm/Target/TargetCallingConv.td" + +//===----------------------------------------------------------------------===// +// Pull in the common support for DAG isel generation. +// +include "llvm/Target/TargetSelectionDAG.td" Added: llvm/trunk/include/llvm/Target/TargetCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetCallingConv.td?rev=59953&view=auto ============================================================================== --- llvm/trunk/include/llvm/Target/TargetCallingConv.td (added) +++ llvm/trunk/include/llvm/Target/TargetCallingConv.td Mon Nov 24 01:34:46 2008 @@ -0,0 +1,103 @@ +//===- TargetCallingConv.td - Target Calling Conventions ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the target-independent interfaces with which targets +// describe their calling conventions. +// +//===----------------------------------------------------------------------===// + +class CCAction; +class CallingConv; + +/// CCPredicateAction - Instances of this class check some predicate, then +/// delegate to another action if the predicate is true. +class CCPredicateAction : CCAction { + CCAction SubAction = A; +} + +/// CCIfType - If the current argument is one of the specified types, apply +/// Action A. +class CCIfType vts, CCAction A> : CCPredicateAction { + list VTs = vts; +} + +/// CCIf - If the predicate matches, apply A. +class CCIf : CCPredicateAction { + string Predicate = predicate; +} + +/// CCIfByVal - If the current argument has ByVal parameter attribute, apply +/// Action A. +class CCIfByVal : CCIf<"ArgFlags.isByVal()", A> { +} + +/// CCIfCC - Match of the current calling convention is 'CC'. +class CCIfCC + : CCIf {} + +/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply +/// the specified action. +class CCIfInReg : CCIf<"ArgFlags.isInReg()", A> {} + +/// CCIfNest - If this argument is marked with the 'nest' attribute, apply +/// the specified action. +class CCIfNest : CCIf<"ArgFlags.isNest()", A> {} + +/// CCIfNotVarArg - If the current function is not vararg - apply the action +class CCIfNotVarArg : CCIf<"!State.isVarArg()", A> {} + +/// CCAssignToReg - This action matches if there is a register in the specified +/// list that is still available. If so, it assigns the value to the first +/// available register and succeeds. +class CCAssignToReg regList> : CCAction { + list RegList = regList; +} + +/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers +/// which became shadowed, when some register is used. +class CCAssignToRegWithShadow regList, + list shadowList> : CCAction { + list RegList = regList; + list ShadowRegList = shadowList; +} + +/// CCAssignToStack - This action always matches: it assigns the value to a +/// stack slot of the specified size and alignment on the stack. If size is +/// zero then the ABI size is used; if align is zero then the ABI alignment +/// is used - these may depend on the target or subtarget. +class CCAssignToStack : CCAction { + int Size = size; + int Align = align; +} + +/// CCPassByVal - This action always matches: it assigns the value to a stack +/// slot to implement ByVal aggregate parameter passing. Size and alignment +/// specify the minimum size and alignment for the stack slot. +class CCPassByVal : CCAction { + int Size = size; + int Align = align; +} + +/// CCPromoteToType - If applied, this promotes the specified current value to +/// the specified type. +class CCPromoteToType : CCAction { + ValueType DestTy = destTy; +} + +/// CCDelegateTo - This action invokes the specified sub-calling-convention. It +/// is successful if the specified CC matches. +class CCDelegateTo : CCAction { + CallingConv CC = cc; +} + +/// CallingConv - An instance of this is used to define each calling convention +/// that the target supports. +class CallingConv actions> { + list Actions = actions; +} Added: llvm/trunk/include/llvm/Target/TargetSchedule.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSchedule.td?rev=59953&view=auto ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSchedule.td (added) +++ llvm/trunk/include/llvm/Target/TargetSchedule.td Mon Nov 24 01:34:46 2008 @@ -0,0 +1,72 @@ +//===- TargetSchedule.td - Target Independent Scheduling ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the target-independent scheduling interfaces which should +// be implemented by each target which is using TableGen based scheduling. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Processor functional unit - These values represent the function units +// available across all chip sets for the target. Eg., IntUnit, FPUnit, ... +// These may be independent values for each chip set or may be shared across +// all chip sets of the target. Each functional unit is treated as a resource +// during scheduling and has an affect instruction order based on availability +// during a time interval. +// +class FuncUnit; + +//===----------------------------------------------------------------------===// +// Instruction stage - These values represent a step in the execution of an +// instruction. The latency represents the number of discrete time slots used +// need to complete the stage. Units represent the choice of functional units +// that can be used to complete the stage. Eg. IntUnit1, IntUnit2. +// +class InstrStage units> { + int Cycles = cycles; // length of stage in machine cycles + list Units = units; // choice of functional units +} + +//===----------------------------------------------------------------------===// +// Instruction itinerary - An itinerary represents a sequential series of steps +// required to complete an instruction. Itineraries are represented as lists of +// instruction stages. +// + +//===----------------------------------------------------------------------===// +// Instruction itinerary classes - These values represent 'named' instruction +// itinerary. Using named itineraries simplifies managing groups of +// instructions across chip sets. An instruction uses the same itinerary class +// across all chip sets. Thus a new chip set can be added without modifying +// instruction information. +// +class InstrItinClass; +def NoItinerary : InstrItinClass; + +//===----------------------------------------------------------------------===// +// Instruction itinerary data - These values provide a runtime map of an +// instruction itinerary class (name) to it's itinerary data. +// +class InstrItinData stages> { + InstrItinClass TheClass = Class; + list Stages = stages; +} + +//===----------------------------------------------------------------------===// +// Processor itineraries - These values represent the set of all itinerary +// classes for a given chip set. +// +class ProcessorItineraries iid> { + list IID = iid; +} + +// NoItineraries - A marker that can be used by processors without schedule +// info. +def NoItineraries : ProcessorItineraries<[]>; + Added: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=59953&view=auto ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (added) +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Nov 24 01:34:46 2008 @@ -0,0 +1,898 @@ +//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the target-independent interfaces used by SelectionDAG +// instruction selection generators. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Selection DAG Type Constraint definitions. +// +// Note that the semantics of these constraints are hard coded into tblgen. To +// modify or add constraints, you have to hack tblgen. +// + +class SDTypeConstraint { + int OperandNum = opnum; +} + +// SDTCisVT - The specified operand has exactly this VT. +class SDTCisVT : SDTypeConstraint { + ValueType VT = vt; +} + +class SDTCisPtrTy : SDTypeConstraint; + +// SDTCisInt - The specified operand is has integer type. +class SDTCisInt : SDTypeConstraint; + +// SDTCisFP - The specified operand is has floating point type. +class SDTCisFP : SDTypeConstraint; + +// SDTCisSameAs - The two specified operands have identical types. +class SDTCisSameAs : SDTypeConstraint { + int OtherOperandNum = OtherOp; +} + +// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is +// smaller than the 'Other' operand. +class SDTCisVTSmallerThanOp : SDTypeConstraint { + int OtherOperandNum = OtherOp; +} + +class SDTCisOpSmallerThanOp : SDTypeConstraint{ + int BigOperandNum = BigOp; +} + +/// SDTCisIntVectorOfSameSize - This indicates that ThisOp and OtherOp are +/// vector types, and that ThisOp is the result of +/// MVT::getIntVectorWithNumElements with the number of elements +/// that ThisOp has. +class SDTCisIntVectorOfSameSize + : SDTypeConstraint { + int OtherOpNum = OtherOp; +} + +/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same +/// type as the element type of OtherOp, which is a vector type. +class SDTCisEltOfVec + : SDTypeConstraint { + int OtherOpNum = OtherOp; +} + +//===----------------------------------------------------------------------===// +// Selection DAG Type Profile definitions. +// +// These use the constraints defined above to describe the type requirements of +// the various nodes. These are not hard coded into tblgen, allowing targets to +// add their own if needed. +// + +// SDTypeProfile - This profile describes the type requirements of a Selection +// DAG node. +class SDTypeProfile constraints> { + int NumResults = numresults; + int NumOperands = numoperands; + list Constraints = constraints; +} + +// Builtin profiles. +def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. +def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. +def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. +def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. +def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert. + +def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> +]>; +def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl + SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> +]>; +def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> +]>; +def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. + SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> +]>; +def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> +]>; +def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz + SDTCisSameAs<0, 1>, SDTCisInt<0> +]>; +def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0> +]>; +def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1> +]>; +def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc + SDTCisSameAs<0, 1>, SDTCisFP<0> +]>; +def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1> +]>; +def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0> +]>; +def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp + SDTCisFP<0>, SDTCisInt<1> +]>; +def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int + SDTCisInt<0>, SDTCisFP<1> +]>; +def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg + SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, + SDTCisVTSmallerThanOp<2, 1> +]>; + +def SDTSetCC : SDTypeProfile<1, 3, [ // setcc + SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> +]>; + +def SDTSelect : SDTypeProfile<1, 3, [ // select + SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> +]>; + +def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc + SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, + SDTCisVT<5, OtherVT> +]>; + +def SDTBr : SDTypeProfile<0, 1, [ // br + SDTCisVT<0, OtherVT> +]>; + +def SDTBrcond : SDTypeProfile<0, 2, [ // brcond + SDTCisInt<0>, SDTCisVT<1, OtherVT> +]>; + +def SDTBrind : SDTypeProfile<0, 1, [ // brind + SDTCisPtrTy<0> +]>; + +def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap + +def SDTLoad : SDTypeProfile<1, 1, [ // load + SDTCisPtrTy<1> +]>; + +def SDTStore : SDTypeProfile<0, 2, [ // store + SDTCisPtrTy<1> +]>; + +def SDTIStore : SDTypeProfile<1, 3, [ // indexed store + SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> +]>; + +def SDTVecShuffle : SDTypeProfile<1, 3, [ + SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisIntVectorOfSameSize<3, 0> +]>; +def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract + SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> +]>; +def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert + SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> +]>; + +def STDPrefetch : SDTypeProfile<0, 3, [ // prefetch + SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1> +]>; + +def STDMemBarrier : SDTypeProfile<0, 5, [ // memory barier + SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, + SDTCisInt<0> +]>; +def STDAtomic3 : SDTypeProfile<1, 3, [ + SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> +]>; +def STDAtomic2 : SDTypeProfile<1, 2, [ + SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> +]>; + +def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su + SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> +]>; + +class SDCallSeqStart constraints> : + SDTypeProfile<0, 1, constraints>; +class SDCallSeqEnd constraints> : + SDTypeProfile<0, 2, constraints>; + +//===----------------------------------------------------------------------===// +// Selection DAG Node Properties. +// +// Note: These are hard coded into tblgen. +// +class SDNodeProperty; +def SDNPCommutative : SDNodeProperty; // X op Y == Y op X +def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) +def SDNPHasChain : SDNodeProperty; // R/W chain operand and result +def SDNPOutFlag : SDNodeProperty; // Write a flag result +def SDNPInFlag : SDNodeProperty; // Read a flag operand +def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand +def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. +def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. +def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. +def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand + +//===----------------------------------------------------------------------===// +// Selection DAG Node definitions. +// +class SDNode props = [], string sdclass = "SDNode"> { + string Opcode = opcode; + string SDClass = sdclass; + list Properties = props; + SDTypeProfile TypeProfile = typeprof; +} + +def set; +def implicit; +def parallel; +def node; +def srcvalue; + +def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; +def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">; +def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; +def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; +def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; +def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; +def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; +def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], + "ConstantPoolSDNode">; +def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], + "ConstantPoolSDNode">; +def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], + "JumpTableSDNode">; +def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], + "JumpTableSDNode">; +def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], + "FrameIndexSDNode">; +def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], + "FrameIndexSDNode">; +def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], + "ExternalSymbolSDNode">; +def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], + "ExternalSymbolSDNode">; + +def add : SDNode<"ISD::ADD" , SDTIntBinOp , + [SDNPCommutative, SDNPAssociative]>; +def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; +def mul : SDNode<"ISD::MUL" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; +def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; +def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; +def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; +def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; +def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; +def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; +def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; +def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; +def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; +def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; +def and : SDNode<"ISD::AND" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def or : SDNode<"ISD::OR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def xor : SDNode<"ISD::XOR" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, + [SDNPCommutative, SDNPOutFlag]>; +def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, + [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>; +def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, + [SDNPOutFlag]>; +def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, + [SDNPOutFlag, SDNPInFlag]>; + +def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; +def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; +def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; +def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>; +def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>; +def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; +def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; +def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; +def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; +def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>; +def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; +def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; + + +def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; +def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; +def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; +def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; +def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; +def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; +def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; +def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; +def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; +def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; +def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; +def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; +def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; +def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; +def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; + +def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; +def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; +def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; + +def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; +def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; +def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; +def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; + +def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; +def select : SDNode<"ISD::SELECT" , SDTSelect>; +def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; +def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; + +def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; +def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; +def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; +def ret : SDNode<"ISD::RET" , SDTNone, [SDNPHasChain]>; +def trap : SDNode<"ISD::TRAP" , SDTNone, + [SDNPHasChain, SDNPSideEffect]>; + +def prefetch : SDNode<"ISD::PREFETCH" , STDPrefetch, + [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; + +def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier, + [SDNPHasChain, SDNPSideEffect]>; + +def atomic_cmp_swap_8 : SDNode<"ISD::ATOMIC_CMP_SWAP_8" , STDAtomic3, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_add_8 : SDNode<"ISD::ATOMIC_LOAD_ADD_8" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_swap_8 : SDNode<"ISD::ATOMIC_SWAP_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_sub_8 : SDNode<"ISD::ATOMIC_LOAD_SUB_8" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_and_8 : SDNode<"ISD::ATOMIC_LOAD_AND_8" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_or_8 : SDNode<"ISD::ATOMIC_LOAD_OR_8" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_xor_8 : SDNode<"ISD::ATOMIC_LOAD_XOR_8" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_nand_8: SDNode<"ISD::ATOMIC_LOAD_NAND_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_min_8 : SDNode<"ISD::ATOMIC_LOAD_MIN_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_max_8 : SDNode<"ISD::ATOMIC_LOAD_MAX_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umin_8 : SDNode<"ISD::ATOMIC_LOAD_UMIN_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umax_8 : SDNode<"ISD::ATOMIC_LOAD_UMAX_8", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_cmp_swap_16 : SDNode<"ISD::ATOMIC_CMP_SWAP_16" , STDAtomic3, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_add_16 : SDNode<"ISD::ATOMIC_LOAD_ADD_16" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_swap_16 : SDNode<"ISD::ATOMIC_SWAP_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_sub_16 : SDNode<"ISD::ATOMIC_LOAD_SUB_16" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_and_16 : SDNode<"ISD::ATOMIC_LOAD_AND_16" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_or_16 : SDNode<"ISD::ATOMIC_LOAD_OR_16" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_xor_16 : SDNode<"ISD::ATOMIC_LOAD_XOR_16" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_nand_16: SDNode<"ISD::ATOMIC_LOAD_NAND_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_min_16 : SDNode<"ISD::ATOMIC_LOAD_MIN_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_max_16 : SDNode<"ISD::ATOMIC_LOAD_MAX_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umin_16 : SDNode<"ISD::ATOMIC_LOAD_UMIN_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umax_16 : SDNode<"ISD::ATOMIC_LOAD_UMAX_16", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_cmp_swap_32 : SDNode<"ISD::ATOMIC_CMP_SWAP_32" , STDAtomic3, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_add_32 : SDNode<"ISD::ATOMIC_LOAD_ADD_32" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_swap_32 : SDNode<"ISD::ATOMIC_SWAP_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_sub_32 : SDNode<"ISD::ATOMIC_LOAD_SUB_32" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_and_32 : SDNode<"ISD::ATOMIC_LOAD_AND_32" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_or_32 : SDNode<"ISD::ATOMIC_LOAD_OR_32" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_xor_32 : SDNode<"ISD::ATOMIC_LOAD_XOR_32" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_nand_32: SDNode<"ISD::ATOMIC_LOAD_NAND_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_min_32 : SDNode<"ISD::ATOMIC_LOAD_MIN_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_max_32 : SDNode<"ISD::ATOMIC_LOAD_MAX_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umin_32 : SDNode<"ISD::ATOMIC_LOAD_UMIN_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umax_32 : SDNode<"ISD::ATOMIC_LOAD_UMAX_32", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_cmp_swap_64 : SDNode<"ISD::ATOMIC_CMP_SWAP_64" , STDAtomic3, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_add_64 : SDNode<"ISD::ATOMIC_LOAD_ADD_64" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_swap_64 : SDNode<"ISD::ATOMIC_SWAP_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_sub_64 : SDNode<"ISD::ATOMIC_LOAD_SUB_64" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_and_64 : SDNode<"ISD::ATOMIC_LOAD_AND_64" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_or_64 : SDNode<"ISD::ATOMIC_LOAD_OR_64" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_xor_64 : SDNode<"ISD::ATOMIC_LOAD_XOR_64" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_nand_64: SDNode<"ISD::ATOMIC_LOAD_NAND_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_min_64 : SDNode<"ISD::ATOMIC_LOAD_MIN_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_max_64 : SDNode<"ISD::ATOMIC_LOAD_MAX_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umin_64 : SDNode<"ISD::ATOMIC_LOAD_UMIN_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load_umax_64 : SDNode<"ISD::ATOMIC_LOAD_UMAX_64", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; + +// Do not use ld, st directly. Use load, extload, sextload, zextload, store, +// and truncst (see below). +def ld : SDNode<"ISD::LOAD" , SDTLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def st : SDNode<"ISD::STORE" , SDTStore, + [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; +def ist : SDNode<"ISD::STORE" , SDTIStore, + [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; + +def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; +def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>; +def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, + []>; +def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", + SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; +def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", + SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; + +def extract_subreg : SDNode<"ISD::EXTRACT_SUBREG", + SDTypeProfile<1, 2, []>>; +def insert_subreg : SDNode<"ISD::INSERT_SUBREG", + SDTypeProfile<1, 3, []>>; + +// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use +// these internally. Don't reference these directly. +def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", + SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, + [SDNPHasChain]>; +def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", + SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, + [SDNPHasChain]>; +def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", + SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; + +// Do not use cvt directly. Use cvt forms below +def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>; + +//===----------------------------------------------------------------------===// +// Selection DAG Condition Codes + +class CondCode; // ISD::CondCode enums +def SETOEQ : CondCode; def SETOGT : CondCode; +def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode; +def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode; +def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode; +def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode; + +def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode; +def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode; + + +//===----------------------------------------------------------------------===// +// Selection DAG Node Transformation Functions. +// +// This mechanism allows targets to manipulate nodes in the output DAG once a +// match has been formed. This is typically used to manipulate immediate +// values. +// +class SDNodeXForm { + SDNode Opcode = opc; + code XFormFunction = xformFunction; +} + +def NOOP_SDNodeXForm : SDNodeXForm; + + +//===----------------------------------------------------------------------===// +// Selection DAG Pattern Fragments. +// +// Pattern fragments are reusable chunks of dags that match specific things. +// They can take arguments and have C++ predicates that control whether they +// match. They are intended to make the patterns for common instructions more +// compact and readable. +// + +/// PatFrag - Represents a pattern fragment. This can match something on the +/// DAG, frame a single node to multiply nested other fragments. +/// +class PatFrag { + dag Operands = ops; + dag Fragment = frag; + code Predicate = pred; + SDNodeXForm OperandTransform = xform; +} + +// PatLeaf's are pattern fragments that have no operands. This is just a helper +// to define immediates and other common things concisely. +class PatLeaf + : PatFrag<(ops), frag, pred, xform>; + +// Leaf fragments. + +def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; +def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; + +def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; +def immAllOnesV: PatLeaf<(build_vector), [{ + return ISD::isBuildVectorAllOnes(N); +}]>; +def immAllOnesV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllOnes(N); +}]>; +def immAllZerosV: PatLeaf<(build_vector), [{ + return ISD::isBuildVectorAllZeros(N); +}]>; +def immAllZerosV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllZeros(N); +}]>; + + + +// Other helper fragments. +def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; +def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; +def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>; +def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; + +// load fragments. +def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + return cast(N)->getAddressingMode() == ISD::UNINDEXED; +}]>; +def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ + return cast(N)->getExtensionType() == ISD::NON_EXTLOAD; +}]>; + +// extending load fragments. +def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ + return cast(N)->getExtensionType() == ISD::EXTLOAD; +}]>; +def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ + return cast(N)->getExtensionType() == ISD::SEXTLOAD; +}]>; +def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ + return cast(N)->getExtensionType() == ISD::ZEXTLOAD; +}]>; + +def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i1; +}]>; +def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; +def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::f32; +}]>; +def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::f64; +}]>; + +def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i1; +}]>; +def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; + +def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i1; +}]>; +def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; + +// store fragments. +def unindexedstore : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + return cast(N)->getAddressingMode() == ISD::UNINDEXED; +}]>; +def store : PatFrag<(ops node:$val, node:$ptr), + (unindexedstore node:$val, node:$ptr), [{ + return !cast(N)->isTruncatingStore(); +}]>; + +// truncstore fragments. +def truncstore : PatFrag<(ops node:$val, node:$ptr), + (unindexedstore node:$val, node:$ptr), [{ + return cast(N)->isTruncatingStore(); +}]>; +def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; +def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::f32; +}]>; +def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), + (truncstore node:$val, node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::f64; +}]>; + +// indexed store fragments. +def istore : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + return !cast(N)->isTruncatingStore(); +}]>; + +def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), + (istore node:$val, node:$base, node:$offset), [{ + ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); + return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; +}]>; + +def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + return cast(N)->isTruncatingStore(); +}]>; +def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), + (itruncstore node:$val, node:$base, node:$offset), [{ + ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); + return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; +}]>; +def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), + (pre_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i1; +}]>; +def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), + (pre_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), + (pre_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (pre_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; +def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (pre_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::f32; +}]>; + +def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), + (istore node:$val, node:$ptr, node:$offset), [{ + ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); + return AM == ISD::POST_INC || AM == ISD::POST_DEC; +}]>; + +def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), + (itruncstore node:$val, node:$base, node:$offset), [{ + ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); + return AM == ISD::POST_INC || AM == ISD::POST_DEC; +}]>; +def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), + (post_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i1; +}]>; +def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), + (post_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), + (post_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (post_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; +def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (post_truncst node:$val, node:$base, node:$offset), [{ + return cast(N)->getMemoryVT() == MVT::f32; +}]>; + +// setcc convenience fragments. +def setoeq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOEQ)>; +def setogt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOGT)>; +def setoge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOGE)>; +def setolt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOLT)>; +def setole : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOLE)>; +def setone : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETONE)>; +def seto : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETO)>; +def setuo : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUO)>; +def setueq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUEQ)>; +def setugt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUGT)>; +def setuge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUGE)>; +def setult : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETULT)>; +def setule : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETULE)>; +def setune : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUNE)>; +def seteq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETEQ)>; +def setgt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETGT)>; +def setge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETGE)>; +def setlt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETLT)>; +def setle : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETLE)>; +def setne : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETNE)>; + +//===----------------------------------------------------------------------===// +// Selection DAG CONVERT_RNDSAT patterns + +def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_FF; + }]>; + +def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_SS; + }]>; + +def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_SU; + }]>; + +def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_US; + }]>; + +def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_UU; + }]>; + +def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_SF; + }]>; + +def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_UF; + }]>; + +def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_FS; + }]>; + +def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), + (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ + return cast(N)->getCvtCode() == ISD::CVT_FU; + }]>; + +//===----------------------------------------------------------------------===// +// Selection DAG Pattern Support. +// +// Patterns are what are actually matched against the target-flavored +// instruction selection DAG. Instructions defined by the target implicitly +// define patterns in most cases, but patterns can also be explicitly added when +// an operation is defined by a sequence of instructions (e.g. loading a large +// immediate value on RISC targets that do not support immediates as large as +// their GPRs). +// + +class Pattern resultInstrs> { + dag PatternToMatch = patternToMatch; + list ResultInstrs = resultInstrs; + list Predicates = []; // See class Instruction in Target.td. + int AddedComplexity = 0; // See class Instruction in Target.td. +} + +// Pat - A simple (but common) form of a pattern, which produces a simple result +// not needing a full list. +class Pat : Pattern; + +//===----------------------------------------------------------------------===// +// Complex pattern definitions. +// + +class CPAttribute; +// Pass the parent Operand as root to CP function rather +// than the root of the sub-DAG +def CPAttrParentAsRoot : CPAttribute; + +// Complex patterns, e.g. X86 addressing mode, requires pattern matching code +// in C++. NumOperands is the number of operands returned by the select function; +// SelectFunc is the name of the function used to pattern match the max. pattern; +// RootNodes are the list of possible root nodes of the sub-dags to match. +// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; +// +class ComplexPattern roots = [], list props = [], + list attrs = []> { + ValueType Ty = ty; + int NumOperands = numops; + string SelectFunc = fn; + list RootNodes = roots; + list Properties = props; + list Attributes = attrs; +} + +//===----------------------------------------------------------------------===// +// Dwarf support. +// +def SDT_dwarf_loc : SDTypeProfile<0, 3, + [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; +def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; Modified: llvm/trunk/lib/Target/ARM/ARM.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARM.td (original) +++ llvm/trunk/lib/Target/ARM/ARM.td Mon Nov 24 01:34:46 2008 @@ -14,7 +14,7 @@ // Target-independent interfaces which we are implementing //===----------------------------------------------------------------------===// -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // ARM Subtarget features. Modified: llvm/trunk/lib/Target/Alpha/Alpha.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/Alpha.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/Alpha.td (original) +++ llvm/trunk/lib/Target/Alpha/Alpha.td Mon Nov 24 01:34:46 2008 @@ -12,7 +12,7 @@ // Get the target-independent interfaces which we are implementing... // -include "../Target.td" +include "llvm/Target/Target.td" //Alpha is little endian Modified: llvm/trunk/lib/Target/CellSPU/SPU.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPU.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPU.td Mon Nov 24 01:34:46 2008 @@ -13,7 +13,7 @@ // Get the target-independent interfaces which we are implementing. // -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // Register File Description Modified: llvm/trunk/lib/Target/IA64/IA64.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64.td (original) +++ llvm/trunk/lib/Target/IA64/IA64.td Mon Nov 24 01:34:46 2008 @@ -14,7 +14,7 @@ // Get the target-independent interfaces which we are implementing... // -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // Register File Description Modified: llvm/trunk/lib/Target/Mips/Mips.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/Mips.td (original) +++ llvm/trunk/lib/Target/Mips/Mips.td Mon Nov 24 01:34:46 2008 @@ -13,7 +13,7 @@ // Target-independent interfaces //===----------------------------------------------------------------------===// -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // Register File, Calling Conv, Instruction Descriptions Modified: llvm/trunk/lib/Target/PIC16/PIC16.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16.td Mon Nov 24 01:34:46 2008 @@ -13,7 +13,7 @@ // Target-independent interfaces //===----------------------------------------------------------------------===// -include "../Target.td" +include "llvm/Target/Target.td" include "PIC16RegisterInfo.td" include "PIC16InstrInfo.td" Modified: llvm/trunk/lib/Target/PowerPC/PPC.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPC.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPC.td Mon Nov 24 01:34:46 2008 @@ -13,7 +13,7 @@ // Get the target-independent interfaces which we are implementing. // -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // PowerPC Subtarget features. Modified: llvm/trunk/lib/Target/Sparc/Sparc.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/Sparc.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/Sparc.td (original) +++ llvm/trunk/lib/Target/Sparc/Sparc.td Mon Nov 24 01:34:46 2008 @@ -14,7 +14,7 @@ // Target-independent interfaces which we are implementing //===----------------------------------------------------------------------===// -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // SPARC Subtarget features. Removed: llvm/trunk/lib/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=59952&view=auto ============================================================================== --- llvm/trunk/lib/Target/Target.td (original) +++ llvm/trunk/lib/Target/Target.td (removed) @@ -1,499 +0,0 @@ -//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the target-independent interfaces which should be -// implemented by each target which is using a TableGen based code generator. -// -//===----------------------------------------------------------------------===// - -// Include all information about LLVM intrinsics. -include "llvm/Intrinsics.td" - -//===----------------------------------------------------------------------===// -// Register file description - These classes are used to fill in the target -// description classes. - -class RegisterClass; // Forward def - -// Register - You should define one instance of this class for each register -// in the target machine. String n will become the "name" of the register. -class Register { - string Namespace = ""; - string AsmName = n; - - // SpillSize - If this value is set to a non-zero value, it is the size in - // bits of the spill slot required to hold this register. If this value is - // set to zero, the information is inferred from any register classes the - // register belongs to. - int SpillSize = 0; - - // SpillAlignment - This value is used to specify the alignment required for - // spilling the register. Like SpillSize, this should only be explicitly - // specified if the register is not in a register class. - int SpillAlignment = 0; - - // Aliases - A list of registers that this register overlaps with. A read or - // modification of this register can potentially read or modify the aliased - // registers. - list Aliases = []; - - // SubRegs - A list of registers that are parts of this register. Note these - // are "immediate" sub-registers and the registers within the list do not - // themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX], - // not [AX, AH, AL]. - list SubRegs = []; - - // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. - // These values can be determined by locating the .h file in the - // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The - // order of these names correspond to the enumeration used by gcc. A value of - // -1 indicates that the gcc number is undefined and -2 that register number - // is invalid for this mode/flavour. - list DwarfNumbers = []; -} - -// RegisterWithSubRegs - This can be used to define instances of Register which -// need to specify sub-registers. -// List "subregs" specifies which registers are sub-registers to this one. This -// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc. -// This allows the code generator to be careful not to put two values with -// overlapping live ranges into registers which alias. -class RegisterWithSubRegs subregs> : Register { - let SubRegs = subregs; -} - -// SubRegSet - This can be used to define a specific mapping of registers to -// indices, for use as named subregs of a particular physical register. Each -// register in 'subregs' becomes an addressable subregister at index 'n' of the -// corresponding register in 'regs'. -class SubRegSet regs, list subregs> { - int index = n; - - list From = regs; - list To = subregs; -} - -// RegisterClass - Now that all of the registers are defined, and aliases -// between registers are defined, specify which registers belong to which -// register classes. This also defines the default allocation order of -// registers by register allocators. -// -class RegisterClass regTypes, int alignment, - list regList> { - string Namespace = namespace; - - // RegType - Specify the list ValueType of the registers in this register - // class. Note that all registers in a register class must have the same - // ValueTypes. This is a list because some targets permit storing different - // types in same register, for example vector values with 128-bit total size, - // but different count/size of items, like SSE on x86. - // - list RegTypes = regTypes; - - // Size - Specify the spill size in bits of the registers. A default value of - // zero lets tablgen pick an appropriate size. - int Size = 0; - - // Alignment - Specify the alignment required of the registers when they are - // stored or loaded to memory. - // - int Alignment = alignment; - - // CopyCost - This value is used to specify the cost of copying a value - // between two registers in this register class. The default value is one - // meaning it takes a single instruction to perform the copying. A negative - // value means copying is extremely expensive or impossible. - int CopyCost = 1; - - // MemberList - Specify which registers are in this class. If the - // allocation_order_* method are not specified, this also defines the order of - // allocation used by the register allocator. - // - list MemberList = regList; - - // SubClassList - Specify which register classes correspond to subregisters - // of this class. The order should be by subregister set index. - list SubRegClassList = []; - - // MethodProtos/MethodBodies - These members can be used to insert arbitrary - // code into a generated register class. The normal usage of this is to - // overload virtual methods. - code MethodProtos = [{}]; - code MethodBodies = [{}]; -} - - -//===----------------------------------------------------------------------===// -// DwarfRegNum - This class provides a mapping of the llvm register enumeration -// to the register numbering used by gcc and gdb. These values are used by a -// debug information writer (ex. DwarfWriter) to describe where values may be -// located during execution. -class DwarfRegNum Numbers> { - // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. - // These values can be determined by locating the .h file in the - // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The - // order of these names correspond to the enumeration used by gcc. A value of - // -1 indicates that the gcc number is undefined and -2 that register number is - // invalid for this mode/flavour. - list DwarfNumbers = Numbers; -} - -//===----------------------------------------------------------------------===// -// Pull in the common support for scheduling -// -include "TargetSchedule.td" - -class Predicate; // Forward def - -//===----------------------------------------------------------------------===// -// Instruction set description - These classes correspond to the C++ classes in -// the Target/TargetInstrInfo.h file. -// -class Instruction { - string Namespace = ""; - - dag OutOperandList; // An dag containing the MI def operand list. - dag InOperandList; // An dag containing the MI use operand list. - string AsmString = ""; // The .s format to print the instruction with. - - // Pattern - Set to the DAG pattern for this instruction, if we know of one, - // otherwise, uninitialized. - list Pattern; - - // The follow state will eventually be inferred automatically from the - // instruction pattern. - - list Uses = []; // Default to using no non-operand registers - list Defs = []; // Default to modifying no non-operand registers - - // Predicates - List of predicates which will be turned into isel matching - // code. - list Predicates = []; - - // Code size. - int CodeSize = 0; - - // Added complexity passed onto matching pattern. - int AddedComplexity = 0; - - // These bits capture information about the high-level semantics of the - // instruction. - bit isReturn = 0; // Is this instruction a return instruction? - bit isBranch = 0; // Is this instruction a branch instruction? - bit isIndirectBranch = 0; // Is this instruction an indirect branch? - bit isBarrier = 0; // Can control flow fall through this instruction? - bit isCall = 0; // Is this instruction a call instruction? - bit isSimpleLoad = 0; // Is this just a load instruction? - bit mayLoad = 0; // Is it possible for this inst to read memory? - bit mayStore = 0; // Is it possible for this inst to write memory? - bit isTwoAddress = 0; // Is this a two address instruction? - bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? - bit isCommutable = 0; // Is this 3 operand instruction commutable? - bit isTerminator = 0; // Is this part of the terminator for a basic block? - bit isReMaterializable = 0; // Is this instruction re-materializable? - bit isPredicable = 0; // Is this instruction predicable? - bit hasDelaySlot = 0; // Does this instruction have an delay slot? - bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help. - bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? - bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? - bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. - - // Side effect flags - When set, the flags have these meanings: - // - // hasSideEffects - The instruction has side effects that are not - // captured by any operands of the instruction or other flags. - // - // mayHaveSideEffects - Some instances of the instruction can have side - // effects. The virtual method "isReallySideEffectFree" is called to - // determine this. Load instructions are an example of where this is - // useful. In general, loads always have side effects. However, loads from - // constant pools don't. Individual back ends make this determination. - // - // neverHasSideEffects - Set on an instruction with no pattern if it has no - // side effects. - bit hasSideEffects = 0; - bit mayHaveSideEffects = 0; - bit neverHasSideEffects = 0; - - InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. - - string Constraints = ""; // OperandConstraint, e.g. $src = $dst. - - /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not - /// be encoded into the output machineinstr. - string DisableEncoding = ""; -} - -/// Predicates - These are extra conditionals which are turned into instruction -/// selector matching code. Currently each predicate is just a string. -class Predicate { - string CondString = cond; -} - -/// NoHonorSignDependentRounding - This predicate is true if support for -/// sign-dependent-rounding is not enabled. -def NoHonorSignDependentRounding - : Predicate<"!HonorSignDependentRoundingFPMath()">; - -class Requires preds> { - list Predicates = preds; -} - -/// ops definition - This is just a simple marker used to identify the operands -/// list for an instruction. outs and ins are identical both syntatically and -/// semantically, they are used to define def operands and use operands to -/// improve readibility. This should be used like this: -/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar. -def ops; -def outs; -def ins; - -/// variable_ops definition - Mark this instruction as taking a variable number -/// of operands. -def variable_ops; - -/// ptr_rc definition - Mark this operand as being a pointer value whose -/// register class is resolved dynamically via a callback to TargetInstrInfo. -/// FIXME: We should probably change this to a class which contain a list of -/// flags. But currently we have but one flag. -def ptr_rc; - -/// unknown definition - Mark this operand as being of unknown type, causing -/// it to be resolved by inference in the context it is used. -def unknown; - -/// Operand Types - These provide the built-in operand types that may be used -/// by a target. Targets can optionally provide their own operand types as -/// needed, though this should not be needed for RISC targets. -class Operand { - ValueType Type = ty; - string PrintMethod = "printOperand"; - dag MIOperandInfo = (ops); -} - -def i1imm : Operand; -def i8imm : Operand; -def i16imm : Operand; -def i32imm : Operand; -def i64imm : Operand; - -def f32imm : Operand; -def f64imm : Operand; - -/// zero_reg definition - Special node to stand for the zero register. -/// -def zero_reg; - -/// PredicateOperand - This can be used to define a predicate operand for an -/// instruction. OpTypes specifies the MIOperandInfo for the operand, and -/// AlwaysVal specifies the value of this predicate when set to "always -/// execute". -class PredicateOperand - : Operand { - let MIOperandInfo = OpTypes; - dag DefaultOps = AlwaysVal; -} - -/// OptionalDefOperand - This is used to define a optional definition operand -/// for an instruction. DefaultOps is the register the operand represents if none -/// is supplied, e.g. zero_reg. -class OptionalDefOperand - : Operand { - let MIOperandInfo = OpTypes; - dag DefaultOps = defaultops; -} - - -// InstrInfo - This class should only be instantiated once to provide parameters -// which are global to the the target machine. -// -class InstrInfo { - // If the target wants to associate some target-specific information with each - // instruction, it should provide these two lists to indicate how to assemble - // the target specific information into the 32 bits available. - // - list TSFlagsFields = []; - list TSFlagsShifts = []; - - // Target can specify its instructions in either big or little-endian formats. - // For instance, while both Sparc and PowerPC are big-endian platforms, the - // Sparc manual specifies its instructions in the format [31..0] (big), while - // PowerPC specifies them using the format [0..31] (little). - bit isLittleEndianEncoding = 0; -} - -// Standard Instructions. -def PHI : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); - let AsmString = "PHINODE"; - let Namespace = "TargetInstrInfo"; -} -def INLINEASM : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; -} -def DBG_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let hasCtrlDep = 1; -} -def EH_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let hasCtrlDep = 1; -} -def GC_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let hasCtrlDep = 1; -} -def DECLARE : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let hasCtrlDep = 1; -} -def EXTRACT_SUBREG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$supersrc, i32imm:$subidx); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let neverHasSideEffects = 1; -} -def INSERT_SUBREG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let neverHasSideEffects = 1; - let Constraints = "$supersrc = $dst"; -} -def IMPLICIT_DEF : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let neverHasSideEffects = 1; - let isReMaterializable = 1; - let isAsCheapAsAMove = 1; -} -def SUBREG_TO_REG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); - let AsmString = ""; - let Namespace = "TargetInstrInfo"; - let neverHasSideEffects = 1; -} - -//===----------------------------------------------------------------------===// -// AsmWriter - This class can be implemented by targets that need to customize -// the format of the .s file writer. -// -// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax -// on X86 for example). -// -class AsmWriter { - // AsmWriterClassName - This specifies the suffix to use for the asmwriter - // class. Generated AsmWriter classes are always prefixed with the target - // name. - string AsmWriterClassName = "AsmPrinter"; - - // InstFormatName - AsmWriters can specify the name of the format string to - // print instructions with. - string InstFormatName = "AsmString"; - - // Variant - AsmWriters can be of multiple different variants. Variants are - // used to support targets that need to emit assembly code in ways that are - // mostly the same for different targets, but have minor differences in - // syntax. If the asmstring contains {|} characters in them, this integer - // will specify which alternative to use. For example "{x|y|z}" with Variant - // == 1, will expand to "y". - int Variant = 0; -} -def DefaultAsmWriter : AsmWriter; - - -//===----------------------------------------------------------------------===// -// Target - This class contains the "global" target information -// -class Target { - // InstructionSet - Instruction set description for this target. - InstrInfo InstructionSet; - - // AssemblyWriters - The AsmWriter instances available for this target. - list AssemblyWriters = [DefaultAsmWriter]; -} - -//===----------------------------------------------------------------------===// -// SubtargetFeature - A characteristic of the chip set. -// -class SubtargetFeature i = []> { - // Name - Feature name. Used by command line (-mattr=) to determine the - // appropriate target chip. - // - string Name = n; - - // Attribute - Attribute to be set by feature. - // - string Attribute = a; - - // Value - Value the attribute to be set to by feature. - // - string Value = v; - - // Desc - Feature description. Used by command line (-mattr=) to display help - // information. - // - string Desc = d; - - // Implies - Features that this feature implies are present. If one of those - // features isn't set, then this one shouldn't be set either. - // - list Implies = i; -} - -//===----------------------------------------------------------------------===// -// Processor chip sets - These values represent each of the chip sets supported -// by the scheduler. Each Processor definition requires corresponding -// instruction itineraries. -// -class Processor f> { - // Name - Chip set name. Used by command line (-mcpu=) to determine the - // appropriate target chip. - // - string Name = n; - - // ProcItin - The scheduling information for the target processor. - // - ProcessorItineraries ProcItin = pi; - - // Features - list of - list Features = f; -} - -//===----------------------------------------------------------------------===// -// Pull in the common support for calling conventions. -// -include "TargetCallingConv.td" - -//===----------------------------------------------------------------------===// -// Pull in the common support for DAG isel generation. -// -include "TargetSelectionDAG.td" Removed: llvm/trunk/lib/Target/TargetCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetCallingConv.td?rev=59952&view=auto ============================================================================== --- llvm/trunk/lib/Target/TargetCallingConv.td (original) +++ llvm/trunk/lib/Target/TargetCallingConv.td (removed) @@ -1,103 +0,0 @@ -//===- TargetCallingConv.td - Target Calling Conventions ---*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the target-independent interfaces with which targets -// describe their calling conventions. -// -//===----------------------------------------------------------------------===// - -class CCAction; -class CallingConv; - -/// CCPredicateAction - Instances of this class check some predicate, then -/// delegate to another action if the predicate is true. -class CCPredicateAction : CCAction { - CCAction SubAction = A; -} - -/// CCIfType - If the current argument is one of the specified types, apply -/// Action A. -class CCIfType vts, CCAction A> : CCPredicateAction { - list VTs = vts; -} - -/// CCIf - If the predicate matches, apply A. -class CCIf : CCPredicateAction { - string Predicate = predicate; -} - -/// CCIfByVal - If the current argument has ByVal parameter attribute, apply -/// Action A. -class CCIfByVal : CCIf<"ArgFlags.isByVal()", A> { -} - -/// CCIfCC - Match of the current calling convention is 'CC'. -class CCIfCC - : CCIf {} - -/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply -/// the specified action. -class CCIfInReg : CCIf<"ArgFlags.isInReg()", A> {} - -/// CCIfNest - If this argument is marked with the 'nest' attribute, apply -/// the specified action. -class CCIfNest : CCIf<"ArgFlags.isNest()", A> {} - -/// CCIfNotVarArg - If the current function is not vararg - apply the action -class CCIfNotVarArg : CCIf<"!State.isVarArg()", A> {} - -/// CCAssignToReg - This action matches if there is a register in the specified -/// list that is still available. If so, it assigns the value to the first -/// available register and succeeds. -class CCAssignToReg regList> : CCAction { - list RegList = regList; -} - -/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers -/// which became shadowed, when some register is used. -class CCAssignToRegWithShadow regList, - list shadowList> : CCAction { - list RegList = regList; - list ShadowRegList = shadowList; -} - -/// CCAssignToStack - This action always matches: it assigns the value to a -/// stack slot of the specified size and alignment on the stack. If size is -/// zero then the ABI size is used; if align is zero then the ABI alignment -/// is used - these may depend on the target or subtarget. -class CCAssignToStack : CCAction { - int Size = size; - int Align = align; -} - -/// CCPassByVal - This action always matches: it assigns the value to a stack -/// slot to implement ByVal aggregate parameter passing. Size and alignment -/// specify the minimum size and alignment for the stack slot. -class CCPassByVal : CCAction { - int Size = size; - int Align = align; -} - -/// CCPromoteToType - If applied, this promotes the specified current value to -/// the specified type. -class CCPromoteToType : CCAction { - ValueType DestTy = destTy; -} - -/// CCDelegateTo - This action invokes the specified sub-calling-convention. It -/// is successful if the specified CC matches. -class CCDelegateTo : CCAction { - CallingConv CC = cc; -} - -/// CallingConv - An instance of this is used to define each calling convention -/// that the target supports. -class CallingConv actions> { - list Actions = actions; -} Removed: llvm/trunk/lib/Target/TargetSchedule.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSchedule.td?rev=59952&view=auto ============================================================================== --- llvm/trunk/lib/Target/TargetSchedule.td (original) +++ llvm/trunk/lib/Target/TargetSchedule.td (removed) @@ -1,72 +0,0 @@ -//===- TargetSchedule.td - Target Independent Scheduling ---*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the target-independent scheduling interfaces which should -// be implemented by each target which is using TableGen based scheduling. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Processor functional unit - These values represent the function units -// available across all chip sets for the target. Eg., IntUnit, FPUnit, ... -// These may be independent values for each chip set or may be shared across -// all chip sets of the target. Each functional unit is treated as a resource -// during scheduling and has an affect instruction order based on availability -// during a time interval. -// -class FuncUnit; - -//===----------------------------------------------------------------------===// -// Instruction stage - These values represent a step in the execution of an -// instruction. The latency represents the number of discrete time slots used -// need to complete the stage. Units represent the choice of functional units -// that can be used to complete the stage. Eg. IntUnit1, IntUnit2. -// -class InstrStage units> { - int Cycles = cycles; // length of stage in machine cycles - list Units = units; // choice of functional units -} - -//===----------------------------------------------------------------------===// -// Instruction itinerary - An itinerary represents a sequential series of steps -// required to complete an instruction. Itineraries are represented as lists of -// instruction stages. -// - -//===----------------------------------------------------------------------===// -// Instruction itinerary classes - These values represent 'named' instruction -// itinerary. Using named itineraries simplifies managing groups of -// instructions across chip sets. An instruction uses the same itinerary class -// across all chip sets. Thus a new chip set can be added without modifying -// instruction information. -// -class InstrItinClass; -def NoItinerary : InstrItinClass; - -//===----------------------------------------------------------------------===// -// Instruction itinerary data - These values provide a runtime map of an -// instruction itinerary class (name) to it's itinerary data. -// -class InstrItinData stages> { - InstrItinClass TheClass = Class; - list Stages = stages; -} - -//===----------------------------------------------------------------------===// -// Processor itineraries - These values represent the set of all itinerary -// classes for a given chip set. -// -class ProcessorItineraries iid> { - list IID = iid; -} - -// NoItineraries - A marker that can be used by processors without schedule -// info. -def NoItineraries : ProcessorItineraries<[]>; - Removed: llvm/trunk/lib/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=59952&view=auto ============================================================================== --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/lib/Target/TargetSelectionDAG.td (removed) @@ -1,898 +0,0 @@ -//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the target-independent interfaces used by SelectionDAG -// instruction selection generators. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Selection DAG Type Constraint definitions. -// -// Note that the semantics of these constraints are hard coded into tblgen. To -// modify or add constraints, you have to hack tblgen. -// - -class SDTypeConstraint { - int OperandNum = opnum; -} - -// SDTCisVT - The specified operand has exactly this VT. -class SDTCisVT : SDTypeConstraint { - ValueType VT = vt; -} - -class SDTCisPtrTy : SDTypeConstraint; - -// SDTCisInt - The specified operand is has integer type. -class SDTCisInt : SDTypeConstraint; - -// SDTCisFP - The specified operand is has floating point type. -class SDTCisFP : SDTypeConstraint; - -// SDTCisSameAs - The two specified operands have identical types. -class SDTCisSameAs : SDTypeConstraint { - int OtherOperandNum = OtherOp; -} - -// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is -// smaller than the 'Other' operand. -class SDTCisVTSmallerThanOp : SDTypeConstraint { - int OtherOperandNum = OtherOp; -} - -class SDTCisOpSmallerThanOp : SDTypeConstraint{ - int BigOperandNum = BigOp; -} - -/// SDTCisIntVectorOfSameSize - This indicates that ThisOp and OtherOp are -/// vector types, and that ThisOp is the result of -/// MVT::getIntVectorWithNumElements with the number of elements -/// that ThisOp has. -class SDTCisIntVectorOfSameSize - : SDTypeConstraint { - int OtherOpNum = OtherOp; -} - -/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same -/// type as the element type of OtherOp, which is a vector type. -class SDTCisEltOfVec - : SDTypeConstraint { - int OtherOpNum = OtherOp; -} - -//===----------------------------------------------------------------------===// -// Selection DAG Type Profile definitions. -// -// These use the constraints defined above to describe the type requirements of -// the various nodes. These are not hard coded into tblgen, allowing targets to -// add their own if needed. -// - -// SDTypeProfile - This profile describes the type requirements of a Selection -// DAG node. -class SDTypeProfile constraints> { - int NumResults = numresults; - int NumOperands = numoperands; - list Constraints = constraints; -} - -// Builtin profiles. -def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. -def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. -def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. -def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. -def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. -def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert. - -def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> -]>; -def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl - SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> -]>; -def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> -]>; -def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. - SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> -]>; -def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. - SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> -]>; -def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz - SDTCisSameAs<0, 1>, SDTCisInt<0> -]>; -def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext - SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0> -]>; -def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc - SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1> -]>; -def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc - SDTCisSameAs<0, 1>, SDTCisFP<0> -]>; -def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround - SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1> -]>; -def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend - SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0> -]>; -def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp - SDTCisFP<0>, SDTCisInt<1> -]>; -def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int - SDTCisInt<0>, SDTCisFP<1> -]>; -def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg - SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, - SDTCisVTSmallerThanOp<2, 1> -]>; - -def SDTSetCC : SDTypeProfile<1, 3, [ // setcc - SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> -]>; - -def SDTSelect : SDTypeProfile<1, 3, [ // select - SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> -]>; - -def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc - SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, - SDTCisVT<5, OtherVT> -]>; - -def SDTBr : SDTypeProfile<0, 1, [ // br - SDTCisVT<0, OtherVT> -]>; - -def SDTBrcond : SDTypeProfile<0, 2, [ // brcond - SDTCisInt<0>, SDTCisVT<1, OtherVT> -]>; - -def SDTBrind : SDTypeProfile<0, 1, [ // brind - SDTCisPtrTy<0> -]>; - -def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap - -def SDTLoad : SDTypeProfile<1, 1, [ // load - SDTCisPtrTy<1> -]>; - -def SDTStore : SDTypeProfile<0, 2, [ // store - SDTCisPtrTy<1> -]>; - -def SDTIStore : SDTypeProfile<1, 3, [ // indexed store - SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> -]>; - -def SDTVecShuffle : SDTypeProfile<1, 3, [ - SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisIntVectorOfSameSize<3, 0> -]>; -def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract - SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> -]>; -def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert - SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> -]>; - -def STDPrefetch : SDTypeProfile<0, 3, [ // prefetch - SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1> -]>; - -def STDMemBarrier : SDTypeProfile<0, 5, [ // memory barier - SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, - SDTCisInt<0> -]>; -def STDAtomic3 : SDTypeProfile<1, 3, [ - SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> -]>; -def STDAtomic2 : SDTypeProfile<1, 2, [ - SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> -]>; - -def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su - SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> -]>; - -class SDCallSeqStart constraints> : - SDTypeProfile<0, 1, constraints>; -class SDCallSeqEnd constraints> : - SDTypeProfile<0, 2, constraints>; - -//===----------------------------------------------------------------------===// -// Selection DAG Node Properties. -// -// Note: These are hard coded into tblgen. -// -class SDNodeProperty; -def SDNPCommutative : SDNodeProperty; // X op Y == Y op X -def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) -def SDNPHasChain : SDNodeProperty; // R/W chain operand and result -def SDNPOutFlag : SDNodeProperty; // Write a flag result -def SDNPInFlag : SDNodeProperty; // Read a flag operand -def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand -def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. -def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. -def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. -def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand - -//===----------------------------------------------------------------------===// -// Selection DAG Node definitions. -// -class SDNode props = [], string sdclass = "SDNode"> { - string Opcode = opcode; - string SDClass = sdclass; - list Properties = props; - SDTypeProfile TypeProfile = typeprof; -} - -def set; -def implicit; -def parallel; -def node; -def srcvalue; - -def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; -def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">; -def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; -def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; -def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; -def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; -def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; -def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], - "GlobalAddressSDNode">; -def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], - "GlobalAddressSDNode">; -def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], - "GlobalAddressSDNode">; -def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], - "GlobalAddressSDNode">; -def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], - "ConstantPoolSDNode">; -def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], - "ConstantPoolSDNode">; -def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], - "JumpTableSDNode">; -def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], - "JumpTableSDNode">; -def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], - "FrameIndexSDNode">; -def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], - "FrameIndexSDNode">; -def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], - "ExternalSymbolSDNode">; -def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], - "ExternalSymbolSDNode">; - -def add : SDNode<"ISD::ADD" , SDTIntBinOp , - [SDNPCommutative, SDNPAssociative]>; -def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; -def mul : SDNode<"ISD::MUL" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; -def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; -def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; -def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; -def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; -def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; -def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; -def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; -def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; -def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; -def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; -def and : SDNode<"ISD::AND" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def or : SDNode<"ISD::OR" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def xor : SDNode<"ISD::XOR" , SDTIntBinOp, - [SDNPCommutative, SDNPAssociative]>; -def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, - [SDNPCommutative, SDNPOutFlag]>; -def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, - [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>; -def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, - [SDNPOutFlag]>; -def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, - [SDNPOutFlag, SDNPInFlag]>; - -def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; -def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; -def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; -def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>; -def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>; -def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; -def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; -def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; -def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; -def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>; -def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; -def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; - - -def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; -def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; -def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; -def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; -def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; -def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; -def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; -def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; -def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; -def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; -def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; -def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; -def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; -def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; -def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; - -def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; -def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; -def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; - -def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; -def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; -def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; -def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; - -def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; -def select : SDNode<"ISD::SELECT" , SDTSelect>; -def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; -def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; - -def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; -def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; -def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; -def ret : SDNode<"ISD::RET" , SDTNone, [SDNPHasChain]>; -def trap : SDNode<"ISD::TRAP" , SDTNone, - [SDNPHasChain, SDNPSideEffect]>; - -def prefetch : SDNode<"ISD::PREFETCH" , STDPrefetch, - [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; - -def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier, - [SDNPHasChain, SDNPSideEffect]>; - -def atomic_cmp_swap_8 : SDNode<"ISD::ATOMIC_CMP_SWAP_8" , STDAtomic3, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_add_8 : SDNode<"ISD::ATOMIC_LOAD_ADD_8" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_swap_8 : SDNode<"ISD::ATOMIC_SWAP_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_sub_8 : SDNode<"ISD::ATOMIC_LOAD_SUB_8" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_and_8 : SDNode<"ISD::ATOMIC_LOAD_AND_8" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_or_8 : SDNode<"ISD::ATOMIC_LOAD_OR_8" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_xor_8 : SDNode<"ISD::ATOMIC_LOAD_XOR_8" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_nand_8: SDNode<"ISD::ATOMIC_LOAD_NAND_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_min_8 : SDNode<"ISD::ATOMIC_LOAD_MIN_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_max_8 : SDNode<"ISD::ATOMIC_LOAD_MAX_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umin_8 : SDNode<"ISD::ATOMIC_LOAD_UMIN_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umax_8 : SDNode<"ISD::ATOMIC_LOAD_UMAX_8", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_cmp_swap_16 : SDNode<"ISD::ATOMIC_CMP_SWAP_16" , STDAtomic3, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_add_16 : SDNode<"ISD::ATOMIC_LOAD_ADD_16" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_swap_16 : SDNode<"ISD::ATOMIC_SWAP_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_sub_16 : SDNode<"ISD::ATOMIC_LOAD_SUB_16" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_and_16 : SDNode<"ISD::ATOMIC_LOAD_AND_16" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_or_16 : SDNode<"ISD::ATOMIC_LOAD_OR_16" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_xor_16 : SDNode<"ISD::ATOMIC_LOAD_XOR_16" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_nand_16: SDNode<"ISD::ATOMIC_LOAD_NAND_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_min_16 : SDNode<"ISD::ATOMIC_LOAD_MIN_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_max_16 : SDNode<"ISD::ATOMIC_LOAD_MAX_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umin_16 : SDNode<"ISD::ATOMIC_LOAD_UMIN_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umax_16 : SDNode<"ISD::ATOMIC_LOAD_UMAX_16", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_cmp_swap_32 : SDNode<"ISD::ATOMIC_CMP_SWAP_32" , STDAtomic3, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_add_32 : SDNode<"ISD::ATOMIC_LOAD_ADD_32" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_swap_32 : SDNode<"ISD::ATOMIC_SWAP_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_sub_32 : SDNode<"ISD::ATOMIC_LOAD_SUB_32" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_and_32 : SDNode<"ISD::ATOMIC_LOAD_AND_32" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_or_32 : SDNode<"ISD::ATOMIC_LOAD_OR_32" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_xor_32 : SDNode<"ISD::ATOMIC_LOAD_XOR_32" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_nand_32: SDNode<"ISD::ATOMIC_LOAD_NAND_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_min_32 : SDNode<"ISD::ATOMIC_LOAD_MIN_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_max_32 : SDNode<"ISD::ATOMIC_LOAD_MAX_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umin_32 : SDNode<"ISD::ATOMIC_LOAD_UMIN_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umax_32 : SDNode<"ISD::ATOMIC_LOAD_UMAX_32", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_cmp_swap_64 : SDNode<"ISD::ATOMIC_CMP_SWAP_64" , STDAtomic3, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_add_64 : SDNode<"ISD::ATOMIC_LOAD_ADD_64" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_swap_64 : SDNode<"ISD::ATOMIC_SWAP_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_sub_64 : SDNode<"ISD::ATOMIC_LOAD_SUB_64" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_and_64 : SDNode<"ISD::ATOMIC_LOAD_AND_64" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_or_64 : SDNode<"ISD::ATOMIC_LOAD_OR_64" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_xor_64 : SDNode<"ISD::ATOMIC_LOAD_XOR_64" , STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_nand_64: SDNode<"ISD::ATOMIC_LOAD_NAND_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_min_64 : SDNode<"ISD::ATOMIC_LOAD_MIN_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_max_64 : SDNode<"ISD::ATOMIC_LOAD_MAX_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umin_64 : SDNode<"ISD::ATOMIC_LOAD_UMIN_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def atomic_load_umax_64 : SDNode<"ISD::ATOMIC_LOAD_UMAX_64", STDAtomic2, - [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; - -// Do not use ld, st directly. Use load, extload, sextload, zextload, store, -// and truncst (see below). -def ld : SDNode<"ISD::LOAD" , SDTLoad, - [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; -def st : SDNode<"ISD::STORE" , SDTStore, - [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; -def ist : SDNode<"ISD::STORE" , SDTIStore, - [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; - -def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; -def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>; -def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, - []>; -def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", - SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; -def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", - SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; - -def extract_subreg : SDNode<"ISD::EXTRACT_SUBREG", - SDTypeProfile<1, 2, []>>; -def insert_subreg : SDNode<"ISD::INSERT_SUBREG", - SDTypeProfile<1, 3, []>>; - -// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use -// these internally. Don't reference these directly. -def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", - SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, - [SDNPHasChain]>; -def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", - SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, - [SDNPHasChain]>; -def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", - SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; - -// Do not use cvt directly. Use cvt forms below -def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>; - -//===----------------------------------------------------------------------===// -// Selection DAG Condition Codes - -class CondCode; // ISD::CondCode enums -def SETOEQ : CondCode; def SETOGT : CondCode; -def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode; -def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode; -def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode; -def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode; - -def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode; -def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode; - - -//===----------------------------------------------------------------------===// -// Selection DAG Node Transformation Functions. -// -// This mechanism allows targets to manipulate nodes in the output DAG once a -// match has been formed. This is typically used to manipulate immediate -// values. -// -class SDNodeXForm { - SDNode Opcode = opc; - code XFormFunction = xformFunction; -} - -def NOOP_SDNodeXForm : SDNodeXForm; - - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Fragments. -// -// Pattern fragments are reusable chunks of dags that match specific things. -// They can take arguments and have C++ predicates that control whether they -// match. They are intended to make the patterns for common instructions more -// compact and readable. -// - -/// PatFrag - Represents a pattern fragment. This can match something on the -/// DAG, frame a single node to multiply nested other fragments. -/// -class PatFrag { - dag Operands = ops; - dag Fragment = frag; - code Predicate = pred; - SDNodeXForm OperandTransform = xform; -} - -// PatLeaf's are pattern fragments that have no operands. This is just a helper -// to define immediates and other common things concisely. -class PatLeaf - : PatFrag<(ops), frag, pred, xform>; - -// Leaf fragments. - -def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; -def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; - -def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; -def immAllOnesV: PatLeaf<(build_vector), [{ - return ISD::isBuildVectorAllOnes(N); -}]>; -def immAllOnesV_bc: PatLeaf<(bitconvert), [{ - return ISD::isBuildVectorAllOnes(N); -}]>; -def immAllZerosV: PatLeaf<(build_vector), [{ - return ISD::isBuildVectorAllZeros(N); -}]>; -def immAllZerosV_bc: PatLeaf<(bitconvert), [{ - return ISD::isBuildVectorAllZeros(N); -}]>; - - - -// Other helper fragments. -def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; -def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; -def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>; -def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; - -// load fragments. -def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ - return cast(N)->getAddressingMode() == ISD::UNINDEXED; -}]>; -def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ - return cast(N)->getExtensionType() == ISD::NON_EXTLOAD; -}]>; - -// extending load fragments. -def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ - return cast(N)->getExtensionType() == ISD::EXTLOAD; -}]>; -def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ - return cast(N)->getExtensionType() == ISD::SEXTLOAD; -}]>; -def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ - return cast(N)->getExtensionType() == ISD::ZEXTLOAD; -}]>; - -def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i1; -}]>; -def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; -def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::f32; -}]>; -def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::f64; -}]>; - -def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i1; -}]>; -def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; - -def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i1; -}]>; -def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; - -// store fragments. -def unindexedstore : PatFrag<(ops node:$val, node:$ptr), - (st node:$val, node:$ptr), [{ - return cast(N)->getAddressingMode() == ISD::UNINDEXED; -}]>; -def store : PatFrag<(ops node:$val, node:$ptr), - (unindexedstore node:$val, node:$ptr), [{ - return !cast(N)->isTruncatingStore(); -}]>; - -// truncstore fragments. -def truncstore : PatFrag<(ops node:$val, node:$ptr), - (unindexedstore node:$val, node:$ptr), [{ - return cast(N)->isTruncatingStore(); -}]>; -def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), - (truncstore node:$val, node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), - (truncstore node:$val, node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), - (truncstore node:$val, node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; -def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), - (truncstore node:$val, node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::f32; -}]>; -def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), - (truncstore node:$val, node:$ptr), [{ - return cast(N)->getMemoryVT() == MVT::f64; -}]>; - -// indexed store fragments. -def istore : PatFrag<(ops node:$val, node:$base, node:$offset), - (ist node:$val, node:$base, node:$offset), [{ - return !cast(N)->isTruncatingStore(); -}]>; - -def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), - (istore node:$val, node:$base, node:$offset), [{ - ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); - return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; -}]>; - -def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset), - (ist node:$val, node:$base, node:$offset), [{ - return cast(N)->isTruncatingStore(); -}]>; -def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), - (itruncstore node:$val, node:$base, node:$offset), [{ - ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); - return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; -}]>; -def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), - (pre_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i1; -}]>; -def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), - (pre_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), - (pre_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), - (pre_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; -def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), - (pre_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::f32; -}]>; - -def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), - (istore node:$val, node:$ptr, node:$offset), [{ - ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); - return AM == ISD::POST_INC || AM == ISD::POST_DEC; -}]>; - -def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), - (itruncstore node:$val, node:$base, node:$offset), [{ - ISD::MemIndexedMode AM = cast(N)->getAddressingMode(); - return AM == ISD::POST_INC || AM == ISD::POST_DEC; -}]>; -def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), - (post_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i1; -}]>; -def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), - (post_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i8; -}]>; -def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), - (post_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i16; -}]>; -def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), - (post_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::i32; -}]>; -def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), - (post_truncst node:$val, node:$base, node:$offset), [{ - return cast(N)->getMemoryVT() == MVT::f32; -}]>; - -// setcc convenience fragments. -def setoeq : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETOEQ)>; -def setogt : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETOGT)>; -def setoge : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETOGE)>; -def setolt : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETOLT)>; -def setole : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETOLE)>; -def setone : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETONE)>; -def seto : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETO)>; -def setuo : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETUO)>; -def setueq : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETUEQ)>; -def setugt : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETUGT)>; -def setuge : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETUGE)>; -def setult : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETULT)>; -def setule : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETULE)>; -def setune : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETUNE)>; -def seteq : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETEQ)>; -def setgt : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETGT)>; -def setge : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETGE)>; -def setlt : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETLT)>; -def setle : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETLE)>; -def setne : PatFrag<(ops node:$lhs, node:$rhs), - (setcc node:$lhs, node:$rhs, SETNE)>; - -//===----------------------------------------------------------------------===// -// Selection DAG CONVERT_RNDSAT patterns - -def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_FF; - }]>; - -def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_SS; - }]>; - -def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_SU; - }]>; - -def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_US; - }]>; - -def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_UU; - }]>; - -def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_SF; - }]>; - -def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_UF; - }]>; - -def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_FS; - }]>; - -def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat), - (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{ - return cast(N)->getCvtCode() == ISD::CVT_FU; - }]>; - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Support. -// -// Patterns are what are actually matched against the target-flavored -// instruction selection DAG. Instructions defined by the target implicitly -// define patterns in most cases, but patterns can also be explicitly added when -// an operation is defined by a sequence of instructions (e.g. loading a large -// immediate value on RISC targets that do not support immediates as large as -// their GPRs). -// - -class Pattern resultInstrs> { - dag PatternToMatch = patternToMatch; - list ResultInstrs = resultInstrs; - list Predicates = []; // See class Instruction in Target.td. - int AddedComplexity = 0; // See class Instruction in Target.td. -} - -// Pat - A simple (but common) form of a pattern, which produces a simple result -// not needing a full list. -class Pat : Pattern; - -//===----------------------------------------------------------------------===// -// Complex pattern definitions. -// - -class CPAttribute; -// Pass the parent Operand as root to CP function rather -// than the root of the sub-DAG -def CPAttrParentAsRoot : CPAttribute; - -// Complex patterns, e.g. X86 addressing mode, requires pattern matching code -// in C++. NumOperands is the number of operands returned by the select function; -// SelectFunc is the name of the function used to pattern match the max. pattern; -// RootNodes are the list of possible root nodes of the sub-dags to match. -// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; -// -class ComplexPattern roots = [], list props = [], - list attrs = []> { - ValueType Ty = ty; - int NumOperands = numops; - string SelectFunc = fn; - list RootNodes = roots; - list Properties = props; - list Attributes = attrs; -} - -//===----------------------------------------------------------------------===// -// Dwarf support. -// -def SDT_dwarf_loc : SDTypeProfile<0, 3, - [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; -def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; Modified: llvm/trunk/lib/Target/X86/X86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86.td (original) +++ llvm/trunk/lib/Target/X86/X86.td Mon Nov 24 01:34:46 2008 @@ -14,7 +14,7 @@ // Get the target-independent interfaces which we are implementing... // -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // X86 Subtarget features. Modified: llvm/trunk/lib/Target/XCore/XCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCore.td?rev=59953&r1=59952&r2=59953&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCore.td (original) +++ llvm/trunk/lib/Target/XCore/XCore.td Mon Nov 24 01:34:46 2008 @@ -14,7 +14,7 @@ // Target-independent interfaces which we are implementing //===----------------------------------------------------------------------===// -include "../Target.td" +include "llvm/Target/Target.td" //===----------------------------------------------------------------------===// // Descriptions From nicholas at mxc.ca Mon Nov 24 01:43:47 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 23 Nov 2008 23:43:47 -0800 Subject: [llvm-commits] [llvm] r59940 - in /llvm/trunk: docs/LangRef.html lib/Analysis/BasicAliasAnalysis.cpp In-Reply-To: <492A5702.3070403@gmail.com> References: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> <492A5702.3070403@gmail.com> Message-ID: <492A5B33.8080406@mxc.ca> T?r?k Edwin wrote: > On 2008-11-24 07:00, Nick Lewycky wrote: >> Author: nicholas >> Date: Sun Nov 23 23:00:44 2008 >> New Revision: 59940 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=59940&view=rev >> Log: >> Seriously strengthen the guarantee offered by noalias on a function's return >> value. It must now be as if the pointer were allocated and has not escaped to >> the caller. Thanks to Dan Gohman for pointing out the error in the original >> and helping devise this definition. >> >> > > malloc(0) is allowed to return a unique pointer, instead of NULL. > Does this code handle that? Sure, a noalias function can return NULL or a unique pointer. Returning NULL is sufficient to not alias. Nick From edwintorok at gmail.com Mon Nov 24 01:47:21 2008 From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=) Date: Mon, 24 Nov 2008 09:47:21 +0200 Subject: [llvm-commits] [llvm] r59940 - in /llvm/trunk: docs/LangRef.html lib/Analysis/BasicAliasAnalysis.cpp In-Reply-To: <492A5B33.8080406@mxc.ca> References: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> <492A5702.3070403@gmail.com> <492A5B33.8080406@mxc.ca> Message-ID: <492A5C09.4090002@gmail.com> On 2008-11-24 09:43, Nick Lewycky wrote: > T?r?k Edwin wrote: > >> On 2008-11-24 07:00, Nick Lewycky wrote: >> >>> Author: nicholas >>> Date: Sun Nov 23 23:00:44 2008 >>> New Revision: 59940 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=59940&view=rev >>> Log: >>> Seriously strengthen the guarantee offered by noalias on a function's return >>> value. It must now be as if the pointer were allocated and has not escaped to >>> the caller. Thanks to Dan Gohman for pointing out the error in the original >>> and helping devise this definition. >>> >>> >>> >> malloc(0) is allowed to return a unique pointer, instead of NULL. >> Does this code handle that? >> > > Sure, a noalias function can return NULL or a unique pointer. Returning > NULL is sufficient to not alias. > > Agreed about NULL. However if I call the function twice, and it returns the same pointer (which is unique, but same for both calls), doesn't that mean that the return value aliases a caller visible pointer? --Edwin From nicholas at mxc.ca Mon Nov 24 01:55:37 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 23 Nov 2008 23:55:37 -0800 Subject: [llvm-commits] [llvm] r59940 - in /llvm/trunk: docs/LangRef.html lib/Analysis/BasicAliasAnalysis.cpp In-Reply-To: <492A5C09.4090002@gmail.com> References: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> <492A5702.3070403@gmail.com> <492A5B33.8080406@mxc.ca> <492A5C09.4090002@gmail.com> Message-ID: <492A5DF9.6030505@mxc.ca> T?r?k Edwin wrote: > On 2008-11-24 09:43, Nick Lewycky wrote: >> T?r?k Edwin wrote: >> >>> On 2008-11-24 07:00, Nick Lewycky wrote: >>> >>>> Author: nicholas >>>> Date: Sun Nov 23 23:00:44 2008 >>>> New Revision: 59940 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=59940&view=rev >>>> Log: >>>> Seriously strengthen the guarantee offered by noalias on a function's return >>>> value. It must now be as if the pointer were allocated and has not escaped to >>>> the caller. Thanks to Dan Gohman for pointing out the error in the original >>>> and helping devise this definition. >>>> >>>> >>>> >>> malloc(0) is allowed to return a unique pointer, instead of NULL. >>> Does this code handle that? >>> >> Sure, a noalias function can return NULL or a unique pointer. Returning >> NULL is sufficient to not alias. >> >> > > Agreed about NULL. > However if I call the function twice, and it returns the same pointer > (which is unique, but same for both calls), doesn't that mean > that the return value aliases a caller visible pointer? Oh I see what you mean. I hadn't thought of that, but since you can't actually store a byte there, it should be treated just like NULL case. Feel free to patch the LangRef, or else I'll get to it later tomorrow. Similarly, there's the case of: p1 = malloc(1) free(p1) p2 = malloc(1) p1 could equal p2, but they don't alias since the object pointed to has been destroyed. "Aliasing" in general is not defined in the LangRef. Perhaps we'll need to do that in order to elucidate the intended behaviour in all of these corner cases. Nick From edwintorok at gmail.com Mon Nov 24 02:02:24 2008 From: edwintorok at gmail.com (Torok Edwin) Date: Mon, 24 Nov 2008 08:02:24 -0000 Subject: [llvm-commits] [llvm] r59955 - /llvm/trunk/docs/LangRef.html Message-ID: <200811240802.mAO82OME013363@zion.cs.uiuc.edu> Author: edwin Date: Mon Nov 24 02:02:24 2008 New Revision: 59955 URL: http://llvm.org/viewvc/llvm-project?rev=59955&view=rev Log: NULL, unique pointers from malloc(0), and freed pointers are legal values for noalias attribute parameters/return values. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=59955&r1=59954&r2=59955&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Nov 24 02:02:24 2008 @@ -894,7 +894,9 @@ parameter. The caller is responsible for ensuring that this is the case. On a function return value, noalias additionally indicates that the pointer does not alias any other pointers visible to the - caller. + caller. Note that this applies only to pointers that can be used to actually + load/store a value: NULL, unique pointers from malloc(0), and freed pointers + are considered to not alias anything.
nest
This indicates that the pointer parameter can be excised using the From edwintorok at gmail.com Mon Nov 24 02:03:22 2008 From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=) Date: Mon, 24 Nov 2008 10:03:22 +0200 Subject: [llvm-commits] [llvm] r59940 - in /llvm/trunk: docs/LangRef.html lib/Analysis/BasicAliasAnalysis.cpp In-Reply-To: <492A5DF9.6030505@mxc.ca> References: <200811240500.mAO50jAr007094@zion.cs.uiuc.edu> <492A5702.3070403@gmail.com> <492A5B33.8080406@mxc.ca> <492A5C09.4090002@gmail.com> <492A5DF9.6030505@mxc.ca> Message-ID: <492A5FCA.7040006@gmail.com> On 2008-11-24 09:55, Nick Lewycky wrote: > T?r?k Edwin wrote: > >> On 2008-11-24 09:43, Nick Lewycky wrote: >> >>> T?r?k Edwin wrote: >>> >>> >>>> On 2008-11-24 07:00, Nick Lewycky wrote: >>>> >>>> >>>>> Author: nicholas >>>>> Date: Sun Nov 23 23:00:44 2008 >>>>> New Revision: 59940 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=59940&view=rev >>>>> Log: >>>>> Seriously strengthen the guarantee offered by noalias on a function's return >>>>> value. It must now be as if the pointer were allocated and has not escaped to >>>>> the caller. Thanks to Dan Gohman for pointing out the error in the original >>>>> and helping devise this definition. >>>>> >>>>> >>>>> >>>>> >>>> malloc(0) is allowed to return a unique pointer, instead of NULL. >>>> Does this code handle that? >>>> >>>> >>> Sure, a noalias function can return NULL or a unique pointer. Returning >>> NULL is sufficient to not alias. >>> >>> >>> >> Agreed about NULL. >> However if I call the function twice, and it returns the same pointer >> (which is unique, but same for both calls), doesn't that mean >> that the return value aliases a caller visible pointer? >> > > Oh I see what you mean. > > I hadn't thought of that, but since you can't actually store a byte > there, it should be treated just like NULL case. > > Feel free to patch the LangRef, or else I'll get to it later tomorrow. > > Similarly, there's the case of: > p1 = malloc(1) > free(p1) > p2 = malloc(1) > p1 could equal p2, but they don't alias since the object pointed to has > been destroyed. > > "Aliasing" in general is not defined in the LangRef. Perhaps we'll need > to do that in order to elucidate the intended behaviour in all of these > corner cases. > > I added an explanation to LangRef.html in r59955, feel free to improve it: - caller.
+ caller. Note that this applies only to pointers that can be used to actually + load/store a value: NULL, unique pointers from malloc(0), and freed pointers + are considered to not alias anything. Best regards, --Edwin From matthijs at stdin.nl Mon Nov 24 05:44:05 2008 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Mon, 24 Nov 2008 11:44:05 -0000 Subject: [llvm-commits] [llvm] r59958 - /llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile Message-ID: <200811241144.mAOBi6T4001738@zion.cs.uiuc.edu> Author: matthijs Date: Mon Nov 24 05:44:00 2008 New Revision: 59958 URL: http://llvm.org/viewvc/llvm-project?rev=59958&view=rev Log: Fix comments. Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile?rev=59958&r1=59957&r2=59958&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/Makefile Mon Nov 24 05:44:00 2008 @@ -1,4 +1,4 @@ -##===- lib/Target/X86/Makefile -----------------------------*- Makefile -*-===## +##===- lib/Target/PowerPC/AsmPrinter/Makefile --------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -9,7 +9,7 @@ LEVEL = ../../../.. LIBRARYNAME = LLVMPowerPCAsmPrinter -# Hack: we need to include 'main' x86 target directory to grab private headers +# Hack: we need to include 'main' PowerPC target directory to grab private headers CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. include $(LEVEL)/Makefile.common From matthijs at stdin.nl Mon Nov 24 07:45:25 2008 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Mon, 24 Nov 2008 14:45:25 +0100 Subject: [llvm-commits] Multiple directories in a single library Message-ID: <20081124134525.GA1010@katherina.student.utwente.nl> Hi all, while working on my own backend, I found that things got really messy real quickly, partly caused by the fact that all .cpp files must be in the same directory (lib/Target/TargetName). Simply putting code in different directories and using DIRS in the Makefile doesn't cut it, since that produces different libraries for each directory, which don't get linked in by the programs that need them. There is some code in llvm-config which fixes the library problem for the TargetNameAsmPrinter library, but that isn't really the clean way IMHO. Is this also meant for cleanup, or is there another reason why the AsmPrinter should be in a seperate library? Anyway, I thought it would be good if one could simply compile .cpp files in subdirectories as if they are in the current directory, without a makefile in the subdirectory. These cpp files would end up in the library as defined by the parent directory's Makefile. I've attached a small patch which facilitates this. It allows you to define the EXTRA_SOURCES variable to explicitely add extra source files (one could also explicitly define SOURCES, but this way you don't loose the default all-sources-in-the-current-dir feature). For example, I would add: EXTRA_SOURCES = $(wildcard $(PROJ_SRC_DIR)/SubDir/*.cpp) to get all the cpp files in SubDir compiled as well. It would be more elegant to specify EXTRA_DIRS instead (or perhaps a better name) as a list of directories, and let Makefile.rules handle the wildcarding here. However, I've not found a way to write .for DIR in $(EXTRA_DIRS) SOURCES += $(patsubst $(PROJ_SRC_DIR)/%, %, wildcard $(PROJ_SRC_DIR)/$DIR/*.cpp)) .endfor in the Makefile (the above appears to be valid in NetBSD make, any suggestions on how to do this in GNU make?) Doing this in shell seems tricky, because then the wildcarding must be done in shell as well AFAICS. The second change in the patch makes sure that the proper directory is created below $(ObjDir). This is a bit ugly, now it depends on $(ObjDir)/%/../.dir, which becomes $(ObjDir)/SubDir/foo/../.dir for foo.cpp in SubDir, which ensures that $(ObjDir)/SubDir is properly created. I tried to do this propely by depending on $(ObjDir)/$(dir %)/.dir but that didn't work for reasons beyond my Makefile-fu. Any suggestions on this are welcome. Gr. Matthijs -------------- next part -------------- Index: Makefile.rules =================================================================== --- Makefile.rules (revision 59957) +++ Makefile.rules (working copy) @@ -541,6 +541,10 @@ Sources := $(SOURCES) endif +ifdef EXTRA_SOURCES + Sources += $(patsubst $(PROJ_SRC_DIR)/%, %, $(EXTRA_SOURCES)) +endif + ifdef BUILT_SOURCES Sources += $(filter %.cpp %.c %.cc %.y %.l,$(BUILT_SOURCES)) endif @@ -1122,17 +1126,17 @@ DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.d.tmp" "$(ObjDir)/$*.d"; \ else $(RM) "$(ObjDir)/$*.d.tmp"; exit 1; fi -$(ObjDir)/%.lo $(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) +$(ObjDir)/%.lo $(ObjDir)/%.o: %.cpp $(ObjDir)/%/../.dir $(BUILT_SOURCES) $(Echo) "Compiling $*.cpp for $(BuildMode) build " $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) -$(ObjDir)/%.lo $(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) +$(ObjDir)/%.lo $(ObjDir)/%.o: %.cc $(ObjDir)/%/../.dir $(BUILT_SOURCES) $(Echo) "Compiling $*.cc for $(BuildMode) build" $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) -$(ObjDir)/%.lo $(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES) +$(ObjDir)/%.lo $(ObjDir)/%.o: %.c $(ObjDir)/%/../.dir $(BUILT_SOURCES) $(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.C) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081124/c56b8dc2/attachment.bin From matthijs at stdin.nl Mon Nov 24 08:32:14 2008 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Mon, 24 Nov 2008 15:32:14 +0100 Subject: [llvm-commits] Multiple directories in a single library In-Reply-To: <20081124134525.GA1010@katherina.student.utwente.nl> References: <20081124134525.GA1010@katherina.student.utwente.nl> Message-ID: <20081124143214.GB1010@katherina.student.utwente.nl> Hi all, I've slightly updated the patch. Now, instead of depending on a .dir file that is possibly in a subdir, it again depends just on $(ObjDir)/.dir. It also executes an explicit mkdir before compiling a file. The previous approach turned out to recompile stuff too often: Make threw away .dir files that we would have liked to keep. This was probably because the .PRECIOUS rules didn't apply because of the funky .. in the path, but those rules wouldn't have applied to .dir files in subdirs anyway... The patch is inlined below. Gr. Matthijs Index: Makefile.rules =================================================================== --- Makefile.rules (revision 59957) +++ Makefile.rules (working copy) @@ -541,6 +541,10 @@ Sources := $(SOURCES) endif +ifdef EXTRA_SOURCES + Sources += $(patsubst $(PROJ_SRC_DIR)/%, %, $(EXTRA_SOURCES)) +endif + ifdef BUILT_SOURCES Sources += $(filter %.cpp %.c %.cc %.y %.l,$(BUILT_SOURCES)) endif @@ -1123,16 +1127,19 @@ else $(RM) "$(ObjDir)/$*.d.tmp"; exit 1; fi $(ObjDir)/%.lo $(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) + $(Verb) $(MKDIR) $(dir $@) > /dev/null $(Echo) "Compiling $*.cpp for $(BuildMode) build " $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) $(ObjDir)/%.lo $(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) + $(Verb) $(MKDIR) $(dir $@) > /dev/null $(Echo) "Compiling $*.cc for $(BuildMode) build" $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) $(ObjDir)/%.lo $(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES) + $(Verb) $(MKDIR) $(dir $@) > /dev/null $(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG) $(Verb) if $(MAYBE_PIC_Compile.C) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \ $(DEPEND_MOVEFILE) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081124/4a6d729b/attachment.bin From baldrick at free.fr Mon Nov 24 08:53:20 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 Nov 2008 14:53:20 -0000 Subject: [llvm-commits] [llvm] r59960 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200811241453.mAOErL7j009491@zion.cs.uiuc.edu> Author: baldrick Date: Mon Nov 24 08:53:14 2008 New Revision: 59960 URL: http://llvm.org/viewvc/llvm-project?rev=59960&view=rev Log: If the type legalizer actually legalized anything (this doesn't happen that often, since most code does not use illegal types) then follow it by a DAG combiner run that is allowed to generate illegal operations but not illegal types. I didn't modify the target combiner code to distinguish like this between illegal operations and illegal types, so it will not produce illegal operations as well as not producing illegal types. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Nov 24 08:53:14 2008 @@ -54,6 +54,12 @@ static void createNode(const SDNode &); }; +enum CombineLevel { + Unrestricted, // Combine may create illegal operations and illegal types. + NoIllegalTypes, // Combine may create illegal operations but no illegal types. + NoIllegalOperations // Combine may only create legal operations and types. +}; + /// SelectionDAG class - This is used to represent a portion of an LLVM function /// in a low-level Data Dependence DAG representation suitable for instruction /// selection. This DAG is constructed as the first step of instruction @@ -187,18 +193,19 @@ } /// Combine - This iterates over the nodes in the SelectionDAG, folding - /// certain types of nodes together, or eliminating superfluous nodes. When - /// the AfterLegalize argument is set to 'true', Combine takes care not to - /// generate any nodes that will be illegal on the target. - void Combine(bool AfterLegalize, AliasAnalysis &AA, bool Fast); - + /// certain types of nodes together, or eliminating superfluous nodes. The + /// Level argument controls whether Combine is allowed to produce nodes and + /// types that are illegal on the target. + void Combine(CombineLevel Level, AliasAnalysis &AA, bool Fast); + /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that - /// only uses types natively supported by the target. + /// only uses types natively supported by the target. Returns "true" if it + /// made any changes. /// /// Note that this is an involved process that may invalidate pointers into /// the graph. - void LegalizeTypes(); - + bool LegalizeTypes(); + /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is /// compatible with the target instruction selector, as indicated by the /// TargetLowering object. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Nov 24 08:53:14 2008 @@ -701,12 +701,10 @@ /// that want to combine struct TargetLoweringOpt { SelectionDAG &DAG; - bool AfterLegalize; SDValue Old; SDValue New; - explicit TargetLoweringOpt(SelectionDAG &InDAG, bool afterLegalize) - : DAG(InDAG), AfterLegalize(afterLegalize) {} + explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {} bool CombineTo(SDValue O, SDValue N) { Old = O; @@ -793,7 +791,7 @@ /// Return Value: /// SDValue.Val == 0 - No change was made /// SDValue.Val == N - N was replaced, is dead, and is already handled. - /// otherwise - N should be replaced by the returned Operand. + /// otherwise - N should be replaced by the returned Operand. /// /// In addition, methods provided by DAGCombinerInfo may be used to perform /// more complex transformations. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Nov 24 08:53:14 2008 @@ -50,7 +50,9 @@ class VISIBILITY_HIDDEN DAGCombiner { SelectionDAG &DAG; TargetLowering &TLI; - bool AfterLegalize; + CombineLevel Level; + bool LegalOperations; + bool LegalTypes; bool Fast; // Worklist of all of the nodes that need to be simplified. @@ -202,8 +204,8 @@ SDValue SimplifySelectCC(SDValue N0, SDValue N1, SDValue N2, SDValue N3, ISD::CondCode CC, bool NotExtCompare = false); - SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, - ISD::CondCode Cond, bool foldBooleans = true); + SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, + bool foldBooleans = true); SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp, unsigned HiOp); SDValue CombineConsecutiveLoads(SDNode *N, MVT VT); @@ -241,12 +243,14 @@ DAGCombiner(SelectionDAG &D, AliasAnalysis &A, bool fast) : DAG(D), TLI(D.getTargetLoweringInfo()), - AfterLegalize(false), + Level(Unrestricted), + LegalOperations(false), + LegalTypes(false), Fast(fast), AA(A) {} /// Run - runs the dag combiner on all nodes in the work list - void Run(bool RunningAfterLegalize); + void Run(CombineLevel AtLevel); }; } @@ -302,7 +306,7 @@ /// isNegatibleForFree - Return 1 if we can compute the negated form of the /// specified expression for the same cost as the expression itself, or 2 if we /// can compute the negated form more cheaply than the expression itself. -static char isNegatibleForFree(SDValue Op, bool AfterLegalize, +static char isNegatibleForFree(SDValue Op, bool LegalOperations, unsigned Depth = 0) { // No compile time optimizations on this type. if (Op.getValueType() == MVT::ppcf128) @@ -322,16 +326,16 @@ case ISD::ConstantFP: // Don't invert constant FP values after legalize. The negated constant // isn't necessarily legal. - return AfterLegalize ? 0 : 1; + return LegalOperations ? 0 : 1; case ISD::FADD: // FIXME: determine better conditions for this xform. if (!UnsafeFPMath) return 0; // -(A+B) -> -A - B - if (char V = isNegatibleForFree(Op.getOperand(0), AfterLegalize, Depth+1)) + if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return V; // -(A+B) -> -B - A - return isNegatibleForFree(Op.getOperand(1), AfterLegalize, Depth+1); + return isNegatibleForFree(Op.getOperand(1), LegalOperations, Depth+1); case ISD::FSUB: // We can't turn -(A-B) into B-A when we honor signed zeros. if (!UnsafeFPMath) return 0; @@ -344,22 +348,22 @@ if (HonorSignDependentRoundingFPMath()) return 0; // -(X*Y) -> (-X * Y) or (X*-Y) - if (char V = isNegatibleForFree(Op.getOperand(0), AfterLegalize, Depth+1)) + if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return V; - return isNegatibleForFree(Op.getOperand(1), AfterLegalize, Depth+1); + return isNegatibleForFree(Op.getOperand(1), LegalOperations, Depth+1); case ISD::FP_EXTEND: case ISD::FP_ROUND: case ISD::FSIN: - return isNegatibleForFree(Op.getOperand(0), AfterLegalize, Depth+1); + return isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1); } } /// GetNegatedExpression - If isNegatibleForFree returns true, this function /// returns the newly negated expression. static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, - bool AfterLegalize, unsigned Depth = 0) { + bool LegalOperations, unsigned Depth = 0) { // fneg is removable even if it has multiple uses. if (Op.getOpcode() == ISD::FNEG) return Op.getOperand(0); @@ -379,15 +383,15 @@ assert(UnsafeFPMath); // -(A+B) -> -A - B - if (isNegatibleForFree(Op.getOperand(0), AfterLegalize, Depth+1)) + if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return DAG.getNode(ISD::FSUB, Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, - AfterLegalize, Depth+1), + LegalOperations, Depth+1), Op.getOperand(1)); // -(A+B) -> -B - A return DAG.getNode(ISD::FSUB, Op.getValueType(), GetNegatedExpression(Op.getOperand(1), DAG, - AfterLegalize, Depth+1), + LegalOperations, Depth+1), Op.getOperand(0)); case ISD::FSUB: // We can't turn -(A-B) into B-A when we honor signed zeros. @@ -407,27 +411,27 @@ assert(!HonorSignDependentRoundingFPMath()); // -(X*Y) -> -X * Y - if (isNegatibleForFree(Op.getOperand(0), AfterLegalize, Depth+1)) + if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return DAG.getNode(Op.getOpcode(), Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, - AfterLegalize, Depth+1), + LegalOperations, Depth+1), Op.getOperand(1)); // -(X*Y) -> X * -Y return DAG.getNode(Op.getOpcode(), Op.getValueType(), Op.getOperand(0), GetNegatedExpression(Op.getOperand(1), DAG, - AfterLegalize, Depth+1)); + LegalOperations, Depth+1)); case ISD::FP_EXTEND: case ISD::FSIN: return DAG.getNode(Op.getOpcode(), Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, - AfterLegalize, Depth+1)); + LegalOperations, Depth+1)); case ISD::FP_ROUND: return DAG.getNode(ISD::FP_ROUND, Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, - AfterLegalize, Depth+1), + LegalOperations, Depth+1), Op.getOperand(1)); } } @@ -531,7 +535,7 @@ /// it can be simplified or if things it uses can be simplified by bit /// propagation. If so, return true. bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) { - TargetLowering::TargetLoweringOpt TLO(DAG, AfterLegalize); + TargetLowering::TargetLoweringOpt TLO(DAG); APInt KnownZero, KnownOne; if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) return false; @@ -575,16 +579,18 @@ // Main DAG Combiner implementation //===----------------------------------------------------------------------===// -void DAGCombiner::Run(bool RunningAfterLegalize) { - // set the instance variable, so that the various visit routines may use it. - AfterLegalize = RunningAfterLegalize; +void DAGCombiner::Run(CombineLevel AtLevel) { + // set the instance variables, so that the various visit routines may use it. + Level = AtLevel; + LegalOperations = Level >= NoIllegalOperations; + LegalTypes = Level >= NoIllegalTypes; // Add all the dag nodes to the worklist. WorkList.reserve(DAG.allnodes_size()); for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I) WorkList.push_back(I); - + // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted, and tracking any // changes of the root. @@ -745,7 +751,7 @@ // Expose the DAG combiner to the target combiner impls. TargetLowering::DAGCombinerInfo - DagCombineInfo(DAG, !AfterLegalize, false, this); + DagCombineInfo(DAG, Level == Unrestricted, false, this); RV = TLI.PerformDAGCombine(N, DagCombineInfo); } @@ -893,7 +899,7 @@ static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, SelectionDAG &DAG, const TargetLowering &TLI, - bool AfterLegalize) { + bool LegalOperations) { MVT VT = N->getValueType(0); unsigned Opc = N->getOpcode(); bool isSlctCC = Slct.getOpcode() == ISD::SELECT_CC; @@ -927,7 +933,7 @@ bool isInt = OpVT.isInteger(); CC = ISD::getSetCCInverse(CC, isInt); - if (AfterLegalize && !TLI.isCondCodeLegal(CC, OpVT)) + if (LegalOperations && !TLI.isCondCodeLegal(CC, OpVT)) return SDValue(); // Inverse operator isn't legal. DoXform = true; @@ -977,7 +983,7 @@ return N0; // fold (add Sym, c) -> Sym+c if (GlobalAddressSDNode *GA = dyn_cast(N0)) - if (!AfterLegalize && TLI.isOffsetFoldingLegal(GA) && N1C && + if (!LegalOperations && TLI.isOffsetFoldingLegal(GA) && N1C && GA->getOpcode() == ISD::GlobalAddress) return DAG.getGlobalAddress(GA->getGlobal(), VT, GA->getOffset() + @@ -1037,11 +1043,11 @@ // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c)) if (N0.getOpcode() == ISD::SELECT && N0.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N0, N1, DAG, TLI, AfterLegalize); + SDValue Result = combineSelectAndUse(N, N0, N1, DAG, TLI, LegalOperations); if (Result.getNode()) return Result; } if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, AfterLegalize); + SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, LegalOperations); if (Result.getNode()) return Result; } @@ -1139,7 +1145,7 @@ return N0.getOperand(0); // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c)) if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) { - SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, AfterLegalize); + SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, LegalOperations); if (Result.getNode()) return Result; } // If either operand of a sub is undef, the result is undef @@ -1150,7 +1156,7 @@ // If the relocation model supports it, consider symbol offsets. if (GlobalAddressSDNode *GA = dyn_cast(N0)) - if (!AfterLegalize && TLI.isOffsetFoldingLegal(GA)) { + if (!LegalOperations && TLI.isOffsetFoldingLegal(GA)) { // fold (sub Sym, c) -> Sym-c if (N1C && GA->getOpcode() == ISD::GlobalAddress) return DAG.getGlobalAddress(GA->getGlobal(), VT, @@ -1522,20 +1528,20 @@ // If the high half is not needed, just compute the low half. bool HiExists = N->hasAnyUseOfValue(1); if (!HiExists && - (!AfterLegalize || + (!LegalOperations || TLI.isOperationLegal(LoOp, N->getValueType(0)))) { SDValue Res = DAG.getNode(LoOp, N->getValueType(0), N->op_begin(), - N->getNumOperands()); + N->getNumOperands()); return CombineTo(N, Res, Res); } // If the low half is not needed, just compute the high half. bool LoExists = N->hasAnyUseOfValue(0); if (!LoExists && - (!AfterLegalize || + (!LegalOperations || TLI.isOperationLegal(HiOp, N->getValueType(1)))) { SDValue Res = DAG.getNode(HiOp, N->getValueType(1), N->op_begin(), - N->getNumOperands()); + N->getNumOperands()); return CombineTo(N, Res, Res); } @@ -1550,18 +1556,18 @@ AddToWorkList(Lo.getNode()); SDValue LoOpt = combine(Lo.getNode()); if (LoOpt.getNode() && LoOpt.getNode() != Lo.getNode() && - (!AfterLegalize || + (!LegalOperations || TLI.isOperationLegal(LoOpt.getOpcode(), LoOpt.getValueType()))) return CombineTo(N, LoOpt, LoOpt); } if (HiExists) { SDValue Hi = DAG.getNode(HiOp, N->getValueType(1), - N->op_begin(), N->getNumOperands()); + N->op_begin(), N->getNumOperands()); AddToWorkList(Hi.getNode()); SDValue HiOpt = combine(Hi.getNode()); if (HiOpt.getNode() && HiOpt != Hi && - (!AfterLegalize || + (!LegalOperations || TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType()))) return CombineTo(N, HiOpt, HiOpt); } @@ -1729,7 +1735,7 @@ bool isInteger = LL.getValueType().isInteger(); ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger); if (Result != ISD::SETCC_INVALID && - (!AfterLegalize || TLI.isCondCodeLegal(Result, LL.getValueType()))) + (!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType()))) return DAG.getSetCC(N0.getValueType(), LL, LR, Result); } } @@ -1754,13 +1760,12 @@ unsigned BitWidth = N1.getValueSizeInBits(); if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth, BitWidth - EVT.getSizeInBits())) && - ((!AfterLegalize && !LN0->isVolatile()) || + ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); AddToWorkList(N); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -1776,13 +1781,12 @@ unsigned BitWidth = N1.getValueSizeInBits(); if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth, BitWidth - EVT.getSizeInBits())) && - ((!AfterLegalize && !LN0->isVolatile()) || + ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); AddToWorkList(N); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -1806,7 +1810,7 @@ // Do not generate loads of non-round integer types since these can // be expensive (and would be wrong if the type is not byte sized). if (EVT != MVT::Other && LoadedVT.bitsGT(EVT) && EVT.isRound() && - (!AfterLegalize || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { + (!LegalOperations || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { MVT PtrType = N0.getOperand(1).getValueType(); // For big endian targets, we need to add an offset to the pointer to // load the correct bytes. For little endian systems, we merely need to @@ -1914,7 +1918,7 @@ bool isInteger = LL.getValueType().isInteger(); ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger); if (Result != ISD::SETCC_INVALID && - (!AfterLegalize || TLI.isCondCodeLegal(Result, LL.getValueType()))) + (!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType()))) return DAG.getSetCC(N0.getValueType(), LL, LR, Result); } } @@ -2171,7 +2175,7 @@ ISD::CondCode NotCC = ISD::getSetCCInverse(cast(CC)->get(), isInt); - if (!AfterLegalize || TLI.isCondCodeLegal(NotCC, LHS.getValueType())) { + if (!LegalOperations || TLI.isCondCodeLegal(NotCC, LHS.getValueType())) { switch (N0.getOpcode()) { default: assert(0 && "Unhandled SetCC Equivalent!"); @@ -2237,7 +2241,7 @@ if (N0 == N1) { if (!VT.isVector()) { return DAG.getConstant(0, VT); - } else if (!AfterLegalize || TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) { + } else if (!LegalOperations || TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)){ // Produce a vector of zeros. SDValue El = DAG.getConstant(0, VT.getVectorElementType()); std::vector Ops(VT.getVectorNumElements(), El); @@ -2433,8 +2437,7 @@ if (N1C && N0.getOpcode() == ISD::SHL && N1 == N0.getOperand(1)) { unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getZExtValue(); MVT EVT = MVT::getIntegerVT(LowBits); - if (EVT.isSimple() && // TODO: remove when apint codegen support lands. - (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT))) + if ((!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT))) return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), DAG.getValueType(EVT)); } @@ -2469,7 +2472,7 @@ // extend already), the truncated to type is legal, sign_extend is legal // on that type, and the the truncate to that type is both legal and free, // perform the transform. - if (ShiftAmt && + if (ShiftAmt && TLI.isOperationLegal(ISD::SIGN_EXTEND, TruncVT) && TLI.isOperationLegal(ISD::TRUNCATE, VT) && TLI.isTruncateFree(VT, TruncVT)) { @@ -2889,8 +2892,8 @@ } // fold (sext (truncate x)) -> (sextinreg x). - if (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, - N0.getValueType())) { + if (!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, + N0.getValueType())) { if (Op.getValueType().bitsLT(VT)) Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); else if (Op.getValueType().bitsGT(VT)) @@ -2902,7 +2905,7 @@ // fold (sext (load x)) -> (sext (truncate (sextload x))) if (ISD::isNON_EXTLoad(N0.getNode()) && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, N0.getValueType()))) { bool DoXform = true; SmallVector SetCCs; @@ -2911,11 +2914,10 @@ if (DoXform) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), - N0.getValueType(), - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), + N0.getValueType(), + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad); CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1)); @@ -2944,13 +2946,12 @@ ISD::isUNINDEXEDLoad(N0.getNode()) && N0.hasOneUse()) { LoadSDNode *LN0 = cast(N0); MVT EVT = LN0->getMemoryVT(); - if ((!AfterLegalize && !LN0->isVolatile()) || + if ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) { SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), @@ -2969,7 +2970,7 @@ } // fold (sext x) -> (zext x) if the sign bit is known zero. - if ((!AfterLegalize || TLI.isOperationLegal(ISD::ZERO_EXTEND, VT)) && + if ((!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, VT)) && DAG.SignBitIsZero(N0)) return DAG.getNode(ISD::ZERO_EXTEND, VT, N0); @@ -3001,7 +3002,7 @@ // fold (zext (truncate x)) -> (and x, mask) if (N0.getOpcode() == ISD::TRUNCATE && - (!AfterLegalize || TLI.isOperationLegal(ISD::AND, VT))) { + (!LegalOperations || TLI.isOperationLegal(ISD::AND, VT))) { SDValue Op = N0.getOperand(0); if (Op.getValueType().bitsLT(VT)) { Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); @@ -3028,7 +3029,7 @@ // fold (zext (load x)) -> (zext (truncate (zextload x))) if (ISD::isNON_EXTLoad(N0.getNode()) && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, N0.getValueType()))) { bool DoXform = true; SmallVector SetCCs; @@ -3037,11 +3038,10 @@ if (DoXform) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), - N0.getValueType(), - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), + N0.getValueType(), + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad); CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1)); @@ -3070,13 +3070,12 @@ ISD::isUNINDEXEDLoad(N0.getNode()) && N0.hasOneUse()) { LoadSDNode *LN0 = cast(N0); MVT EVT = LN0->getMemoryVT(); - if ((!AfterLegalize && !LN0->isVolatile()) || + if ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT)) { SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), @@ -3150,15 +3149,14 @@ // fold (aext (load x)) -> (aext (truncate (extload x))) if (ISD::isNON_EXTLoad(N0.getNode()) && N0.hasOneUse() && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), - N0.getValueType(), - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), + N0.getValueType(), + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); // Redirect any chain users to the new load. DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 1), @@ -3179,11 +3177,10 @@ LoadSDNode *LN0 = cast(N0); MVT EVT = LN0->getMemoryVT(); SDValue ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT, - LN0->getChain(), LN0->getBasePtr(), - LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getChain(), LN0->getBasePtr(), + LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), @@ -3257,7 +3254,7 @@ if (Opc == ISD::SIGN_EXTEND_INREG) { ExtType = ISD::SEXTLOAD; EVT = cast(N->getOperand(1))->getVT(); - if (AfterLegalize && !TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) + if (LegalOperations && !TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) return SDValue(); } @@ -3295,7 +3292,7 @@ uint64_t PtrOff = ShAmt / 8; unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); SDValue NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), - DAG.getConstant(PtrOff, PtrType)); + DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.getNode()); SDValue Load = (ExtType == ISD::NON_EXTLOAD) ? DAG.getLoad(VT, LN0->getChain(), NewPtr, @@ -3389,14 +3386,13 @@ if (ISD::isEXTLoad(N0.getNode()) && ISD::isUNINDEXEDLoad(N0.getNode()) && EVT == cast(N0)->getMemoryVT() && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -3405,14 +3401,13 @@ if (ISD::isZEXTLoad(N0.getNode()) && ISD::isUNINDEXEDLoad(N0.getNode()) && N0.hasOneUse() && EVT == cast(N0)->getMemoryVT() && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), EVT, + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! @@ -3492,7 +3487,7 @@ unsigned NewAlign = TLI.getTargetData()-> getABITypeAlignment(VT.getTypeForMVT()); if (NewAlign <= Align && - (!AfterLegalize || TLI.isOperationLegal(ISD::LOAD, VT))) + (!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(), LD->getSrcValueOffset(), false, Align); @@ -3508,7 +3503,7 @@ // Only do this before legalize, since afterward the target may be depending // on the bitconvert. // First check to see if this is all constant. - if (!AfterLegalize && + if (!LegalTypes && N0.getOpcode() == ISD::BUILD_VECTOR && N0.getNode()->hasOneUse() && VT.isVector()) { bool isSimple = true; @@ -3542,15 +3537,15 @@ if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse() && // Do not change the width of a volatile load. !cast(N0)->isVolatile() && - (!AfterLegalize || TLI.isOperationLegal(ISD::LOAD, VT))) { + (!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) { LoadSDNode *LN0 = cast(N0); unsigned Align = TLI.getTargetData()-> getABITypeAlignment(VT.getTypeForMVT()); unsigned OrigAlign = LN0->getAlignment(); if (Align <= OrigAlign) { SDValue Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(), - LN0->getSrcValue(), LN0->getSrcValueOffset(), - LN0->isVolatile(), OrigAlign); + LN0->getSrcValue(), LN0->getSrcValueOffset(), + LN0->isVolatile(), OrigAlign); AddToWorkList(N); CombineTo(N0.getNode(), DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load), @@ -3581,35 +3576,36 @@ isa(N0.getOperand(0)) && VT.isInteger() && !VT.isVector()) { unsigned OrigXWidth = N0.getOperand(1).getValueType().getSizeInBits(); - SDValue X = DAG.getNode(ISD::BIT_CONVERT, - MVT::getIntegerVT(OrigXWidth), - N0.getOperand(1)); - AddToWorkList(X.getNode()); - - // If X has a different width than the result/lhs, sext it or truncate it. - unsigned VTWidth = VT.getSizeInBits(); - if (OrigXWidth < VTWidth) { - X = DAG.getNode(ISD::SIGN_EXTEND, VT, X); + MVT IntXVT = MVT::getIntegerVT(OrigXWidth); + if (TLI.isTypeLegal(IntXVT) || !LegalTypes) { + SDValue X = DAG.getNode(ISD::BIT_CONVERT, IntXVT, N0.getOperand(1)); AddToWorkList(X.getNode()); - } else if (OrigXWidth > VTWidth) { - // To get the sign bit in the right place, we have to shift it right - // before truncating. - X = DAG.getNode(ISD::SRL, X.getValueType(), X, - DAG.getConstant(OrigXWidth-VTWidth, X.getValueType())); - AddToWorkList(X.getNode()); - X = DAG.getNode(ISD::TRUNCATE, VT, X); - AddToWorkList(X.getNode()); - } + + // If X has a different width than the result/lhs, sext it or truncate it. + unsigned VTWidth = VT.getSizeInBits(); + if (OrigXWidth < VTWidth) { + X = DAG.getNode(ISD::SIGN_EXTEND, VT, X); + AddToWorkList(X.getNode()); + } else if (OrigXWidth > VTWidth) { + // To get the sign bit in the right place, we have to shift it right + // before truncating. + X = DAG.getNode(ISD::SRL, X.getValueType(), X, + DAG.getConstant(OrigXWidth-VTWidth, X.getValueType())); + AddToWorkList(X.getNode()); + X = DAG.getNode(ISD::TRUNCATE, VT, X); + AddToWorkList(X.getNode()); + } - APInt SignBit = APInt::getSignBit(VT.getSizeInBits()); - X = DAG.getNode(ISD::AND, VT, X, DAG.getConstant(SignBit, VT)); - AddToWorkList(X.getNode()); + APInt SignBit = APInt::getSignBit(VT.getSizeInBits()); + X = DAG.getNode(ISD::AND, VT, X, DAG.getConstant(SignBit, VT)); + AddToWorkList(X.getNode()); - SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0)); - Cst = DAG.getNode(ISD::AND, VT, Cst, DAG.getConstant(~SignBit, VT)); - AddToWorkList(Cst.getNode()); + SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0)); + Cst = DAG.getNode(ISD::AND, VT, Cst, DAG.getConstant(~SignBit, VT)); + AddToWorkList(Cst.getNode()); - return DAG.getNode(ISD::OR, VT, X, Cst); + return DAG.getNode(ISD::OR, VT, X, Cst); + } } // bitconvert(build_pair(ld, ld)) -> ld iff load locations are consecutive. @@ -3760,13 +3756,13 @@ if (N0CFP && !N1CFP) return DAG.getNode(ISD::FADD, VT, N1, N0); // fold (A + (-B)) -> A-B - if (isNegatibleForFree(N1, AfterLegalize) == 2) + if (isNegatibleForFree(N1, LegalOperations) == 2) return DAG.getNode(ISD::FSUB, VT, N0, - GetNegatedExpression(N1, DAG, AfterLegalize)); + GetNegatedExpression(N1, DAG, LegalOperations)); // fold ((-A) + B) -> B-A - if (isNegatibleForFree(N0, AfterLegalize) == 2) + if (isNegatibleForFree(N0, LegalOperations) == 2) return DAG.getNode(ISD::FSUB, VT, N1, - GetNegatedExpression(N0, DAG, AfterLegalize)); + GetNegatedExpression(N0, DAG, LegalOperations)); // If allowed, fold (fadd (fadd x, c1), c2) -> (fadd x, (fadd c1, c2)) if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FADD && @@ -3795,14 +3791,14 @@ return DAG.getNode(ISD::FSUB, VT, N0, N1); // fold (0-B) -> -B if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { - if (isNegatibleForFree(N1, AfterLegalize)) - return GetNegatedExpression(N1, DAG, AfterLegalize); + if (isNegatibleForFree(N1, LegalOperations)) + return GetNegatedExpression(N1, DAG, LegalOperations); return DAG.getNode(ISD::FNEG, VT, N1); } // fold (A-(-B)) -> A+B - if (isNegatibleForFree(N1, AfterLegalize)) + if (isNegatibleForFree(N1, LegalOperations)) return DAG.getNode(ISD::FADD, VT, N0, - GetNegatedExpression(N1, DAG, AfterLegalize)); + GetNegatedExpression(N1, DAG, LegalOperations)); return SDValue(); } @@ -3834,14 +3830,14 @@ return DAG.getNode(ISD::FNEG, VT, N0); // -X * -Y -> X*Y - if (char LHSNeg = isNegatibleForFree(N0, AfterLegalize)) { - if (char RHSNeg = isNegatibleForFree(N1, AfterLegalize)) { + if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { + if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) { // Both can be negated for free, check to see if at least one is cheaper // negated. if (LHSNeg == 2 || RHSNeg == 2) return DAG.getNode(ISD::FMUL, VT, - GetNegatedExpression(N0, DAG, AfterLegalize), - GetNegatedExpression(N1, DAG, AfterLegalize)); + GetNegatedExpression(N0, DAG, LegalOperations), + GetNegatedExpression(N1, DAG, LegalOperations)); } } @@ -3873,14 +3869,14 @@ // -X / -Y -> X*Y - if (char LHSNeg = isNegatibleForFree(N0, AfterLegalize)) { - if (char RHSNeg = isNegatibleForFree(N1, AfterLegalize)) { + if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { + if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) { // Both can be negated for free, check to see if at least one is cheaper // negated. if (LHSNeg == 2 || RHSNeg == 2) return DAG.getNode(ISD::FDIV, VT, - GetNegatedExpression(N0, DAG, AfterLegalize), - GetNegatedExpression(N1, DAG, AfterLegalize)); + GetNegatedExpression(N0, DAG, LegalOperations), + GetNegatedExpression(N1, DAG, LegalOperations)); } } @@ -4053,7 +4049,7 @@ ConstantFPSDNode *N0CFP = dyn_cast(N0); // fold (fp_round_inreg c1fp) -> c1fp - if (N0CFP) { + if (N0CFP && (TLI.isTypeLegal(EVT) || !LegalTypes)) { SDValue Round = DAG.getConstantFP(*N0CFP->getConstantFPValue(), EVT); return DAG.getNode(ISD::FP_EXTEND, VT, Round); } @@ -4087,15 +4083,14 @@ // fold (fpext (load x)) -> (fpext (fptrunc (extload x))) if (ISD::isNON_EXTLoad(N0.getNode()) && N0.hasOneUse() && - ((!AfterLegalize && !cast(N0)->isVolatile()) || + ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) { LoadSDNode *LN0 = cast(N0); SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), - LN0->getSrcValueOffset(), - N0.getValueType(), - LN0->isVolatile(), - LN0->getAlignment()); + LN0->getBasePtr(), LN0->getSrcValue(), + LN0->getSrcValueOffset(), + N0.getValueType(), + LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad, DAG.getIntPtrConstant(1)), @@ -4109,8 +4104,8 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { SDValue N0 = N->getOperand(0); - if (isNegatibleForFree(N0, AfterLegalize)) - return GetNegatedExpression(N0, DAG, AfterLegalize); + if (isNegatibleForFree(N0, LegalOperations)) + return GetNegatedExpression(N0, DAG, LegalOperations); // Transform fneg(bitconvert(x)) -> bitconvert(x^sign) to avoid loading // constant pool values. @@ -4193,7 +4188,8 @@ SDValue CondLHS = N->getOperand(2), CondRHS = N->getOperand(3); // Use SimplifySetCC to simplify SETCC's. - SDValue Simp = SimplifySetCC(MVT::i1, CondLHS, CondRHS, CC->get(), false); + SDValue Simp = SimplifySetCC(TLI.getSetCCResultType(CondLHS), + CondLHS, CondRHS, CC->get(), false); if (Simp.getNode()) AddToWorkList(Simp.getNode()); ConstantSDNode *SCCC = dyn_cast_or_null(Simp.getNode()); @@ -4222,7 +4218,7 @@ /// the add / subtract in and all of its other uses are redirected to the /// new load / store. bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) { - if (!AfterLegalize) + if (!LegalOperations) return false; bool isLoad = true; @@ -4343,7 +4339,7 @@ /// load / store effectively and all of its uses are redirected to the /// new load / store. bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) { - if (!AfterLegalize) + if (!LegalOperations) return false; bool isLoad = true; @@ -4651,7 +4647,7 @@ unsigned OrigAlign = TLI.getTargetData()-> getABITypeAlignment(SVT.getTypeForMVT()); if (Align <= OrigAlign && - ((!AfterLegalize && !ST->isVolatile()) || + ((!LegalOperations && !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, SVT))) return DAG.getStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign); @@ -4672,8 +4668,8 @@ case MVT::ppcf128: break; case MVT::f32: - if ((!AfterLegalize && !ST->isVolatile()) || - TLI.isOperationLegal(ISD::STORE, MVT::i32)) { + if (((TLI.isTypeLegal(MVT::i32) || !LegalTypes) && !LegalOperations && + !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i32)) { Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF(). bitcastToAPInt().getZExtValue(), MVT::i32); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), @@ -4682,8 +4678,8 @@ } break; case MVT::f64: - if ((!AfterLegalize && !ST->isVolatile()) || - TLI.isOperationLegal(ISD::STORE, MVT::i64)) { + if (((TLI.isTypeLegal(MVT::i64) || !LegalTypes) && !LegalOperations && + !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i64)) { Tmp = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). getZExtValue(), MVT::i64); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), @@ -4830,7 +4826,7 @@ // Perform only after legalization to ensure build_vector / vector_shuffle // optimizations have already been done. - if (!AfterLegalize) return SDValue(); + if (!LegalOperations) return SDValue(); SDValue InVec = N->getOperand(0); SDValue EltNo = N->getOperand(1); @@ -4973,7 +4969,9 @@ // Add count and size info. MVT BuildVecVT = MVT::getVectorVT(TLI.getPointerTy(), NumElts); - + if (!TLI.isTypeLegal(BuildVecVT) && LegalTypes) + return SDValue(); + // Return the new VECTOR_SHUFFLE node. SDValue Ops[5]; Ops[0] = VecIn1; @@ -5201,7 +5199,7 @@ // After legalize, the target may be depending on adds and other // binary ops to provide legal ways to construct constants or other // things. Simplifying them may result in a loss of legality. - if (AfterLegalize) return SDValue(); + if (LegalOperations) return SDValue(); MVT VT = N->getValueType(0); assert(VT.isVector() && "SimplifyVBinOp only works on vectors!"); @@ -5456,7 +5454,7 @@ // target where it isn't. SDValue Temp, SCC; // cast from setcc result type to select result type - if (AfterLegalize) { + if (LegalTypes) { SCC = DAG.getSetCC(TLI.getSetCCResultType(N0), N0, N1, CC); if (N2.getValueType().bitsLT(SCC.getValueType())) Temp = DAG.getZeroExtendInReg(SCC, N2.getValueType()); @@ -5482,7 +5480,7 @@ // otherwise, go ahead with the folds. if (0 && N3C && N3C->isNullValue() && N2C && (N2C->getAPIntValue() == 1ULL)) { MVT XType = N0.getValueType(); - if (!AfterLegalize || + if (!LegalOperations || TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(N0))) { SDValue Res = DAG.getSetCC(TLI.getSetCCResultType(N0), N0, N1, CC); if (Res.getValueType() != VT) @@ -5492,7 +5490,7 @@ // seteq X, 0 -> srl (ctlz X, log2(size(X))) if (N1C && N1C->isNullValue() && CC == ISD::SETEQ && - (!AfterLegalize || + (!LegalOperations || TLI.isOperationLegal(ISD::CTLZ, XType))) { SDValue Ctlz = DAG.getNode(ISD::CTLZ, XType, N0); return DAG.getNode(ISD::SRL, XType, Ctlz, @@ -5559,7 +5557,7 @@ SDValue N1, ISD::CondCode Cond, bool foldBooleans) { TargetLowering::DAGCombinerInfo - DagCombineInfo(DAG, !AfterLegalize, false, this); + DagCombineInfo(DAG, Level == Unrestricted, false, this); return TLI.SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo); } @@ -5778,9 +5776,8 @@ // SelectionDAG::Combine - This is the entry point for the file. // -void SelectionDAG::Combine(bool RunningAfterLegalize, AliasAnalysis &AA, - bool Fast) { +void SelectionDAG::Combine(CombineLevel Level, AliasAnalysis &AA, bool Fast) { /// run - This is the main entry point to this class. /// - DAGCombiner(*this, AA, Fast).Run(RunningAfterLegalize); + DAGCombiner(*this, AA, Fast).Run(Level); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Mon Nov 24 08:53:14 2008 @@ -20,8 +20,11 @@ using namespace llvm; /// run - This is the main entry point for the type legalizer. This does a -/// top-down traversal of the dag, legalizing types as it goes. -void DAGTypeLegalizer::run() { +/// top-down traversal of the dag, legalizing types as it goes. Returns "true" +/// if it made any changes. +bool DAGTypeLegalizer::run() { + bool Changed = false; + // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted, and tracking any // changes of the root. @@ -65,21 +68,27 @@ break; case PromoteInteger: PromoteIntegerResult(N, i); + Changed = true; goto NodeDone; case ExpandInteger: ExpandIntegerResult(N, i); + Changed = true; goto NodeDone; case SoftenFloat: SoftenFloatResult(N, i); + Changed = true; goto NodeDone; case ExpandFloat: ExpandFloatResult(N, i); + Changed = true; goto NodeDone; case ScalarizeVector: ScalarizeVectorResult(N, i); + Changed = true; goto NodeDone; case SplitVector: SplitVectorResult(N, i); + Changed = true; goto NodeDone; } } @@ -103,21 +112,27 @@ continue; case PromoteInteger: NeedsRevisit = PromoteIntegerOperand(N, i); + Changed = true; break; case ExpandInteger: NeedsRevisit = ExpandIntegerOperand(N, i); + Changed = true; break; case SoftenFloat: NeedsRevisit = SoftenFloatOperand(N, i); + Changed = true; break; case ExpandFloat: NeedsRevisit = ExpandFloatOperand(N, i); + Changed = true; break; case ScalarizeVector: NeedsRevisit = ScalarizeVectorOperand(N, i); + Changed = true; break; case SplitVector: NeedsRevisit = SplitVectorOperand(N, i); + Changed = true; break; } break; @@ -216,6 +231,8 @@ } } #endif + + return Changed; } /// AnalyzeNewNode - The specified node is the root of a subtree of potentially @@ -727,10 +744,11 @@ //===----------------------------------------------------------------------===// /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that -/// only uses types natively supported by the target. +/// only uses types natively supported by the target. Returns "true" if it made +/// any changes. /// /// Note that this is an involved process that may invalidate pointers into /// the graph. -void SelectionDAG::LegalizeTypes() { - DAGTypeLegalizer(*this).run(); +bool SelectionDAG::LegalizeTypes() { + return DAGTypeLegalizer(*this).run(); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Nov 24 08:53:14 2008 @@ -160,7 +160,10 @@ "Too many value types for ValueTypeActions to hold!"); } - void run(); + /// run - This is the main entry point for the type legalizer. This does a + /// top-down traversal of the dag, legalizing types as it goes. Returns + /// "true" if it made any changes. + bool run(); /// ReanalyzeNode - Recompute the NodeId and correct processed operands /// for the specified node, adding it to the worklist if ready. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Nov 24 08:53:14 2008 @@ -88,6 +88,10 @@ cl::desc("Pop up a window to show dags before the second " "dag combine pass")); static cl::opt +ViewDAGCombineLT("view-dag-combine-lt-dags", cl::Hidden, + cl::desc("Pop up a window to show dags before the post legalize types" + " dag combine pass")); +static cl::opt ViewISelDAGs("view-isel-dags", cl::Hidden, cl::desc("Pop up a window to show isel dags as they are selected")); static cl::opt @@ -100,6 +104,7 @@ static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false, ViewLegalizeDAGs = false, ViewDAGCombine2 = false, + ViewDAGCombineLT = false, ViewISelDAGs = false, ViewSchedDAGs = false, ViewSUnitDAGs = false; #endif @@ -556,7 +561,8 @@ GroupName = "Instruction Selection and Scheduling"; std::string BlockName; if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewLegalizeDAGs || - ViewDAGCombine2 || ViewISelDAGs || ViewSchedDAGs || ViewSUnitDAGs) + ViewDAGCombine2 || ViewDAGCombineLT || ViewISelDAGs || ViewSchedDAGs || + ViewSUnitDAGs) BlockName = CurDAG->getMachineFunction().getFunction()->getName() + ':' + BB->getBasicBlock()->getName(); @@ -568,9 +574,9 @@ // Run the DAG combiner in pre-legalize mode. if (TimePassesIsEnabled) { NamedRegionTimer T("DAG Combining 1", GroupName); - CurDAG->Combine(false, *AA, Fast); + CurDAG->Combine(Unrestricted, *AA, Fast); } else { - CurDAG->Combine(false, *AA, Fast); + CurDAG->Combine(Unrestricted, *AA, Fast); } DOUT << "Optimized lowered selection DAG:\n"; @@ -582,17 +588,32 @@ if (ViewLegalizeTypesDAGs) CurDAG->viewGraph("legalize-types input for " + BlockName); + bool Changed; if (TimePassesIsEnabled) { NamedRegionTimer T("Type Legalization", GroupName); - CurDAG->LegalizeTypes(); + Changed = CurDAG->LegalizeTypes(); } else { - CurDAG->LegalizeTypes(); + Changed = CurDAG->LegalizeTypes(); } DOUT << "Type-legalized selection DAG:\n"; DEBUG(CurDAG->dump()); - // TODO: enable a dag combine pass here. + if (Changed) { + if (ViewDAGCombineLT) + CurDAG->viewGraph("dag-combine-lt input for " + BlockName); + + // Run the DAG combiner in post-type-legalize mode. + if (TimePassesIsEnabled) { + NamedRegionTimer T("DAG Combining after legalize types", GroupName); + CurDAG->Combine(NoIllegalTypes, *AA, Fast); + } else { + CurDAG->Combine(NoIllegalTypes, *AA, Fast); + } + + DOUT << "Optimized type-legalized selection DAG:\n"; + DEBUG(CurDAG->dump()); + } } if (ViewLegalizeDAGs) CurDAG->viewGraph("legalize input for " + BlockName); @@ -612,9 +633,9 @@ // Run the DAG combiner in post-legalize mode. if (TimePassesIsEnabled) { NamedRegionTimer T("DAG Combining 2", GroupName); - CurDAG->Combine(true, *AA, Fast); + CurDAG->Combine(NoIllegalOperations, *AA, Fast); } else { - CurDAG->Combine(true, *AA, Fast); + CurDAG->Combine(NoIllegalOperations, *AA, Fast); } DOUT << "Optimized legalized selection DAG:\n"; Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=59960&r1=59959&r2=59960&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Nov 24 08:53:14 2008 @@ -4436,8 +4436,8 @@ // Target Optimization Hooks //===----------------------------------------------------------------------===// -SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, - DAGCombinerInfo &DCI) const { +SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, + DAGCombinerInfo &DCI) const { TargetMachine &TM = getTargetMachine(); SelectionDAG &DAG = DCI.DAG; switch (N->getOpcode()) { From matthijs at stdin.nl Mon Nov 24 10:01:25 2008 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Mon, 24 Nov 2008 16:01:25 -0000 Subject: [llvm-commits] [llvm] r59961 - in /llvm/trunk/lib/CodeGen: RegAllocBigBlock.cpp RegAllocLocal.cpp Message-ID: <200811241601.mAOG1P32012070@zion.cs.uiuc.edu> Author: matthijs Date: Mon Nov 24 10:01:21 2008 New Revision: 59961 URL: http://llvm.org/viewvc/llvm-project?rev=59961&view=rev Log: Minor fix debug for register allocation debug output. Modified: llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp?rev=59961&r1=59960&r2=59961&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBigBlock.cpp Mon Nov 24 10:01:21 2008 @@ -808,14 +808,14 @@ if (PhysReg) { DOUT << " Register " << RegInfo->getName(PhysReg) << " [%reg" << VirtReg - << "] is never used, removing it frame live list\n"; + << "] is never used, removing it from live set\n"; removePhysReg(PhysReg); for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg); *AliasSet; ++AliasSet) { if (PhysRegsUsed[*AliasSet] != -2) { DOUT << " Register " << RegInfo->getName(*AliasSet) << " [%reg" << *AliasSet - << "] is never used, removing it frame live list\n"; + << "] is never used, removing it from live set\n"; removePhysReg(*AliasSet); } } Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=59961&r1=59960&r2=59961&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Mon Nov 24 10:01:21 2008 @@ -945,14 +945,14 @@ if (PhysReg) { DOUT << " Register " << TRI->getName(PhysReg) << " [%reg" << VirtReg - << "] is never used, removing it frame live list\n"; + << "] is never used, removing it from live set\n"; removePhysReg(PhysReg); for (const unsigned *AliasSet = TRI->getAliasSet(PhysReg); *AliasSet; ++AliasSet) { if (PhysRegsUsed[*AliasSet] != -2) { DOUT << " Register " << TRI->getName(*AliasSet) << " [%reg" << *AliasSet - << "] is never used, removing it frame live list\n"; + << "] is never used, removing it from live set\n"; removePhysReg(*AliasSet); } } From pgurd at rapidmind.com Mon Nov 24 10:06:41 2008 From: pgurd at rapidmind.com (Preston Gurd) Date: Mon, 24 Nov 2008 11:06:41 -0500 Subject: [llvm-commits] CVS: llvm-www/Users.html In-Reply-To: <200811221936.mAMJanNs002012@zion.cs.uiuc.edu> References: <200811221936.mAMJanNs002012@zion.cs.uiuc.edu> Message-ID: <1227542801.14435.30.camel@Remington> Hi Chris, Thanks for adding Rapidmind to the llvm users web page! However, the embedded link to http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20081117/009633.html does not seem to be relevant to Rapidmind! Perhaps you intended to use http://rapidmind.com/News-Nov10-08-LLVM-OpenCL.php or http://www.rapidmind.com ? Preston On Sat, 2008-22-11 at 14:36 -0500, Chris Lattner wrote: > > Changes in directory llvm-www: > > Users.html updated: 1.42 -> 1.43 > --- > Log message: > > add rapidmind. > > > --- > Diffs of the changes: (+7 -1) > > Users.html | 8 +++++++- > 1 files changed, 7 insertions(+), 1 deletion(-) > > > Index: llvm-www/Users.html > diff -u llvm-www/Users.html:1.42 llvm-www/Users.html:1.43 > --- llvm-www/Users.html:1.42 Fri Nov 21 00:00:09 2008 > +++ llvm-www/Users.html Sat Nov 22 13:35:32 2008 > @@ -97,6 +97,12 @@ > Compiler for stack machine architecture > > > + > + > + Rapidmind > +
Compiler platform for their GPGPU, multicore CPU, and OpenCL runtime platforms. > + > + > > > Siemens Technology-to-Business Center > @@ -399,6 +405,6 @@ > src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> > >
LLVM Development List
> - Last modified: $Date: 2008/11/21 06:00:09 $ > + Last modified: $Date: 2008/11/22 19:35:32 $ > > > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Mon Nov 24 10:27:23 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 16:27:23 -0000 Subject: [llvm-commits] [llvm] r59962 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <200811241627.mAOGROPn013173@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 10:27:17 2008 New Revision: 59962 URL: http://llvm.org/viewvc/llvm-project?rev=59962&view=rev Log: Some documentation for LegalizeTypes. Modified: llvm/trunk/docs/CodeGenerator.html Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=59962&r1=59961&r2=59962&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Mon Nov 24 10:27:17 2008 @@ -50,6 +50,7 @@ Process
  • Initial SelectionDAG Construction
  • +
  • SelectionDAG LegalizeTypes Phase
  • SelectionDAG Legalize Phase
  • SelectionDAG Optimization Phase: the DAG Combiner
  • @@ -813,8 +814,9 @@ operations and supported types. On a 32-bit PowerPC, for example, a DAG with a value of type i1, i8, i16, or i64 would be illegal, as would a DAG that uses a SREM or UREM operation. The -legalize phase is responsible for turning -an illegal DAG into a legal DAG.

    +legalize types and +legalize operations phases are +responsible for turning an illegal DAG into a legal DAG.

    @@ -837,12 +839,18 @@ pairs) for targets that support these meta operations. This makes the resultant code more efficient and the select instructions from DAG phase (below) simpler. -
  • Legalize SelectionDAG - This stage - converts the illegal SelectionDAG to a legal SelectionDAG by eliminating - unsupported operations and data types.
  • -
  • Optimize SelectionDAG (#2) - This - second run of the SelectionDAG optimizes the newly legalized DAG to - eliminate inefficiencies introduced by legalization.
  • +
  • Legalize SelectionDAG Types - This + stage transforms SelectionDAG nodes to eliminate any types that are + unsupported on the target.
  • +
  • Optimize SelectionDAG - The + SelectionDAG optimizer is run to clean up redundancies exposed + by type legalization.
  • +
  • Legalize SelectionDAG Types - This + stage transforms SelectionDAG nodes to eliminate any types that are + unsupported on the target.
  • +
  • Optimize SelectionDAG - The + SelectionDAG optimizer is run to eliminate inefficiencies introduced + by operation legalization.
  • Select instructions from DAG - Finally, the target instruction selector matches the DAG operations to target instructions. This process translates the target-independent input DAG into @@ -876,7 +884,7 @@

    The -view-sunit-dags displays the Scheduler's dependency graph. This graph is based on the final SelectionDAG, with nodes that must be scheduled together bundled into a single scheduling-unit node, and with -immediate operands and other nodes that aren't relevent for scheduling +immediate operands and other nodes that aren't relevant for scheduling omitted.

    @@ -903,51 +911,67 @@
    -

    The Legalize phase is in charge of converting a DAG to only use the types and -operations that are natively supported by the target. This involves two major -tasks:

    +

    The Legalize phase is in charge of converting a DAG to only use the types +that are natively supported by the target.

    -
      -
    1. Convert values of unsupported types to values of supported types.

      -

      There are two main ways of doing this: converting small types to - larger types ("promoting"), and breaking up large integer types - into smaller ones ("expanding"). For example, a target might require - that all f32 values are promoted to f64 and that all i1/i8/i16 values - are promoted to i32. The same target might require that all i64 values - be expanded into i32 values. These changes can insert sign and zero - extensions as needed to make sure that the final code has the same - behavior as the input.

      -

      A target implementation tells the legalizer which types are supported - (and which register class to use for them) by calling the - addRegisterClass method in its TargetLowering constructor.

      -
    2. +

      There are two main ways of converting values of unsupported scalar types + to values of supported types: converting small types to + larger types ("promoting"), and breaking up large integer types + into smaller ones ("expanding"). For example, a target might require + that all f32 values are promoted to f64 and that all i1/i8/i16 values + are promoted to i32. The same target might require that all i64 values + be expanded into pairs of i32 values. These changes can insert sign and + zero extensions as needed to make sure that the final code has the same + behavior as the input.

      + +

      There are two main ways of converting values of unsupported vector types + to value of supported types: splitting vector types, multiple times if + necessary, until a legal type is found, and extending vector types by + adding elements to the end to round them out to legal types ("widening"). + If a vector gets split all the way down to single-element parts with + no supported vector type being found, the elements are converted to + scalars ("scalarizing").

      + +

      A target implementation tells the legalizer which types are supported + (and which register class to use for them) by calling the + addRegisterClass method in its TargetLowering constructor.

      -
    3. Eliminate operations that are not supported by the target.

      -

      Targets often have weird constraints, such as not supporting every - operation on every supported datatype (e.g. X86 does not support byte - conditional moves and PowerPC does not support sign-extending loads from - a 16-bit memory location). Legalize takes care of this by open-coding - another sequence of operations to emulate the operation ("expansion"), by - promoting one type to a larger type that supports the operation - ("promotion"), or by using a target-specific hook to implement the - legalization ("custom").

      -

      A target implementation tells the legalizer which operations are not - supported (and which of the above three actions to take) by calling the - setOperationAction method in its TargetLowering - constructor.

      -
    4. -
    +
    + + + + +
    + +

    The Legalize phase is in charge of converting a DAG to only use the +operations that are natively supported by the target.

    + +

    Targets often have weird constraints, such as not supporting every + operation on every supported datatype (e.g. X86 does not support byte + conditional moves and PowerPC does not support sign-extending loads from + a 16-bit memory location). Legalize takes care of this by open-coding + another sequence of operations to emulate the operation ("expansion"), by + promoting one type to a larger type that supports the operation + ("promotion"), or by using a target-specific hook to implement the + legalization ("custom").

    + +

    A target implementation tells the legalizer which operations are not + supported (and which of the above three actions to take) by calling the + setOperationAction method in its TargetLowering + constructor.

    -

    Prior to the existance of the Legalize pass, we required that every target +

    Prior to the existence of the Legalize passes, we required that every target selector supported and handled every operator and type even if they are not natively supported. The introduction of -the Legalize phase allows all of the cannonicalization patterns to be shared -across targets, and makes it very easy to optimize the cannonicalized code +the Legalize phases allows all of the canonicalization patterns to be shared +across targets, and makes it very easy to optimize the canonicalized code because it is still in the form of a DAG.

    @@ -960,12 +984,12 @@
    -

    The SelectionDAG optimization phase is run twice for code generation: once -immediately after the DAG is built and once after legalization. The first run -of the pass allows the initial code to be cleaned up (e.g. performing +

    The SelectionDAG optimization phase is run multiple times for code generation, +immediately after the DAG is built and once after each legalization. The first +run of the pass allows the initial code to be cleaned up (e.g. performing optimizations that depend on knowing that the operators have restricted type -inputs). The second run of the pass cleans up the messy code generated by the -Legalize pass, which allows Legalize to be very simple (it can focus on making +inputs). Subsequent runs of the pass clean up the messy code generated by the +Legalize passes, which allows Legalize to be very simple (it can focus on making code legal instead of focusing on generating good and legal code).

    One important class of optimizations performed is optimizing inserted sign @@ -1228,7 +1252,7 @@

    PHI nodes need to be handled specially, because the calculation of the live variable information from a depth first traversal of the CFG of the function won't guarantee that a virtual register used by the PHI -node is defined before it's used. When a PHI node is encounted, only +node is defined before it's used. When a PHI node is encountered, only the definition is handled, because the uses will be handled in other basic blocks.

    @@ -1722,7 +1746,7 @@
    -

    The folowing target-specific calling conventions are known to backend:

    +

    The following target-specific calling conventions are known to backend:

    • x86_StdCall - stdcall calling convention seen on Microsoft Windows @@ -1829,7 +1853,7 @@ not passed the -fomit-frame-pointer flag. The stack pointer is always aligned to 16 bytes, so that space allocated for altivec vectors will be properly aligned.

      -

      An invocation frame is layed out as follows (low memory at top);

      +

      An invocation frame is laid out as follows (low memory at top);

    @@ -1938,7 +1962,7 @@ there are not enough registers or the callee is a thunk or vararg function, these register arguments can be spilled into the parameter area. Thus, the parameter area must be large enough to store all the parameters for the largest -call sequence made by the caller. The size must also be mimimally large enough +call sequence made by the caller. The size must also be minimally large enough to spill registers r3-r10. This allows callees blind to the call signature, such as thunks and vararg functions, enough space to cache the argument registers. Therefore, the parameter area is minimally 32 bytes (64 bytes in 64 @@ -1960,7 +1984,7 @@ linkage and parameter areas. The cost of shifting the linkage and parameter areas is minor since only the link value needs to be copied. The link value can be easily fetched by adding the original frame size to the base pointer. Note -that allocations in the dynamic space need to observe 16 byte aligment.

    +that allocations in the dynamic space need to observe 16 byte alignment.

    From gohman at apple.com Mon Nov 24 10:35:38 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 16:35:38 -0000 Subject: [llvm-commits] [llvm] r59963 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <200811241635.mAOGZdE3013536@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 10:35:31 2008 New Revision: 59963 URL: http://llvm.org/viewvc/llvm-project?rev=59963&view=rev Log: Fix some "

    "s. Modified: llvm/trunk/docs/CodeGenerator.html Modified: llvm/trunk/docs/CodeGenerator.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=59963&r1=59962&r2=59963&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Mon Nov 24 10:35:31 2008 @@ -1077,7 +1077,7 @@

    The portion of the instruction definition in bold indicates the pattern used to match the instruction. The DAG operators (like fmul/fadd) are defined in the lib/Target/TargetSelectionDAG.td file. -"F4RC" is the register class of the input and result values.

    +"F4RC" is the register class of the input and result values.

    The TableGen DAG instruction selector generator reads the instruction patterns in the .td file and automatically builds parts of the pattern @@ -1556,7 +1556,7 @@

    -

    can be safely substituted by the single instruction: +

    can be safely substituted by the single instruction:

    
    
    
    
    From gohman at apple.com  Mon Nov 24 10:45:25 2008
    From: gohman at apple.com (Dan Gohman)
    Date: Mon, 24 Nov 2008 16:45:25 -0000
    Subject: [llvm-commits] [llvm] r59964 - /llvm/trunk/docs/CodeGenerator.html
    Message-ID: <200811241645.mAOGjR8O014004@zion.cs.uiuc.edu>
    
    Author: djg
    Date: Mon Nov 24 10:45:15 2008
    New Revision: 59964
    
    URL: http://llvm.org/viewvc/llvm-project?rev=59964&view=rev
    Log:
    Delete some spurious characters.
    
    Modified:
        llvm/trunk/docs/CodeGenerator.html
    
    Modified: llvm/trunk/docs/CodeGenerator.html
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=59964&r1=59963&r2=59964&view=diff
    
    ==============================================================================
    --- llvm/trunk/docs/CodeGenerator.html (original)
    +++ llvm/trunk/docs/CodeGenerator.html Mon Nov 24 10:45:15 2008
    @@ -1532,7 +1532,7 @@
     from the target code. The most traditional PHI deconstruction
     algorithm replaces PHI instructions with copy instructions. That is
     the strategy adopted by LLVM. The SSA deconstruction algorithm is
    -implemented in nlib/CodeGen/>PHIElimination.cpp. In order to
    +implemented in lib/CodeGen/PHIElimination.cpp. In order to
     invoke this pass, the identifier PHIEliminationID must be
     marked as required in the code of the register allocator.

    From scottm at aero.org Mon Nov 24 11:11:17 2008 From: scottm at aero.org (Scott Michel) Date: Mon, 24 Nov 2008 17:11:17 -0000 Subject: [llvm-commits] [llvm] r59965 - in /llvm/trunk: lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp lib/Target/CellSPU/README.txt lib/Target/CellSPU/SPUISelLowering.cpp lib/Target/CellSPU/SPUISelLowering.h lib/Target/CellSPU/SPUInstrInfo.td lib/Target/CellSPU/SPUNodes.td test/CodeGen/CellSPU/extract_elt.ll Message-ID: <200811241711.mAOHBHb5015342@zion.cs.uiuc.edu> Author: pingbak Date: Mon Nov 24 11:11:17 2008 New Revision: 59965 URL: http://llvm.org/viewvc/llvm-project?rev=59965&view=rev Log: CellSPU: (a) Improve the extract element code: there's no need to do gymnastics with rotates into the preferred slot if a shuffle will do the same thing. (b) Rename a couple of SPUISD pseudo-instructions for readability and better semantic correspondence. (c) Fix i64 sign/any/zero extension lowering. Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp llvm/trunk/lib/Target/CellSPU/README.txt llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/lib/Target/CellSPU/SPUNodes.td llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp Mon Nov 24 11:11:17 2008 @@ -261,7 +261,7 @@ void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo) { if (MI->getOperand(OpNo).isImm()) { int value = (int) MI->getOperand(OpNo).getImm(); - assert((value >= 0 && value < 32) + assert((value >= 0 && value <= 32) && "Invalid negated immediate rotate 7-bit argument"); O << -value; } else { Modified: llvm/trunk/lib/Target/CellSPU/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/README.txt?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/README.txt (original) +++ llvm/trunk/lib/Target/CellSPU/README.txt Mon Nov 24 11:11:17 2008 @@ -8,6 +8,7 @@ - Mark Thomas (floating point instructions) - Michael AuYeung (intrinsics) - Chandler Carruth (LLVM expertise) +- Nehal Desai (debugging, RoadRunner SPU expertise) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -33,6 +34,11 @@ --------------------------------------------------------------------------- +The unofficially official status page (because it's not easy to get an +officially blessed external web page from either IBM Austin or Aerosapce): + + http://sites.google.com/site/llvmcellspu/ + TODO: * Finish branch instructions, branch prediction Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Nov 24 11:11:17 2008 @@ -425,9 +425,9 @@ node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK"; node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB"; node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR"; - node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0"; - node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] - = "SPUISD::EXTRACT_ELT0_CHAINED"; + node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT"; + node_names[(unsigned) SPUISD::VEC2PREFSLOT_CHAINED] + = "SPUISD::VEC2PREFSLOT_CHAINED"; node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT"; node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT"; node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT"; @@ -447,8 +447,6 @@ "SPUISD::ROTQUAD_RZ_BYTES"; node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] = "SPUISD::ROTQUAD_RZ_BITS"; - node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] = - "SPUISD::ROTBYTES_RIGHT_S"; node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT"; node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] = "SPUISD::ROTBYTES_LEFT_CHAINED"; @@ -647,7 +645,7 @@ Ops[0] = the_chain; Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result); scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other); - result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2); + result = DAG.getNode(SPUISD::VEC2PREFSLOT_CHAINED, scalarvts, Ops, 2); the_chain = result.getValue(1); } else { // Handle the sign and zero-extending loads for i1 and i8: @@ -889,7 +887,7 @@ if (VT == MVT::i64) { SDValue T = DAG.getConstant(CN->getZExtValue(), MVT::i64); - return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T)); } else { cerr << "LowerConstant: unhandled constant type " @@ -1603,7 +1601,7 @@ case MVT::v2f64: { uint64_t f64val = SplatBits; assert(SplatSize == 8 - && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size."); + && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes."); // NOTE: pretend the constant is an integer. LLVM won't load FP constants SDValue T = DAG.getConstant(f64val, MVT::i64); return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, @@ -1656,8 +1654,8 @@ // specialized masks to replace any and all 0's, 0xff's and 0x80's. // Detect if the upper or lower half is a special shuffle mask pattern: - upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000); - lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000); + upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000); + lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000); // Create lower vector if not a special pattern if (!lower_special) { @@ -2077,7 +2075,7 @@ if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) { // i32 and i64: Element 0 is the preferred slot - return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N); + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N); } // Need to generate shuffle mask and extract: @@ -2140,7 +2138,7 @@ &ShufMask[0], sizeof(ShufMask) / sizeof(ShufMask[0])); - retval = DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(SPUISD::SHUFB, N.getValueType(), N, N, ShufMaskVec)); } else { @@ -2158,60 +2156,20 @@ // Scale the index to a bit/byte shift quantity APInt scaleFactor = - APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false); + APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false); + unsigned scaleShift = scaleFactor.logBase2(); SDValue vecShift; - - switch (VT.getSimpleVT()) { - default: - cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n"; - abort(); - /*NOTREACHED*/ - case MVT::i8: { - // Don't need to scale, but we do need to correct for where bytes go in - // slot 0: - SDValue prefSlot = DAG.getNode(ISD::SUB, MVT::i32, - Elt, DAG.getConstant(3, MVT::i32)); - SDValue corrected = DAG.getNode(ISD::ADD, MVT::i32, prefSlot, - DAG.getConstant(16, MVT::i32)); - - SDValue shiftAmt = DAG.getNode(ISD::SELECT_CC, MVT::i32, - prefSlot, DAG.getConstant(0, MVT::i32), - prefSlot, // trueval - corrected, // falseval - DAG.getCondCode(ISD::SETGT)); - vecShift = DAG.getNode(SPUISD::ROTBYTES_LEFT, VecVT, N, shiftAmt); - break; - } - case MVT::i16: { - // Scale the index to bytes, subtract for preferred slot: - Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt, - DAG.getConstant(scaleFactor.logBase2(), MVT::i32)); - SDValue prefSlot = DAG.getNode(ISD::SUB, MVT::i32, - Elt, DAG.getConstant(2, MVT::i32)); - SDValue corrected = DAG.getNode(ISD::ADD, MVT::i32, prefSlot, - DAG.getConstant(16, MVT::i32)); - - SDValue shiftAmt = DAG.getNode(ISD::SELECT_CC, MVT::i32, - prefSlot, DAG.getConstant(0, MVT::i32), - prefSlot, // trueval - corrected, // falseval - DAG.getCondCode(ISD::SETGT)); - vecShift = DAG.getNode(SPUISD::ROTBYTES_LEFT, VecVT, N, shiftAmt); - break; - } - case MVT::i32: - case MVT::f32: - case MVT::i64: - case MVT::f64: - // Simple left shift to slot 0 + + if (scaleShift > 0) { + // Scale the shift factor: Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt, - DAG.getConstant(scaleFactor.logBase2(), MVT::i32)); - vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt); - break; + DAG.getConstant(scaleShift, MVT::i32)); } - // Replicate slot 0 across the entire vector (for consistency with the - // notion of a unified register set) + vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt); + + // Replicate the bytes starting at byte 0 across the entire vector (for + // consistency with the notion of a unified register set) SDValue replicate; switch (VT.getSimpleVT()) { @@ -2220,13 +2178,13 @@ abort(); /*NOTREACHED*/ case MVT::i8: { - SDValue factor = DAG.getConstant(0x03030303, MVT::i32); + SDValue factor = DAG.getConstant(0x00000000, MVT::i32); replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor, factor, factor); break; } case MVT::i16: { - SDValue factor = DAG.getConstant(0x02030203, MVT::i32); + SDValue factor = DAG.getConstant(0x00010001, MVT::i32); replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor, factor, factor); break; @@ -2248,7 +2206,7 @@ } } - retval = DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(SPUISD::SHUFB, VecVT, vecShift, vecShift, replicate)); } @@ -2400,19 +2358,34 @@ assert(Op0VT == MVT::i32 && "CellSPU: Zero/sign extending something other than i32"); - DEBUG(cerr << "CellSPU: LowerI64Math custom lowering zero/sign/any extend\n"); - unsigned NewOpc = (Opc == ISD::SIGN_EXTEND - ? SPUISD::ROTBYTES_RIGHT_S - : SPUISD::ROTQUAD_RZ_BYTES); + DEBUG(cerr << "CellSPU.LowerI64Math: lowering zero/sign/any extend\n"); + SDValue PromoteScalar = - DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0); + DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0); + SDValue RotQuad = + DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, Op0VecVT, + PromoteScalar, DAG.getConstant(4, MVT::i32)); + + if (Opc != ISD::SIGN_EXTEND) { + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, + DAG.getNode(ISD::BIT_CONVERT, VecVT, RotQuad)); + } else { + // SPU has no "rotate quadword and replicate bit 0" (i.e. rotate/shift + // right and propagate the sign bit) instruction. + SDValue SignQuad = + DAG.getNode(SPUISD::VEC_SRA, Op0VecVT, + PromoteScalar, DAG.getConstant(32, MVT::i32)); + SDValue SelMask = + DAG.getNode(SPUISD::SELECT_MASK, Op0VecVT, + DAG.getConstant(0xf0f0, MVT::i16)); + SDValue CombineQuad = + DAG.getNode(SPUISD::SELB, Op0VecVT, + SignQuad, RotQuad, SelMask); - return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, - DAG.getNode(ISD::BIT_CONVERT, VecVT, - DAG.getNode(NewOpc, Op0VecVT, - PromoteScalar, - DAG.getConstant(4, MVT::i32)))); + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, + DAG.getNode(ISD::BIT_CONVERT, VecVT, CombineQuad)); + } } case ISD::ADD: { @@ -2439,7 +2412,7 @@ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, &ShufBytes[0], ShufBytes.size())); - return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64, + return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64, DAG.getNode(SPUISD::ADD_EXTENDED, MVT::v2i64, Op0, Op1, ShiftedCarry)); } @@ -2468,7 +2441,7 @@ DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, &ShufBytes[0], ShufBytes.size())); - return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64, + return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64, DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64, Op0, Op1, ShiftedBorrow)); } @@ -2492,7 +2465,7 @@ ShiftAmt, DAG.getConstant(7, ShiftAmtVT)); - return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT, DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, MaskLower, ShiftAmtBytes), @@ -2532,7 +2505,7 @@ } SDValue UpperHalfSign = - DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i32, + DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i32, DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, DAG.getNode(SPUISD::VEC_SRA, MVT::v2i64, Op0, DAG.getConstant(31, MVT::i32)))); @@ -2551,7 +2524,7 @@ DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v2i64, RotateLeftBytes, ShiftAmt); - return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64, + return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64, RotateLeftBits); } } @@ -2968,7 +2941,7 @@ case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: case ISD::ANY_EXTEND: { - if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 && + if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && N->getValueType(0) == Op0.getValueType()) { // (any_extend (SPUextract_elt0 )) -> // (SPUextract_elt0 ) @@ -3031,7 +3004,7 @@ // // but only if the SPUpromote_scalar and types match. SDValue Op00 = Op0.getOperand(0); - if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) { + if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) { SDValue Op000 = Op00.getOperand(0); if (Op000.getValueType() == N->getValueType(0)) { Result = Op000; @@ -3039,7 +3012,7 @@ } break; } - case SPUISD::EXTRACT_ELT0: { + case SPUISD::VEC2PREFSLOT: { // (SPUpromote_scalar (SPUextract_elt0 )) -> // Result = Op0.getOperand(0); @@ -3146,8 +3119,8 @@ } case SPUISD::LDRESULT: - case SPUISD::EXTRACT_ELT0: - case SPUISD::EXTRACT_ELT0_CHAINED: { + case SPUISD::VEC2PREFSLOT: + case SPUISD::VEC2PREFSLOT_CHAINED: { MVT OpVT = Op.getValueType(); unsigned OpVTBits = OpVT.getSizeInBits(); uint64_t InMask = OpVT.getIntegerVTBitMask(); @@ -3174,7 +3147,6 @@ case SPUISD::VEC_ROTR: case SPUISD::ROTQUAD_RZ_BYTES: case SPUISD::ROTQUAD_RZ_BITS: - case SPUISD::ROTBYTES_RIGHT_S: case SPUISD::ROTBYTES_LEFT: case SPUISD::ROTBYTES_LEFT_CHAINED: case SPUISD::SELECT_MASK: Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Mon Nov 24 11:11:17 2008 @@ -40,8 +40,8 @@ SHUFFLE_MASK, ///< Shuffle mask CNTB, ///< Count leading ones in bytes PROMOTE_SCALAR, ///< Promote scalar->vector - EXTRACT_ELT0, ///< Extract element 0 - EXTRACT_ELT0_CHAINED, ///< Extract element 0, with chain + VEC2PREFSLOT, ///< Extract element 0 + VEC2PREFSLOT_CHAINED, ///< Extract element 0, with chain EXTRACT_I1_ZEXT, ///< Extract element 0 as i1, zero extend EXTRACT_I1_SEXT, ///< Extract element 0 as i1, sign extend EXTRACT_I8_ZEXT, ///< Extract element 0 as i8, zero extend @@ -59,7 +59,6 @@ VEC_ROTR, ///< Vector rotate right ROTQUAD_RZ_BYTES, ///< Rotate quad right, by bytes, zero fill ROTQUAD_RZ_BITS, ///< Rotate quad right, by bits, zero fill - ROTBYTES_RIGHT_S, ///< Vector rotate right, by bytes, sign fill ROTBYTES_LEFT, ///< Rotate bytes (loads -> ROTQBYI) ROTBYTES_LEFT_CHAINED, ///< Rotate bytes (loads -> ROTQBYI), with chain ROTBYTES_LEFT_BITS, ///< Rotate bytes left by bit shift count Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Mon Nov 24 11:11:17 2008 @@ -1286,40 +1286,40 @@ // ORi*_v*: Used to extract vector element 0 (the preferred slot) -def : Pat<(SPUextract_elt0 (v16i8 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v16i8 VECREG:$rA)), (ORi8_v16i8 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v16i8 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v16i8 VECREG:$rA)), (ORi8_v16i8 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0 (v8i16 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v8i16 VECREG:$rA)), (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v8i16 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v8i16 VECREG:$rA)), (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0 (v4i32 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v4i32 VECREG:$rA)), (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v4i32 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v4i32 VECREG:$rA)), (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0 (v2i64 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v2i64 VECREG:$rA)), (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v2i64 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v2i64 VECREG:$rA)), (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0 (v4f32 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v4f32 VECREG:$rA)), (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v4f32 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v4f32 VECREG:$rA)), (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0 (v2f64 VECREG:$rA)), +def : Pat<(SPUvec2prefslot (v2f64 VECREG:$rA)), (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUextract_elt0_chained (v2f64 VECREG:$rA)), +def : Pat<(SPUvec2prefslot_chained (v2f64 VECREG:$rA)), (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; // ORC: Bitwise "or" with complement (c = a | ~b) Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Mon Nov 24 11:11:17 2008 @@ -121,9 +121,6 @@ def SPUrotquad_rz_bits: SDNode<"SPUISD::ROTQUAD_RZ_BITS", SPUvecshift_type, []>; -def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S", - SPUvecshift_type, []>; - // Vector rotate left, bits shifted out of the left are rotated in on the right def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT", SPUvecshift_type, []>; @@ -155,9 +152,9 @@ def SPUpromote_scalar: SDNode<"SPUISD::PROMOTE_SCALAR", SDTpromote_scalar, []>; def SPU_vec_demote : SDTypeProfile<1, 1, []>; -def SPUextract_elt0: SDNode<"SPUISD::EXTRACT_ELT0", SPU_vec_demote, []>; +def SPUvec2prefslot: SDNode<"SPUISD::VEC2PREFSLOT", SPU_vec_demote, []>; def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>; -def SPUextract_elt0_chained: SDNode<"SPUISD::EXTRACT_ELT0_CHAINED", +def SPUvec2prefslot_chained: SDNode<"SPUISD::VEC2PREFSLOT_CHAINED", SPU_vec_demote_chained, [SDNPHasChain]>; def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>; def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>; Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll?rev=59965&r1=59964&r2=59965&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Mon Nov 24 11:11:17 2008 @@ -1,12 +1,10 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep shufb %t1.s | count 39 -; RUN: grep ilhu %t1.s | count 31 -; RUN: grep iohl %t1.s | count 31 +; RUN: grep ilhu %t1.s | count 27 +; RUN: grep iohl %t1.s | count 27 ; RUN: grep lqa %t1.s | count 10 -; RUN: grep shlqbyi %t1.s | count 8 -; RUN: grep selb %t1.s | count 4 -; RUN: grep cgti %t1.s | count 4 -; RUN: grep 515 %t1.s | count 5 +; RUN: grep shlqbyi %t1.s | count 12 +; RUN: grep 515 %t1.s | count 1 ; RUN: grep 1029 %t1.s | count 2 ; RUN: grep 1543 %t1.s | count 2 ; RUN: grep 2057 %t1.s | count 2 From gohman at apple.com Mon Nov 24 11:18:43 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 17:18:43 -0000 Subject: [llvm-commits] [llvm] r59966 - in /llvm/trunk/docs: CodingStandards.html CompilerWriterInfo.html FAQ.html LangRef.html Lexicon.html Message-ID: <200811241718.mAOHIiNR015578@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 11:18:39 2008 New Revision: 59966 URL: http://llvm.org/viewvc/llvm-project?rev=59966&view=rev Log: Fix a few HTML tidiness issues. Modified: llvm/trunk/docs/CodingStandards.html llvm/trunk/docs/CompilerWriterInfo.html llvm/trunk/docs/FAQ.html llvm/trunk/docs/LangRef.html llvm/trunk/docs/Lexicon.html Modified: llvm/trunk/docs/CodingStandards.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodingStandards.html?rev=59966&r1=59965&r2=59966&view=diff ============================================================================== --- llvm/trunk/docs/CodingStandards.html (original) +++ llvm/trunk/docs/CodingStandards.html Mon Nov 24 11:18:39 2008 @@ -645,7 +645,7 @@
    -assert(0 && "Some helpful error message");
    +assert(0 && "Some helpful error message");
     
    @@ -656,7 +656,7 @@
    -assert(0 && "Some helpful error message");
    +assert(0 && "Some helpful error message");
     // Not reached
     return 0;
     
    Modified: llvm/trunk/docs/CompilerWriterInfo.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CompilerWriterInfo.html?rev=59966&r1=59965&r2=59966&view=diff ============================================================================== --- llvm/trunk/docs/CompilerWriterInfo.html (original) +++ llvm/trunk/docs/CompilerWriterInfo.html Mon Nov 24 11:18:39 2008 @@ -7,6 +7,8 @@ + +
    Architecture/platform information for compiler writers
    Modified: llvm/trunk/docs/FAQ.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/FAQ.html?rev=59966&r1=59965&r2=59966&view=diff ============================================================================== --- llvm/trunk/docs/FAQ.html (original) +++ llvm/trunk/docs/FAQ.html Mon Nov 24 11:18:39 2008 @@ -61,7 +61,7 @@
  • What source languages are supported?
  • I'd like to write a self-hosting LLVM compiler. How should I interface with the LLVM middle-end optimizers and back-end code - generators?
  • + generators?
  • What support is there for higher level source language constructs for building a compiler?
  • I don't understand the GetElementPtr @@ -85,7 +85,7 @@ How can I disable all optimizations when compiling code using the LLVM GCC front end?
  • -
  • Can I use LLVM to convert C++ code to C code?
  • +
  • Can I use LLVM to convert C++ code to C code?
  • @@ -480,7 +480,7 @@ of running optimizations, linking, and executable generation.

    -

    +

    @@ -565,7 +565,7 @@ Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=59966&r1=59965&r2=59966&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Nov 24 11:18:39 2008 @@ -565,7 +565,7 @@ -

    For example, since the ".LC0" +

    For example, since the ".LC0" variable is defined to be internal, if another module defined a ".LC0" variable and was linked with this one, one of the two would be renamed, preventing a collision. Since "main" and "puts" are Modified: llvm/trunk/docs/Lexicon.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Lexicon.html?rev=59966&r1=59965&r2=59966&view=diff ============================================================================== --- llvm/trunk/docs/Lexicon.html (original) +++ llvm/trunk/docs/Lexicon.html Mon Nov 24 11:18:39 2008 @@ -36,6 +36,7 @@ DSE - G - + GC - I - From gohman at apple.com Mon Nov 24 11:22:52 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 17:22:52 -0000 Subject: [llvm-commits] [llvm] r59967 - /llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Message-ID: <200811241722.mAOHMq7L015773@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 11:22:52 2008 New Revision: 59967 URL: http://llvm.org/viewvc/llvm-project?rev=59967&view=rev Log: Run post-RA scheduling after branch folding, as it tends to obscure tail-merging opportunities. Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=59967&r1=59966&r2=59967&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Nov 24 11:22:52 2008 @@ -225,6 +225,13 @@ if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(cerr)); + // Branch folding must be run after regalloc and prolog/epilog insertion. + if (!Fast) + PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(cerr)); + // Second pass scheduler. if (!Fast && !DisablePostRAScheduler) { PM.add(createPostRAScheduler()); @@ -233,10 +240,6 @@ PM.add(createMachineFunctionPrinterPass(cerr)); } - // Branch folding must be run after regalloc and prolog/epilog insertion. - if (!Fast) - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - PM.add(createGCMachineCodeAnalysisPass()); if (PrintMachineCode) From gohman at apple.com Mon Nov 24 11:24:27 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 17:24:27 -0000 Subject: [llvm-commits] [llvm] r59968 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200811241724.mAOHOR0o015831@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 11:24:27 2008 New Revision: 59968 URL: http://llvm.org/viewvc/llvm-project?rev=59968&view=rev Log: Pass the isAntiDep argument. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=59968&r1=59967&r2=59968&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Mon Nov 24 11:24:27 2008 @@ -58,7 +58,7 @@ SUnit *&Def = Defs[*Alias]; if (Def && Def != SU) Def->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false, - /*PhyReg=*/*Alias, Cost); + /*PhyReg=*/*Alias, Cost, /*isAntiDep=*/MO.isUse()); } if (MO.isDef()) { From gohman at apple.com Mon Nov 24 11:33:53 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 17:33:53 -0000 Subject: [llvm-commits] [llvm] r59969 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200811241733.mAOHXr0B016170@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 11:33:52 2008 New Revision: 59969 URL: http://llvm.org/viewvc/llvm-project?rev=59969&view=rev Log: Check in the rest of this change. The isAntiDep flag needs to be passed to removePred because an SUnit can both data-depend and anti-depend on the same SUnit. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59969&r1=59968&r2=59969&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Nov 24 11:33:52 2008 @@ -164,7 +164,7 @@ return true; } - bool removePred(SUnit *N, bool isCtrl, bool isArtificial) { + bool removePred(SUnit *N, bool isCtrl, bool isArtificial, bool isAntiDep) { for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) if (I->Dep == N && I->isCtrl == isCtrl && I->isArtificial == isArtificial) { @@ -172,7 +172,8 @@ for (SmallVector::iterator II = N->Succs.begin(), EE = N->Succs.end(); II != EE; ++II) if (II->Dep == this && - II->isCtrl == isCtrl && II->isArtificial == isArtificial) { + II->isCtrl == isCtrl && II->isArtificial == isArtificial && + II->isAntiDep == isAntiDep) { FoundSucc = true; N->Succs.erase(II); break; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59969&r1=59968&r2=59969&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Mon Nov 24 11:33:52 2008 @@ -198,7 +198,7 @@ /// the current node M. bool ScheduleDAGFast::RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial) { - return M->removePred(N, isCtrl, isArtificial); + return M->removePred(N, isCtrl, isArtificial, false); } /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59969&r1=59968&r2=59969&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Nov 24 11:33:52 2008 @@ -506,7 +506,7 @@ bool ScheduleDAGRRList::RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial) { // InitDAGTopologicalSorting(); - return M->removePred(N, isCtrl, isArtificial); + return M->removePred(N, isCtrl, isArtificial, false); } /// DFS - Make a DFS traversal to mark all nodes reachable from SU and mark From scottm at aero.org Mon Nov 24 12:20:47 2008 From: scottm at aero.org (Scott Michel) Date: Mon, 24 Nov 2008 18:20:47 -0000 Subject: [llvm-commits] [llvm] r59970 - in /llvm/trunk: lib/Target/CellSPU/SPUISelLowering.cpp test/CodeGen/CellSPU/i64ops.ll Message-ID: <200811241820.mAOIKl4Q017800@zion.cs.uiuc.edu> Author: pingbak Date: Mon Nov 24 12:20:46 2008 New Revision: 59970 URL: http://llvm.org/viewvc/llvm-project?rev=59970&view=rev Log: CellSPU: (a) Slight rethink on i64 zero/sign/any extend code - use a shuffle to directly zero-extend i32 to i64, but use rotates and shifts for sign extension. Also ensure unified register consistency. (b) Add new test harness for i64 operations: i64ops.ll Added: llvm/trunk/test/CodeGen/CellSPU/i64ops.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59970&r1=59969&r2=59970&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Nov 24 12:20:46 2008 @@ -2363,16 +2363,27 @@ SDValue PromoteScalar = DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0); - SDValue RotQuad = - DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, Op0VecVT, - PromoteScalar, DAG.getConstant(4, MVT::i32)); if (Opc != ISD::SIGN_EXTEND) { + // Use a shuffle to zero extend the i32 to i64 directly: + SDValue shufMask = + DAG.getNode(ISD::BUILD_VECTOR, Op0VecVT, + DAG.getConstant(0x80808080, MVT::i32), + DAG.getConstant(0x00010203, MVT::i32), + DAG.getConstant(0x80808080, MVT::i32), + DAG.getConstant(0x08090a0b, MVT::i32)); + SDValue zextShuffle = + DAG.getNode(SPUISD::SHUFB, Op0VecVT, + PromoteScalar, PromoteScalar, shufMask); + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, - DAG.getNode(ISD::BIT_CONVERT, VecVT, RotQuad)); + DAG.getNode(ISD::BIT_CONVERT, VecVT, zextShuffle)); } else { // SPU has no "rotate quadword and replicate bit 0" (i.e. rotate/shift // right and propagate the sign bit) instruction. + SDValue RotQuad = + DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, Op0VecVT, + PromoteScalar, DAG.getConstant(4, MVT::i32)); SDValue SignQuad = DAG.getNode(SPUISD::VEC_SRA, Op0VecVT, PromoteScalar, DAG.getConstant(32, MVT::i32)); Added: llvm/trunk/test/CodeGen/CellSPU/i64ops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/i64ops.ll?rev=59970&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/i64ops.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/i64ops.ll Mon Nov 24 12:20:46 2008 @@ -0,0 +1,27 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep {fsmbi.*61680} %t1.s | count 1 +; RUN: grep rotqmbyi %t1.s | count 1 +; RUN: grep rotmai %t1.s | count 1 +; RUN: grep selb %t1.s | count 1 +; RUN: grep shufb %t1.s | count 2 +; RUN: grep cg %t1.s | count 1 +; RUN: grep addx %t1.s | count 1 + +; ModuleID = 'stores.bc' +target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" +target triple = "spu" + +define i64 @sext_i64_i32(i32 %a) nounwind { + %1 = sext i32 %a to i64 + ret i64 %1 +} + +define i64 @zext_i64_i32(i32 %a) nounwind { + %1 = zext i32 %a to i64 + ret i64 %1 +} + +define i64 @add_i64(i64 %a, i64 %b) nounwind { + %1 = add i64 %a, %b + ret i64 %1 +} From clattner at apple.com Mon Nov 24 13:02:14 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 Nov 2008 11:02:14 -0800 Subject: [llvm-commits] CVS: llvm-www/Users.html In-Reply-To: <1227542801.14435.30.camel@Remington> References: <200811221936.mAMJanNs002012@zion.cs.uiuc.edu> <1227542801.14435.30.camel@Remington> Message-ID: <4BF192A2-30E3-47AA-A5FC-1CD494315670@apple.com> On Nov 24, 2008, at 8:06 AM, Preston Gurd wrote: > Hi Chris, > > Thanks for adding Rapidmind to the llvm users web page! > > However, the embedded link to > http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20081117/009633.html > does not seem to be relevant to Rapidmind! Perhaps you intended to use > http://rapidmind.com/News-Nov10-08-LLVM-OpenCL.php or > http://www.rapidmind.com ? Urr... yeah, how about that. :) Fixed! Thanks for pointing this out, -Chris From sabre at nondot.org Mon Nov 24 13:03:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 13:03:10 -0600 Subject: [llvm-commits] CVS: llvm-www/Users.html Message-ID: <200811241903.mAOJ3A28019519@zion.cs.uiuc.edu> Changes in directory llvm-www: Users.html updated: 1.45 -> 1.46 --- Log message: fix rapidmind link. --- Diffs of the changes: (+2 -2) Users.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/Users.html diff -u llvm-www/Users.html:1.45 llvm-www/Users.html:1.46 --- llvm-www/Users.html:1.45 Sun Nov 23 01:39:28 2008 +++ llvm-www/Users.html Mon Nov 24 13:01:48 2008 @@ -100,7 +100,7 @@ Rapidmind - Compiler platform for their GPGPU, multicore CPU, and OpenCL runtime platforms. + Compiler platform for their GPGPU, multicore CPU, and OpenCL runtime platforms. @@ -405,6 +405,6 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!">
    LLVM Development List
    - Last modified: $Date: 2008/11/23 07:39:28 $ + Last modified: $Date: 2008/11/24 19:01:48 $ From clattner at apple.com Mon Nov 24 13:04:48 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 Nov 2008 11:04:48 -0800 Subject: [llvm-commits] [llvm] r59960 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/PowerPC/PPCISelLowering.cpp In-Reply-To: <200811241453.mAOErL7j009491@zion.cs.uiuc.edu> References: <200811241453.mAOErL7j009491@zion.cs.uiuc.edu> Message-ID: <5D51222E-8941-495A-B86A-FDE6433EEADB@apple.com> On Nov 24, 2008, at 6:53 AM, Duncan Sands wrote: > Author: baldrick > Date: Mon Nov 24 08:53:14 2008 > New Revision: 59960 > > URL: http://llvm.org/viewvc/llvm-project?rev=59960&view=rev > Log: > If the type legalizer actually legalized anything > (this doesn't happen that often, since most code > does not use illegal types) then follow it by a > DAG combiner run that is allowed to generate > illegal operations but not illegal types. I didn't > modify the target combiner code to distinguish like > this between illegal operations and illegal types, > so it will not produce illegal operations as well > as not producing illegal types. Nifty, does this improve anything? Can you add a testcase? -Chris From isanbard at gmail.com Mon Nov 24 13:21:49 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 19:21:49 -0000 Subject: [llvm-commits] [llvm] r59971 - in /llvm/trunk/lib: CodeGen/SelectionDAG/LegalizeDAG.cpp CodeGen/SelectionDAG/SelectionDAGBuild.cpp Target/X86/X86ISelLowering.cpp Target/X86/X86ISelLowering.h Message-ID: <200811241921.mAOJLoun020233@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 13:21:46 2008 New Revision: 59971 URL: http://llvm.org/viewvc/llvm-project?rev=59971&view=rev Log: - Make lowering of "add with overflow" customizable by back-ends. - Mark "add with overflow" as having a custom lowering for X86. Give it a null lowering representation for now. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=59971&r1=59970&r2=59971&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 24 13:21:46 2008 @@ -4172,22 +4172,34 @@ case ISD::SADDO: case ISD::UADDO: { - SDValue LHS = LegalizeOp(Node->getOperand(0)); - SDValue RHS = LegalizeOp(Node->getOperand(1)); + MVT VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action not supported for this op yet!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Op, DAG); + if (Result.getNode()) break; + // FALLTHROUGH + case TargetLowering::Legal: { + SDValue LHS = LegalizeOp(Node->getOperand(0)); + SDValue RHS = LegalizeOp(Node->getOperand(1)); + + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + MVT OType = Node->getValueType(1); + SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, + (Node->getOpcode() == ISD::SADDO) ? + ISD::SETLT : ISD::SETULT); + + MVT ValueVTs[] = { LHS.getValueType(), OType }; + SDValue Ops[] = { Sum, Cmp }; + + Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); + SDNode *RNode = Result.getNode(); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); + break; + } + } - SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); - MVT OType = SDValue(Node, 1).getValueType(); - SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, - (Node->getOpcode() == ISD::SADDO) ? - ISD::SETLT : ISD::SETULT); - - MVT ValueVTs[] = { LHS.getValueType(), OType }; - SDValue Ops[] = { Sum, Cmp }; - - Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); - SDNode *RNode = Result.getNode(); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); break; } } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=59971&r1=59970&r2=59971&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Nov 24 13:21:46 2008 @@ -4096,9 +4096,8 @@ case Intrinsic::sadd_with_overflow: { SDValue Op1 = getValue(I.getOperand(1)); SDValue Op2 = getValue(I.getOperand(2)); - MVT Ty = Op1.getValueType(); - MVT ValueVTs[] = { Ty, MVT::i1 }; + MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 }; SDValue Ops[] = { Op1, Op2 }; SDValue Result = Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=59971&r1=59970&r2=59971&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Nov 24 13:21:46 2008 @@ -780,6 +780,12 @@ // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + // Add with overflow operations are custom lowered. + setOperationAction(ISD::SADDO, MVT::i32, Custom); + setOperationAction(ISD::SADDO, MVT::i64, Custom); + setOperationAction(ISD::UADDO, MVT::i32, Custom); + setOperationAction(ISD::UADDO, MVT::i64, Custom); + // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::VECTOR_SHUFFLE); setTargetDAGCombine(ISD::BUILD_VECTOR); @@ -6142,6 +6148,11 @@ return Op; } +SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, + ISD::NodeType NTy) { + return SDValue(); +} + SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) { MVT T = Op.getValueType(); unsigned Reg = 0; @@ -6321,6 +6332,8 @@ case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); case ISD::CTLZ: return LowerCTLZ(Op, DAG); case ISD::CTTZ: return LowerCTTZ(Op, DAG); + case ISD::SADDO: return LowerXADDO(Op, DAG, ISD::SADDO); + case ISD::UADDO: return LowerXADDO(Op, DAG, ISD::UADDO); // FIXME: REMOVE THIS WHEN LegalizeDAGTypes lands. case ISD::READCYCLECOUNTER: Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=59971&r1=59970&r2=59971&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Nov 24 13:21:46 2008 @@ -592,6 +592,8 @@ SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG); SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG); SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG); + SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy); + SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG); SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); SDValue LowerATOMIC_BINARY_64(SDValue Op, SelectionDAG &DAG, From sabre at nondot.org Mon Nov 24 13:25:36 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 19:25:36 -0000 Subject: [llvm-commits] [llvm] r59972 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp test/Transforms/CodeGenPrepare/ test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll test/Transforms/CodeGenPrepare/dg.exp Message-ID: <200811241925.mAOJPaTx020379@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 13:25:36 2008 New Revision: 59972 URL: http://llvm.org/viewvc/llvm-project?rev=59972&view=rev Log: Fix 3113: If we have a dead cyclic PHI, replace the whole thing with an undef. Added: llvm/trunk/test/Transforms/CodeGenPrepare/ llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll llvm/trunk/test/Transforms/CodeGenPrepare/dg.exp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59972&r1=59971&r2=59972&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 13:25:36 2008 @@ -206,7 +206,10 @@ if (DestBB->getSinglePredecessor()) { // If DestBB has single-entry PHI nodes, fold them. while (PHINode *PN = dyn_cast(DestBB->begin())) { - PN->replaceAllUsesWith(PN->getIncomingValue(0)); + Value *NewVal = PN->getIncomingValue(0); + // Replace self referencing PHI with undef, it must be dead. + if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); + PN->replaceAllUsesWith(NewVal); PN->eraseFromParent(); } @@ -569,6 +572,9 @@ if (Instruction *I = dyn_cast_or_null(AddrInst)) AddrModeInsts.push_back(I); + if (AddrInst && !AddrInst->hasOneUse()) + ; + else switch (Opcode) { case Instruction::PtrToInt: // PtrToInt is always a noop, as we know that the int type is pointer sized. Added: llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll?rev=59972&view=auto ============================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll (added) +++ llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Mon Nov 24 13:25:36 2008 @@ -0,0 +1,511 @@ +; RUN: llvm-as < %s | opt -codegenprepare | llvm-dis +; PR3113 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define fastcc i32 @ascii2flt(i8* %str) nounwind { +entry: + br label %bb2.i + +bb2.i: ; preds = %bb4.i.bb2.i_crit_edge, %entry + br i1 false, label %bb4.i, label %base2flt.exit + +bb4.i: ; preds = %bb2.i + br i1 false, label %bb11.i, label %bb4.i.bb2.i_crit_edge + +bb4.i.bb2.i_crit_edge: ; preds = %bb4.i + br label %bb2.i + +bb11.i: ; preds = %bb4.i + br label %bb11.i.base2flt.exit204_crit_edge + +bb11.i.base2flt.exit204_crit_edge: ; preds = %bb11.i + br label %base2flt.exit204 + +bb11.i.bb7.i197_crit_edge: ; No predecessors! + br label %bb7.i197 + +base2flt.exit: ; preds = %bb2.i + br label %base2flt.exit.base2flt.exit204_crit_edge + +base2flt.exit.base2flt.exit204_crit_edge: ; preds = %base2flt.exit + br label %base2flt.exit204 + +base2flt.exit.bb7.i197_crit_edge: ; No predecessors! + br label %bb7.i197 + +bb10.i196: ; preds = %bb7.i197 + br label %bb10.i196.base2flt.exit204_crit_edge + +bb10.i196.base2flt.exit204_crit_edge: ; preds = %bb7.i197, %bb10.i196 + br label %base2flt.exit204 + +bb10.i196.bb7.i197_crit_edge: ; No predecessors! + br label %bb7.i197 + +bb7.i197: ; preds = %bb10.i196.bb7.i197_crit_edge, %base2flt.exit.bb7.i197_crit_edge, %bb11.i.bb7.i197_crit_edge + %.reg2mem.0 = phi i32 [ 0, %base2flt.exit.bb7.i197_crit_edge ], [ %.reg2mem.0, %bb10.i196.bb7.i197_crit_edge ], [ 0, %bb11.i.bb7.i197_crit_edge ] ; [#uses=1] + br i1 undef, label %bb10.i196.base2flt.exit204_crit_edge, label %bb10.i196 + +base2flt.exit204: ; preds = %bb10.i196.base2flt.exit204_crit_edge, %base2flt.exit.base2flt.exit204_crit_edge, %bb11.i.base2flt.exit204_crit_edge + br i1 false, label %base2flt.exit204.bb8_crit_edge, label %bb + +base2flt.exit204.bb8_crit_edge: ; preds = %base2flt.exit204 + br label %bb8 + +bb: ; preds = %base2flt.exit204 + br i1 false, label %bb.bb18_crit_edge, label %bb1.i + +bb.bb18_crit_edge: ; preds = %bb9, %bb + br label %bb18 + +bb1.i: ; preds = %bb + br i1 false, label %bb1.i.bb7_crit_edge, label %bb1.i158 + +bb1.i.bb7_crit_edge.loopexit: ; preds = %bb2.i164 + br label %bb1.i.bb7_crit_edge + +bb1.i.bb7_crit_edge: ; preds = %bb1.i.bb7_crit_edge.loopexit, %bb1.i + br label %bb7.preheader + +bb1.i158: ; preds = %bb1.i + br i1 false, label %bb1.i158.bb10.i179_crit_edge, label %bb1.i158.bb2.i164_crit_edge + +bb1.i158.bb2.i164_crit_edge: ; preds = %bb1.i158 + br label %bb2.i164 + +bb1.i158.bb10.i179_crit_edge: ; preds = %bb1.i158 + br label %bb10.i179 + +bb2.i164: ; preds = %bb4.i166.bb2.i164_crit_edge, %bb1.i158.bb2.i164_crit_edge + br i1 false, label %bb4.i166, label %bb1.i.bb7_crit_edge.loopexit + +bb4.i166: ; preds = %bb2.i164 + br i1 false, label %bb4.i166.bb11.i172_crit_edge, label %bb4.i166.bb2.i164_crit_edge + +bb4.i166.bb2.i164_crit_edge: ; preds = %bb4.i166 + br label %bb2.i164 + +bb4.i166.bb11.i172_crit_edge: ; preds = %bb4.i166 + br label %bb11.i172 + +bb11.i172: ; preds = %bb10.i179.bb11.i172_crit_edge, %bb4.i166.bb11.i172_crit_edge + br label %bb7.preheader + +bb10.i179: ; preds = %bb9.i182, %bb1.i158.bb10.i179_crit_edge + br i1 false, label %bb7.i180, label %bb10.i179.bb11.i172_crit_edge + +bb10.i179.bb11.i172_crit_edge: ; preds = %bb10.i179 + br label %bb11.i172 + +bb7.i180: ; preds = %bb10.i179 + br i1 false, label %bb7.i180.bb7_crit_edge, label %bb9.i182 + +bb7.i180.bb7_crit_edge: ; preds = %bb7.i180 + br label %bb7.preheader + +bb7.preheader: ; preds = %bb7.i180.bb7_crit_edge, %bb11.i172, %bb1.i.bb7_crit_edge + br label %bb7 + +bb9.i182: ; preds = %bb7.i180 + br label %bb10.i179 + +bb7: ; preds = %addflt.exit114, %bb7.preheader + switch i8 0, label %bb4 [ + i8 0, label %bb7.bb8_crit_edge + i8 46, label %bb7.bb8_crit_edge + ] + +bb7.bb8_crit_edge: ; preds = %bb7, %bb7 + br label %bb8 + +bb4: ; preds = %bb7 + br i1 false, label %bb18.loopexit1, label %bb1.i5 + +bb1.i5: ; preds = %bb4 + br i1 false, label %bb1.i5.mulflt.exit157_crit_edge, label %bb3.i147 + +bb1.i5.mulflt.exit157_crit_edge: ; preds = %bb5.i148, %bb1.i5 + br label %mulflt.exit157 + +bb3.i147: ; preds = %bb1.i5 + br i1 false, label %bb3.i147.mulflt.exit157_crit_edge, label %bb5.i148 + +bb3.i147.mulflt.exit157_crit_edge: ; preds = %bb8.i150, %bb3.i147 + br label %mulflt.exit157 + +bb5.i148: ; preds = %bb3.i147 + br i1 false, label %bb1.i5.mulflt.exit157_crit_edge, label %bb7.i149 + +bb7.i149: ; preds = %bb5.i148 + br i1 false, label %bb8.i150, label %bb7.i149.bb12.i154_crit_edge + +bb7.i149.bb12.i154_crit_edge: ; preds = %bb7.i149 + br label %bb12.i154 + +bb8.i150: ; preds = %bb7.i149 + br i1 false, label %bb3.i147.mulflt.exit157_crit_edge, label %bb10.i151 + +bb10.i151: ; preds = %bb8.i150 + br label %bb12.i154 + +bb12.i154: ; preds = %bb10.i151, %bb7.i149.bb12.i154_crit_edge + br label %mulflt.exit157 + +mulflt.exit157: ; preds = %bb12.i154, %bb3.i147.mulflt.exit157_crit_edge, %bb1.i5.mulflt.exit157_crit_edge + br i1 false, label %mulflt.exit157.base2flt.exit144_crit_edge, label %bb1.i115 + +mulflt.exit157.base2flt.exit144_crit_edge.loopexit: ; preds = %bb2.i121 + br label %mulflt.exit157.base2flt.exit144_crit_edge + +mulflt.exit157.base2flt.exit144_crit_edge: ; preds = %mulflt.exit157.base2flt.exit144_crit_edge.loopexit, %mulflt.exit157 + br label %base2flt.exit144 + +bb1.i115: ; preds = %mulflt.exit157 + br i1 false, label %bb1.i115.bb10.i136_crit_edge, label %bb1.i115.bb2.i121_crit_edge + +bb1.i115.bb2.i121_crit_edge: ; preds = %bb1.i115 + br label %bb2.i121 + +bb1.i115.bb10.i136_crit_edge: ; preds = %bb1.i115 + br label %bb10.i136 + +bb2.i121: ; preds = %bb4.i123.bb2.i121_crit_edge, %bb1.i115.bb2.i121_crit_edge + br i1 false, label %bb4.i123, label %mulflt.exit157.base2flt.exit144_crit_edge.loopexit + +bb4.i123: ; preds = %bb2.i121 + br i1 false, label %bb4.i123.bb11.i129_crit_edge, label %bb4.i123.bb2.i121_crit_edge + +bb4.i123.bb2.i121_crit_edge: ; preds = %bb4.i123 + br label %bb2.i121 + +bb4.i123.bb11.i129_crit_edge: ; preds = %bb4.i123 + br label %bb11.i129 + +bb11.i129: ; preds = %bb10.i136.bb11.i129_crit_edge, %bb4.i123.bb11.i129_crit_edge + br label %base2flt.exit144 + +bb10.i136: ; preds = %bb9.i139, %bb1.i115.bb10.i136_crit_edge + br i1 false, label %bb7.i137, label %bb10.i136.bb11.i129_crit_edge + +bb10.i136.bb11.i129_crit_edge: ; preds = %bb10.i136 + br label %bb11.i129 + +bb7.i137: ; preds = %bb10.i136 + br i1 false, label %bb7.i137.base2flt.exit144_crit_edge, label %bb9.i139 + +bb7.i137.base2flt.exit144_crit_edge: ; preds = %bb7.i137 + br label %base2flt.exit144 + +bb9.i139: ; preds = %bb7.i137 + br label %bb10.i136 + +base2flt.exit144: ; preds = %bb7.i137.base2flt.exit144_crit_edge, %bb11.i129, %mulflt.exit157.base2flt.exit144_crit_edge + br i1 false, label %base2flt.exit144.addflt.exit114_crit_edge, label %bb3.i105 + +base2flt.exit144.addflt.exit114_crit_edge: ; preds = %bb3.i105, %base2flt.exit144 + br label %addflt.exit114 + +bb3.i105: ; preds = %base2flt.exit144 + br i1 false, label %base2flt.exit144.addflt.exit114_crit_edge, label %bb5.i106 + +bb5.i106: ; preds = %bb3.i105 + br i1 false, label %bb5.i106.bb9.i111_crit_edge, label %bb6.i107 + +bb5.i106.bb9.i111_crit_edge: ; preds = %bb5.i106 + br label %bb9.i111 + +bb6.i107: ; preds = %bb5.i106 + br i1 false, label %bb6.i107.addflt.exit114_crit_edge, label %bb8.i108 + +bb6.i107.addflt.exit114_crit_edge: ; preds = %bb6.i107 + br label %addflt.exit114 + +bb8.i108: ; preds = %bb6.i107 + br label %bb9.i111 + +bb9.i111: ; preds = %bb8.i108, %bb5.i106.bb9.i111_crit_edge + br label %addflt.exit114 + +addflt.exit114: ; preds = %bb9.i111, %bb6.i107.addflt.exit114_crit_edge, %base2flt.exit144.addflt.exit114_crit_edge + br label %bb7 + +bb18.loopexit1: ; preds = %bb4 + ret i32 -1 + +bb18: ; preds = %bb8.bb18_crit_edge, %bb.bb18_crit_edge + ret i32 0 + +bb8: ; preds = %bb7.bb8_crit_edge, %base2flt.exit204.bb8_crit_edge + br i1 false, label %bb9, label %bb8.bb18_crit_edge + +bb8.bb18_crit_edge: ; preds = %bb8 + br label %bb18 + +bb9: ; preds = %bb8 + br i1 false, label %bb.bb18_crit_edge, label %bb1.i13 + +bb1.i13: ; preds = %bb9 + br i1 false, label %bb1.i13.base2flt.exit102_crit_edge, label %bb1.i73 + +bb1.i13.base2flt.exit102_crit_edge.loopexit: ; preds = %bb2.i79 + br label %bb1.i13.base2flt.exit102_crit_edge + +bb1.i13.base2flt.exit102_crit_edge: ; preds = %bb1.i13.base2flt.exit102_crit_edge.loopexit, %bb1.i13 + br label %base2flt.exit102 + +bb1.i73: ; preds = %bb1.i13 + br i1 false, label %bb1.i73.bb10.i94_crit_edge, label %bb1.i73.bb2.i79_crit_edge + +bb1.i73.bb2.i79_crit_edge: ; preds = %bb1.i73 + br label %bb2.i79 + +bb1.i73.bb10.i94_crit_edge: ; preds = %bb1.i73 + br label %bb10.i94 + +bb2.i79: ; preds = %bb4.i81.bb2.i79_crit_edge, %bb1.i73.bb2.i79_crit_edge + br i1 false, label %bb4.i81, label %bb1.i13.base2flt.exit102_crit_edge.loopexit + +bb4.i81: ; preds = %bb2.i79 + br i1 false, label %bb4.i81.bb11.i87_crit_edge, label %bb4.i81.bb2.i79_crit_edge + +bb4.i81.bb2.i79_crit_edge: ; preds = %bb4.i81 + br label %bb2.i79 + +bb4.i81.bb11.i87_crit_edge: ; preds = %bb4.i81 + br label %bb11.i87 + +bb11.i87: ; preds = %bb10.i94.bb11.i87_crit_edge, %bb4.i81.bb11.i87_crit_edge + br label %base2flt.exit102 + +bb10.i94: ; preds = %bb9.i97, %bb1.i73.bb10.i94_crit_edge + br i1 false, label %bb7.i95, label %bb10.i94.bb11.i87_crit_edge + +bb10.i94.bb11.i87_crit_edge: ; preds = %bb10.i94 + br label %bb11.i87 + +bb7.i95: ; preds = %bb10.i94 + br i1 false, label %bb7.i95.base2flt.exit102_crit_edge, label %bb9.i97 + +bb7.i95.base2flt.exit102_crit_edge: ; preds = %bb7.i95 + br label %base2flt.exit102 + +bb9.i97: ; preds = %bb7.i95 + br label %bb10.i94 + +base2flt.exit102: ; preds = %bb7.i95.base2flt.exit102_crit_edge, %bb11.i87, %bb1.i13.base2flt.exit102_crit_edge + br i1 false, label %base2flt.exit102.mulflt.exit72_crit_edge, label %bb3.i62 + +base2flt.exit102.mulflt.exit72_crit_edge: ; preds = %bb5.i63, %base2flt.exit102 + br label %mulflt.exit72 + +bb3.i62: ; preds = %base2flt.exit102 + br i1 false, label %bb3.i62.mulflt.exit72_crit_edge, label %bb5.i63 + +bb3.i62.mulflt.exit72_crit_edge: ; preds = %bb8.i65, %bb3.i62 + br label %mulflt.exit72 + +bb5.i63: ; preds = %bb3.i62 + br i1 false, label %base2flt.exit102.mulflt.exit72_crit_edge, label %bb7.i64 + +bb7.i64: ; preds = %bb5.i63 + br i1 false, label %bb8.i65, label %bb7.i64.bb12.i69_crit_edge + +bb7.i64.bb12.i69_crit_edge: ; preds = %bb7.i64 + br label %bb12.i69 + +bb8.i65: ; preds = %bb7.i64 + br i1 false, label %bb3.i62.mulflt.exit72_crit_edge, label %bb10.i66 + +bb10.i66: ; preds = %bb8.i65 + br label %bb12.i69 + +bb12.i69: ; preds = %bb10.i66, %bb7.i64.bb12.i69_crit_edge + br label %mulflt.exit72 + +mulflt.exit72: ; preds = %bb12.i69, %bb3.i62.mulflt.exit72_crit_edge, %base2flt.exit102.mulflt.exit72_crit_edge + br i1 false, label %mulflt.exit72.bb10.i58_crit_edge, label %bb3.i50 + +mulflt.exit72.bb10.i58_crit_edge: ; preds = %bb3.i50, %mulflt.exit72 + br label %bb10.i58 + +bb3.i50: ; preds = %mulflt.exit72 + br i1 false, label %mulflt.exit72.bb10.i58_crit_edge, label %bb5.i51 + +bb5.i51: ; preds = %bb3.i50 + br i1 false, label %bb5.i51.bb9.i56_crit_edge, label %bb6.i52 + +bb5.i51.bb9.i56_crit_edge: ; preds = %bb5.i51 + br label %bb9.i56 + +bb6.i52: ; preds = %bb5.i51 + br i1 false, label %bb6.i52.bb10.i58_crit_edge, label %bb8.i53 + +bb6.i52.bb10.i58_crit_edge: ; preds = %bb6.i52 + br label %bb10.i58 + +bb8.i53: ; preds = %bb6.i52 + br label %bb9.i56 + +bb9.i56: ; preds = %bb8.i53, %bb5.i51.bb9.i56_crit_edge + br label %bb15.preheader + +bb10.i58: ; preds = %bb6.i52.bb10.i58_crit_edge, %mulflt.exit72.bb10.i58_crit_edge + br label %bb15.preheader + +bb15.preheader: ; preds = %bb10.i58, %bb9.i56 + br label %bb15 + +bb15: ; preds = %addflt.exit, %bb15.preheader + br i1 false, label %bb15.bb18.loopexit_crit_edge, label %bb12 + +bb15.bb18.loopexit_crit_edge: ; preds = %bb15 + br label %bb18.loopexit + +bb12: ; preds = %bb15 + br i1 false, label %bb12.bb18.loopexit_crit_edge, label %bb1.i21 + +bb12.bb18.loopexit_crit_edge: ; preds = %bb12 + br label %bb18.loopexit + +bb1.i21: ; preds = %bb12 + br i1 false, label %bb1.i21.mulflt.exit47_crit_edge, label %bb3.i37 + +bb1.i21.mulflt.exit47_crit_edge: ; preds = %bb5.i38, %bb1.i21 + br label %mulflt.exit47 + +bb3.i37: ; preds = %bb1.i21 + br i1 false, label %bb3.i37.mulflt.exit47_crit_edge, label %bb5.i38 + +bb3.i37.mulflt.exit47_crit_edge: ; preds = %bb8.i40, %bb3.i37 + br label %mulflt.exit47 + +bb5.i38: ; preds = %bb3.i37 + br i1 false, label %bb1.i21.mulflt.exit47_crit_edge, label %bb7.i39 + +bb7.i39: ; preds = %bb5.i38 + br i1 false, label %bb8.i40, label %bb7.i39.bb12.i44_crit_edge + +bb7.i39.bb12.i44_crit_edge: ; preds = %bb7.i39 + br label %bb12.i44 + +bb8.i40: ; preds = %bb7.i39 + br i1 false, label %bb3.i37.mulflt.exit47_crit_edge, label %bb10.i41 + +bb10.i41: ; preds = %bb8.i40 + br label %bb12.i44 + +bb12.i44: ; preds = %bb10.i41, %bb7.i39.bb12.i44_crit_edge + br label %mulflt.exit47 + +mulflt.exit47: ; preds = %bb12.i44, %bb3.i37.mulflt.exit47_crit_edge, %bb1.i21.mulflt.exit47_crit_edge + br i1 false, label %mulflt.exit47.base2flt.exit34_crit_edge, label %bb1.i15 + +mulflt.exit47.base2flt.exit34_crit_edge.loopexit: ; preds = %bb2.i20 + br label %mulflt.exit47.base2flt.exit34_crit_edge + +mulflt.exit47.base2flt.exit34_crit_edge: ; preds = %mulflt.exit47.base2flt.exit34_crit_edge.loopexit, %mulflt.exit47 + br label %base2flt.exit34 + +bb1.i15: ; preds = %mulflt.exit47 + br i1 false, label %bb1.i15.bb10.i31_crit_edge, label %bb1.i15.bb2.i20_crit_edge + +bb1.i15.bb2.i20_crit_edge: ; preds = %bb1.i15 + br label %bb2.i20 + +bb1.i15.bb10.i31_crit_edge: ; preds = %bb1.i15 + br label %bb10.i31 + +bb2.i20: ; preds = %bb4.i22.bb2.i20_crit_edge, %bb1.i15.bb2.i20_crit_edge + br i1 false, label %bb4.i22, label %mulflt.exit47.base2flt.exit34_crit_edge.loopexit + +bb4.i22: ; preds = %bb2.i20 + br i1 false, label %bb4.i22.bb11.i28_crit_edge, label %bb4.i22.bb2.i20_crit_edge + +bb4.i22.bb2.i20_crit_edge: ; preds = %bb4.i22 + br label %bb2.i20 + +bb4.i22.bb11.i28_crit_edge: ; preds = %bb4.i22 + br label %bb11.i28 + +bb11.i28: ; preds = %bb10.i31.bb11.i28_crit_edge, %bb4.i22.bb11.i28_crit_edge + br label %base2flt.exit34 + +bb10.i31: ; preds = %bb9.i33, %bb1.i15.bb10.i31_crit_edge + br i1 false, label %bb7.i32, label %bb10.i31.bb11.i28_crit_edge + +bb10.i31.bb11.i28_crit_edge: ; preds = %bb10.i31 + br label %bb11.i28 + +bb7.i32: ; preds = %bb10.i31 + br i1 false, label %bb7.i32.base2flt.exit34_crit_edge, label %bb9.i33 + +bb7.i32.base2flt.exit34_crit_edge: ; preds = %bb7.i32 + br label %base2flt.exit34 + +bb9.i33: ; preds = %bb7.i32 + br label %bb10.i31 + +base2flt.exit34: ; preds = %bb7.i32.base2flt.exit34_crit_edge, %bb11.i28, %mulflt.exit47.base2flt.exit34_crit_edge + br i1 false, label %base2flt.exit34.mulflt.exit_crit_edge, label %bb3.i9 + +base2flt.exit34.mulflt.exit_crit_edge: ; preds = %bb5.i10, %base2flt.exit34 + br label %mulflt.exit + +bb3.i9: ; preds = %base2flt.exit34 + br i1 false, label %bb3.i9.mulflt.exit_crit_edge, label %bb5.i10 + +bb3.i9.mulflt.exit_crit_edge: ; preds = %bb8.i11, %bb3.i9 + br label %mulflt.exit + +bb5.i10: ; preds = %bb3.i9 + br i1 false, label %base2flt.exit34.mulflt.exit_crit_edge, label %bb7.i + +bb7.i: ; preds = %bb5.i10 + br i1 false, label %bb8.i11, label %bb7.i.bb12.i_crit_edge + +bb7.i.bb12.i_crit_edge: ; preds = %bb7.i + br label %bb12.i + +bb8.i11: ; preds = %bb7.i + br i1 false, label %bb3.i9.mulflt.exit_crit_edge, label %bb10.i12 + +bb10.i12: ; preds = %bb8.i11 + br label %bb12.i + +bb12.i: ; preds = %bb10.i12, %bb7.i.bb12.i_crit_edge + br label %mulflt.exit + +mulflt.exit: ; preds = %bb12.i, %bb3.i9.mulflt.exit_crit_edge, %base2flt.exit34.mulflt.exit_crit_edge + br i1 false, label %mulflt.exit.addflt.exit_crit_edge, label %bb3.i + +mulflt.exit.addflt.exit_crit_edge: ; preds = %bb3.i, %mulflt.exit + br label %addflt.exit + +bb3.i: ; preds = %mulflt.exit + br i1 false, label %mulflt.exit.addflt.exit_crit_edge, label %bb5.i + +bb5.i: ; preds = %bb3.i + br i1 false, label %bb5.i.bb9.i_crit_edge, label %bb6.i + +bb5.i.bb9.i_crit_edge: ; preds = %bb5.i + br label %bb9.i + +bb6.i: ; preds = %bb5.i + br i1 false, label %bb6.i.addflt.exit_crit_edge, label %bb8.i + +bb6.i.addflt.exit_crit_edge: ; preds = %bb6.i + br label %addflt.exit + +bb8.i: ; preds = %bb6.i + br label %bb9.i + +bb9.i: ; preds = %bb8.i, %bb5.i.bb9.i_crit_edge + br label %addflt.exit + +addflt.exit: ; preds = %bb9.i, %bb6.i.addflt.exit_crit_edge, %mulflt.exit.addflt.exit_crit_edge + br label %bb15 + +bb18.loopexit: ; preds = %bb12.bb18.loopexit_crit_edge, %bb15.bb18.loopexit_crit_edge + ret i32 0 +} Added: llvm/trunk/test/Transforms/CodeGenPrepare/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/dg.exp?rev=59972&view=auto ============================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/dg.exp (added) +++ llvm/trunk/test/Transforms/CodeGenPrepare/dg.exp Mon Nov 24 13:25:36 2008 @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]] From sabre at nondot.org Mon Nov 24 13:40:34 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 19:40:34 -0000 Subject: [llvm-commits] [llvm] r59976 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811241940.mAOJeYUU020985@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 13:40:34 2008 New Revision: 59976 URL: http://llvm.org/viewvc/llvm-project?rev=59976&view=rev Log: revert an accidental commit, this fixes the regression on test/CodeGen/X86/isel-sink.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59976&r1=59975&r2=59976&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 13:40:34 2008 @@ -208,7 +208,7 @@ while (PHINode *PN = dyn_cast(DestBB->begin())) { Value *NewVal = PN->getIncomingValue(0); // Replace self referencing PHI with undef, it must be dead. - if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); + //if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); PN->replaceAllUsesWith(NewVal); PN->eraseFromParent(); } @@ -572,9 +572,6 @@ if (Instruction *I = dyn_cast_or_null(AddrInst)) AddrModeInsts.push_back(I); - if (AddrInst && !AddrInst->hasOneUse()) - ; - else switch (Opcode) { case Instruction::PtrToInt: // PtrToInt is always a noop, as we know that the int type is pointer sized. From gohman at apple.com Mon Nov 24 13:52:00 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 19:52:00 -0000 Subject: [llvm-commits] [llvm] r59977 - /llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200811241952.mAOJq0x4021411@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 13:51:59 2008 New Revision: 59977 URL: http://llvm.org/viewvc/llvm-project?rev=59977&view=rev Log: Fix an unused-parameter warning. Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59977&r1=59976&r2=59977&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Nov 24 13:51:59 2008 @@ -313,7 +313,7 @@ /// addCustomGraphFeatures - Add custom features for a visualization of /// the ScheduleDAG. - virtual void addCustomGraphFeatures(GraphWriter &GW) const {} + virtual void addCustomGraphFeatures(GraphWriter &) const {} #ifndef NDEBUG /// VerifySchedule - Verify that all SUnits were scheduled and that From gohman at apple.com Mon Nov 24 13:53:22 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 Nov 2008 19:53:22 -0000 Subject: [llvm-commits] [llvm] r59978 - in /llvm/trunk/include/llvm/CodeGen: LinkAllCodegenComponents.h ScheduleDAGSDNodes.h SchedulerRegistry.h Message-ID: <200811241953.mAOJrMdW021481@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 13:53:21 2008 New Revision: 59978 URL: http://llvm.org/viewvc/llvm-project?rev=59978&view=rev Log: Move the scheduler constructor functions to SchedulerRegistry.h, to simplify header dependencies for front-ends that just want to choose a scheduler and don't need all the scheduling machinery declarations. Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=59978&r1=59977&r2=59978&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h (original) +++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Mon Nov 24 13:53:21 2008 @@ -16,7 +16,7 @@ #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/ScheduleDAGSDNodes.h" +#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/GCs.h" namespace { Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h?rev=59978&r1=59977&r2=59978&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h Mon Nov 24 13:53:21 2008 @@ -188,46 +188,6 @@ const TargetInstrDesc &II, DenseMap &VRBaseMap); }; - - /// createBURRListDAGScheduler - This creates a bottom up register usage - /// reduction list scheduler. - ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDRRListDAGScheduler - This creates a top down register usage - /// reduction list scheduler. - ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createTDListDAGScheduler - This creates a top-down list scheduler with - /// a hazard recognizer. - ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createFastDAGScheduler - This creates a "fast" scheduler. - /// - ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); - - /// createDefaultScheduler - This creates an instruction scheduler appropriate - /// for the target. - ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, - SelectionDAG *DAG, - const TargetMachine *TM, - MachineBasicBlock *BB, - bool Fast); } #endif Modified: llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h?rev=59978&r1=59977&r2=59978&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h (original) +++ llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h Mon Nov 24 13:53:21 2008 @@ -31,9 +31,7 @@ class MachineBasicBlock; class RegisterScheduler : public MachinePassRegistryNode { - public: - typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*, const TargetMachine *, MachineBasicBlock*, bool); @@ -63,9 +61,48 @@ static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } - }; +/// createBURRListDAGScheduler - This creates a bottom up register usage +/// reduction list scheduler. +ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + const TargetMachine *TM, + MachineBasicBlock *BB, + bool Fast); + +/// createTDRRListDAGScheduler - This creates a top down register usage +/// reduction list scheduler. +ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + const TargetMachine *TM, + MachineBasicBlock *BB, + bool Fast); + +/// createTDListDAGScheduler - This creates a top-down list scheduler with +/// a hazard recognizer. +ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + const TargetMachine *TM, + MachineBasicBlock *BB, + bool Fast); + +/// createFastDAGScheduler - This creates a "fast" scheduler. +/// +ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + const TargetMachine *TM, + MachineBasicBlock *BB, + bool Fast); + +/// createDefaultScheduler - This creates an instruction scheduler appropriate +/// for the target. +ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + const TargetMachine *TM, + MachineBasicBlock *BB, + bool Fast); + } // end namespace llvm From brukman+llvm at gmail.com Mon Nov 24 14:37:23 2008 From: brukman+llvm at gmail.com (Misha Brukman) Date: Mon, 24 Nov 2008 20:37:23 -0000 Subject: [llvm-commits] [nightly-test-server] r59980 - /nightly-test-server/trunk/locgraph.php Message-ID: <200811242037.mAOKbNuH023109@zion.cs.uiuc.edu> Author: brukman Date: Mon Nov 24 14:37:23 2008 New Revision: 59980 URL: http://llvm.org/viewvc/llvm-project?rev=59980&view=rev Log: * s/CVS/SVN/ * Cleaned up some code and formatting * Realized that PHP debugging leaves a lot to be desired * Noticed that PHP, as a language, does the same Modified: nightly-test-server/trunk/locgraph.php Modified: nightly-test-server/trunk/locgraph.php URL: http://llvm.org/viewvc/llvm-project/nightly-test-server/trunk/locgraph.php?rev=59980&r1=59979&r2=59980&view=diff ============================================================================== --- nightly-test-server/trunk/locgraph.php (original) +++ nightly-test-server/trunk/locgraph.php Mon Nov 24 14:37:23 2008 @@ -4,70 +4,52 @@ include("jpgraph/jpgraph_utils.inc"); include("jpgraph/jpgraph_date.php"); -if(isset($HTTP_GET_VARS['start'])){ - $start = $HTTP_GET_VARS['start']; -} -if(isset($HTTP_GET_VARS['end'])){ - $end = $HTTP_GET_VARS['end']; -} - -$locgraphlink=mysql_connect("localhost","llvm","ll2002vm"); +$locgraphlink = mysql_connect("localhost", "llvm", "ll2002vm"); mysql_select_db("nightlytestresults"); - -$lines = array(); +$lines = array(); $files = array(); $dirs = array(); $xdata = array(); -/******************************** - * - * This is where we choose the bounds on the graph - * - ********************************/ -if(isset($start) && isset($end)){ - $query = mysql_query("select * from code where added <= \"$end\" and added >= \"$start\" order by added desc") or die (mysql_error()); -} -else if(!isset($start) && isset($end)){ - $query = mysql_query("select * from code where added <=\"$end\" order by added desc") or die (mysql_error()); -} -else if(isset($start) && !isset($end)){ - $query = mysql_query("select * from code where added >= \"$start\" order by added desc") or die (mysql_error()); -} -else{ - $query = mysql_query("select * from code order by added desc") or die (mysql_error()); -} - -if(isset($HTTP_GET_VARS['xsize'])){ - $xsize = $HTTP_GET_VARS['xsize']; -} -else{ - $xsize=400; -} - -if(isset($HTTP_GET_VARS['ysize'])){ - $ysize = $HTTP_GET_VARS['ysize']; -} -else{ - $ysize=250; -} - - -while($row = mysql_fetch_array($query)){ - array_push($lines, $row['loc']); - #array_push($dirs, $row['dirs']); - #array_push($files, $row['files']); - preg_match("/(\d\d\d\d)\-(\d\d)\-(\d\d)\s(\d\d)\:(\d\d)\:(\d\d)/", $row['added'], $values); - $seconds = mktime($values[4], $values[5], $values[6], $values[2], $values[3],$values[1]); - array_push($xdata, $seconds); -} - -function TimeCallback( $aVal) { - return Date ('m-d-y', $aVal); -} -$graph = new Graph($xsize,$ysize); +function GetSqlQuery() { + if (isset($HTTP_GET_VARS['start'])) { + $start = $HTTP_GET_VARS['start']; + } + if (isset($HTTP_GET_VARS['end'])) { + $end = $HTTP_GET_VARS['end']; + } + $query_tpl = "SELECT * FROM code %s ORDER BY added DESC"; + if (isset($start) && isset($end)) { + return sprintf($query_tpl, "WHERE added <= \"$end\" AND added >= \"$start\""); + } else if (!isset($start) && isset($end)) { + return sprintf($query_tpl, "WHERE added <=\"$end\""); + } else if (isset($start) && !isset($end)) { + return sprintf($query_tpl, "WHERE added >= \"$start\""); + } else { + return sprintf($query_tpl, ""); + } +} + +$sql_data = mysql_query(GetSqlQuery()) or die(mysql_error()); +while ($row = mysql_fetch_array($sql_data)) { + array_push($lines, $row['loc']); + #array_push($dirs, $row['dirs']); + #array_push($files, $row['files']); + preg_match("/(\d\d\d\d)\-(\d\d)\-(\d\d)\s(\d\d)\:(\d\d)\:(\d\d)/", $row['added'], $values); + $seconds = mktime($values[4], $values[5], $values[6], $values[2], $values[3], $values[1]); + array_push($xdata, $seconds); +} + +function TimeCallback($aVal) { + return Date('m-d-y', $aVal); +} + +$xsize = isset($HTTP_GET_VARS['xsize']) ? $HTTP_GET_VARS['xsize'] : 400; +$ysize = isset($HTTP_GET_VARS['ysize']) ? $HTTP_GET_VARS['ysize'] : 250; +$graph = new Graph($xsize, $ysize); $graph->SetScale("datelin"); -$graph->tabtitle->Set(" Lines of Code in CVS Repository "); +$graph->tabtitle->Set(" Lines of Code in SVN Repository "); #$graph->tabtitle->SetFont(FF_ARIAL,FS_BOLD,13); $graph->xaxis->SetLabelAngle(90); $graph->SetMargin(70,40,30,80); @@ -75,13 +57,13 @@ $graph->yaxis->title->SetMargin(30); $graph->SetFrame(false); $graph->SetMarginColor("White"); -$graph->legend->SetShadow('gray at 0.4',5); -$graph->legend->SetPos(0.2,0.13,'left','top'); +$graph->legend->SetShadow('gray at 0.4', 5); +$graph->legend->SetPos(0.2, 0.13, 'left', 'top'); $graph->legend->hide(true); -$graph->ygrid->SetFill(true,'#EFEFEF at 0.5','#BBCCFF at 0.5'); +$graph->ygrid->SetFill(true, '#EFEFEF at 0.5', '#BBCCFF at 0.5'); $graph->xgrid->Show(); $graph->xaxis->scale->SetTimeAlign(MONTHADJ_1); -$graph->xaxis-> SetLabelFormatCallback( 'TimeCallback'); +$graph->xaxis->SetLabelFormatCallback('TimeCallback'); $line = new LinePlot($lines, $xdata); $line->SetLegend("Lines of code"); From isanbard at gmail.com Mon Nov 24 14:43:33 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 20:43:33 -0000 Subject: [llvm-commits] [llvm] r59981 - /llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Message-ID: <200811242043.mAOKhX2M023322@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 14:43:33 2008 New Revision: 59981 URL: http://llvm.org/viewvc/llvm-project?rev=59981&view=rev Log: Temporarily XFAIL this test. r59976 and r59972 broke it. Modified: llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Modified: llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll?rev=59981&r1=59980&r2=59981&view=diff ============================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll (original) +++ llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Mon Nov 24 14:43:33 2008 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | opt -codegenprepare | llvm-dis +; XFAIL: * ; PR3113 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" From isanbard at gmail.com Mon Nov 24 14:44:28 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 12:44:28 -0800 Subject: [llvm-commits] [llvm] r59976 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <200811241940.mAOJeYUU020985@zion.cs.uiuc.edu> References: <200811241940.mAOJeYUU020985@zion.cs.uiuc.edu> Message-ID: <16e5fdf90811241244w4433a7ach6613935bf3c8afb0@mail.gmail.com> Chris, This testcase is still failing. I XFAILed it for now. Did you mean to comment out the first "if" statement here? -bw On Mon, Nov 24, 2008 at 11:40 AM, Chris Lattner wrote: > Author: lattner > Date: Mon Nov 24 13:40:34 2008 > New Revision: 59976 > > URL: http://llvm.org/viewvc/llvm-project?rev=59976&view=rev > Log: > revert an accidental commit, this fixes the regression on test/CodeGen/X86/isel-sink.ll > > Modified: > llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59976&r1=59975&r2=59976&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 13:40:34 2008 > @@ -208,7 +208,7 @@ > while (PHINode *PN = dyn_cast(DestBB->begin())) { > Value *NewVal = PN->getIncomingValue(0); > // Replace self referencing PHI with undef, it must be dead. > - if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); > + //if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); > PN->replaceAllUsesWith(NewVal); > PN->eraseFromParent(); > } > @@ -572,9 +572,6 @@ > if (Instruction *I = dyn_cast_or_null(AddrInst)) > AddrModeInsts.push_back(I); > > - if (AddrInst && !AddrInst->hasOneUse()) > - ; > - else > switch (Opcode) { > case Instruction::PtrToInt: > // PtrToInt is always a noop, as we know that the int type is pointer sized. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From dalej at apple.com Mon Nov 24 14:56:51 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 24 Nov 2008 20:56:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59984 - /llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Message-ID: <200811242056.mAOKupMA023776@zion.cs.uiuc.edu> Author: johannes Date: Mon Nov 24 14:56:51 2008 New Revision: 59984 URL: http://llvm.org/viewvc/llvm-project?rev=59984&view=rev Log: Move definition outside #if. The #if doesn't keep gengtype from seeing it. Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c?rev=59984&r1=59983&r2=59984&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.c Mon Nov 24 14:56:51 2008 @@ -20567,10 +20567,13 @@ fatal_insn ("bad address", op); } +/* LLVM LOCAL begin move branch_island_list outside #if */ +static GTY (()) tree branch_island_list = 0; + #if TARGET_MACHO /* APPLE LOCAL mlongcall long names 4271187 */ -static GTY (()) tree branch_island_list = 0; +/* LLVM LOCAL end move branch_island_list outside #if */ /* APPLE LOCAL begin 4380289 */ /* Remember to generate a branch island for far calls to the given From sabre at nondot.org Mon Nov 24 15:26:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 21:26:21 -0000 Subject: [llvm-commits] [llvm] r59985 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811242126.mAOLQLv8024861@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 15:26:21 2008 New Revision: 59985 URL: http://llvm.org/viewvc/llvm-project?rev=59985&view=rev Log: reenable the right part of the code. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59985&r1=59984&r2=59985&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 15:26:21 2008 @@ -208,7 +208,7 @@ while (PHINode *PN = dyn_cast(DestBB->begin())) { Value *NewVal = PN->getIncomingValue(0); // Replace self referencing PHI with undef, it must be dead. - //if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); + if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); PN->replaceAllUsesWith(NewVal); PN->eraseFromParent(); } From clattner at apple.com Mon Nov 24 15:26:44 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 Nov 2008 13:26:44 -0800 Subject: [llvm-commits] [llvm] r59976 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp In-Reply-To: <16e5fdf90811241244w4433a7ach6613935bf3c8afb0@mail.gmail.com> References: <200811241940.mAOJeYUU020985@zion.cs.uiuc.edu> <16e5fdf90811241244w4433a7ach6613935bf3c8afb0@mail.gmail.com> Message-ID: <50110730-CFB0-4B25-97D5-18AEBD2BB334@apple.com> On Nov 24, 2008, at 12:44 PM, Bill Wendling wrote: > Chris, > > This testcase is still failing. I XFAILed it for now. Did you mean to > comment out the first "if" statement here? Sorry fixed. From sabre at nondot.org Mon Nov 24 15:27:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 21:27:21 -0000 Subject: [llvm-commits] [llvm] r59986 - /llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Message-ID: <200811242127.mAOLRLVQ024900@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 15:27:20 2008 New Revision: 59986 URL: http://llvm.org/viewvc/llvm-project?rev=59986&view=rev Log: reenable test Modified: llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Modified: llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll?rev=59986&r1=59985&r2=59986&view=diff ============================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll (original) +++ llvm/trunk/test/Transforms/CodeGenPrepare/2008-11-24-RAUW-Self.ll Mon Nov 24 15:27:20 2008 @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | opt -codegenprepare | llvm-dis -; XFAIL: * ; PR3113 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" From sabre at nondot.org Mon Nov 24 16:40:05 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 22:40:05 -0000 Subject: [llvm-commits] [llvm] r59989 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811242240.mAOMe6mm028910@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 16:40:05 2008 New Revision: 59989 URL: http://llvm.org/viewvc/llvm-project?rev=59989&view=rev Log: minor cleanups to debug code, no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59989&r1=59988&r2=59989&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 16:40:05 2008 @@ -485,40 +485,44 @@ } namespace { + /// ExtAddrMode - This is an extended version of TargetLowering::AddrMode + /// which holds actual Value*'s for register values. + struct ExtAddrMode : public TargetLowering::AddrMode { + Value *BaseReg; + Value *ScaledReg; + ExtAddrMode() : BaseReg(0), ScaledReg(0) {} + void print(OStream &OS) const; + void dump() const { + print(cerr); + cerr << '\n'; + } + }; +} // end anonymous namespace + +static OStream &operator<<(OStream &OS, const ExtAddrMode &AM) { + AM.print(OS); + return OS; +} -/// ExtAddrMode - This is an extended version of TargetLowering::AddrMode which -/// holds actual Value*'s for register values. -struct ExtAddrMode : public TargetLowering::AddrMode { - Value *BaseReg; - Value *ScaledReg; - ExtAddrMode() : BaseReg(0), ScaledReg(0) {} - void dump() const; -}; -static std::ostream &operator<<(std::ostream &OS, const ExtAddrMode &AM) { +void ExtAddrMode::print(OStream &OS) const { bool NeedPlus = false; OS << "["; - if (AM.BaseGV) + if (BaseGV) OS << (NeedPlus ? " + " : "") - << "GV:%" << AM.BaseGV->getName(), NeedPlus = true; + << "GV:%" << BaseGV->getName(), NeedPlus = true; - if (AM.BaseOffs) - OS << (NeedPlus ? " + " : "") << AM.BaseOffs, NeedPlus = true; + if (BaseOffs) + OS << (NeedPlus ? " + " : "") << BaseOffs, NeedPlus = true; - if (AM.BaseReg) + if (BaseReg) OS << (NeedPlus ? " + " : "") - << "Base:%" << AM.BaseReg->getName(), NeedPlus = true; - if (AM.Scale) + << "Base:%" << BaseReg->getName(), NeedPlus = true; + if (Scale) OS << (NeedPlus ? " + " : "") - << AM.Scale << "*%" << AM.ScaledReg->getName(), NeedPlus = true; - - return OS << "]"; -} - -void ExtAddrMode::dump() const { - cerr << *this << "\n"; -} + << Scale << "*%" << ScaledReg->getName(), NeedPlus = true; + OS << ']'; } static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale, @@ -572,6 +576,11 @@ if (Instruction *I = dyn_cast_or_null(AddrInst)) AddrModeInsts.push_back(I); +#if 0 + if (AddrInst && !AddrInst->hasOneUse()) + ; + else +#endif switch (Opcode) { case Instruction::PtrToInt: // PtrToInt is always a noop, as we know that the int type is pointer sized. From sabre at nondot.org Mon Nov 24 16:44:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 Nov 2008 22:44:17 -0000 Subject: [llvm-commits] [llvm] r59990 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811242244.mAOMiH13029078@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 16:44:16 2008 New Revision: 59990 URL: http://llvm.org/viewvc/llvm-project?rev=59990&view=rev Log: rearrange and tidy some code, no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=59990&r1=59989&r2=59990&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 16:44:16 2008 @@ -334,6 +334,7 @@ /// registers that must be created and coalesced. /// /// Return true if any changes are made. +/// static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI){ // If this is a noop copy, MVT SrcVT = TLI.getValueType(CI->getOperand(0)->getType()); @@ -415,8 +416,7 @@ /// (PowerPC), where it might lose; some adjustment may be wanted there. /// /// Return true if any changes are made. -static bool OptimizeCmpExpression(CmpInst *CI){ - +static bool OptimizeCmpExpression(CmpInst *CI) { BasicBlock *DefBB = CI->getParent(); /// InsertedCmp - Only insert a cmp in each block once. @@ -464,7 +464,7 @@ return MadeChange; } -/// EraseDeadInstructions - Erase any dead instructions +/// EraseDeadInstructions - Erase any dead instructions, recursively. static void EraseDeadInstructions(Value *V) { Instruction *I = dyn_cast(V); if (!I || !I->use_empty()) return; @@ -525,15 +525,63 @@ OS << ']'; } +/// TryMatchingScaledValue - Try adding ScaleReg*Scale to the specified +/// addressing mode. Return true if this addr mode is legal for the target, +/// false if not. static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale, const Type *AccessTy, ExtAddrMode &AddrMode, SmallVector &AddrModeInsts, - const TargetLowering &TLI, unsigned Depth); + const TargetLowering &TLI, unsigned Depth) { + // If we already have a scale of this value, we can add to it, otherwise, we + // need an available scale field. + if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) + return false; + + ExtAddrMode InputAddrMode = AddrMode; + + // Add scale to turn X*4+X*3 -> X*7. This could also do things like + // [A+B + A*7] -> [B+A*8]. + AddrMode.Scale += Scale; + AddrMode.ScaledReg = ScaleReg; + + if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) { + // Okay, we decided that we can add ScaleReg+Scale to AddrMode. Check now + // to see if ScaleReg is actually X+C. If so, we can turn this into adding + // X*Scale + C*Scale to addr mode. + BinaryOperator *BinOp = dyn_cast(ScaleReg); + if (BinOp && BinOp->getOpcode() == Instruction::Add && + isa(BinOp->getOperand(1)) && InputAddrMode.ScaledReg ==0) { + + InputAddrMode.Scale = Scale; + InputAddrMode.ScaledReg = BinOp->getOperand(0); + InputAddrMode.BaseOffs += + cast(BinOp->getOperand(1))->getSExtValue()*Scale; + if (TLI.isLegalAddressingMode(InputAddrMode, AccessTy)) { + AddrModeInsts.push_back(BinOp); + AddrMode = InputAddrMode; + return true; + } + } + + // Otherwise, not (x+c)*scale, just return what we have. + return true; + } + + // Otherwise, back this attempt out. + AddrMode.Scale -= Scale; + if (AddrMode.Scale == 0) AddrMode.ScaledReg = 0; + + return false; +} + /// FindMaximalLegalAddressingMode - If we can, try to merge the computation of /// Addr into the specified addressing mode. If Addr can't be added to AddrMode /// this returns false. This assumes that Addr is either a pointer type or /// intptr_t for the target. +/// +/// This method is used to optimize both load/store and inline asms with memory +/// operands. static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, ExtAddrMode &AddrMode, SmallVector &AddrModeInsts, @@ -767,55 +815,6 @@ return false; } -/// TryMatchingScaledValue - Try adding ScaleReg*Scale to the specified -/// addressing mode. Return true if this addr mode is legal for the target, -/// false if not. -static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale, - const Type *AccessTy, ExtAddrMode &AddrMode, - SmallVector &AddrModeInsts, - const TargetLowering &TLI, unsigned Depth) { - // If we already have a scale of this value, we can add to it, otherwise, we - // need an available scale field. - if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) - return false; - - ExtAddrMode InputAddrMode = AddrMode; - - // Add scale to turn X*4+X*3 -> X*7. This could also do things like - // [A+B + A*7] -> [B+A*8]. - AddrMode.Scale += Scale; - AddrMode.ScaledReg = ScaleReg; - - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) { - // Okay, we decided that we can add ScaleReg+Scale to AddrMode. Check now - // to see if ScaleReg is actually X+C. If so, we can turn this into adding - // X*Scale + C*Scale to addr mode. - BinaryOperator *BinOp = dyn_cast(ScaleReg); - if (BinOp && BinOp->getOpcode() == Instruction::Add && - isa(BinOp->getOperand(1)) && InputAddrMode.ScaledReg ==0) { - - InputAddrMode.Scale = Scale; - InputAddrMode.ScaledReg = BinOp->getOperand(0); - InputAddrMode.BaseOffs += - cast(BinOp->getOperand(1))->getSExtValue()*Scale; - if (TLI.isLegalAddressingMode(InputAddrMode, AccessTy)) { - AddrModeInsts.push_back(BinOp); - AddrMode = InputAddrMode; - return true; - } - } - - // Otherwise, not (x+c)*scale, just return what we have. - return true; - } - - // Otherwise, back this attempt out. - AddrMode.Scale -= Scale; - if (AddrMode.Scale == 0) AddrMode.ScaledReg = 0; - - return false; -} - /// IsNonLocalValue - Return true if the specified values are defined in a /// different basic block than BB. From isanbard at gmail.com Mon Nov 24 17:21:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 23:21:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59991 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp Message-ID: <200811242321.mAONLDqI030273@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 17:21:13 2008 New Revision: 59991 URL: http://llvm.org/viewvc/llvm-project?rev=59991&view=rev Log: When a constant CFString is created, it's not given a name. LLVM gladly accepts this and assigns it the name "_unnamed_#_#". This plays havoc with the runtime because the runtime is expecting the name to be internal. It also prevents the linker from coalescing these strings. The fix to generate a name for a variable going into the _cfstring section if it doesn't already have one and it has internal linkage. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.h?rev=59991&r1=59990&r2=59991&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.h Mon Nov 24 17:21:13 2008 @@ -694,6 +694,21 @@ (FN)->setLinkage(Function::ExternalLinkage); \ } \ } while (0) + +/* A const CFString is created as an anonymous global variable. LLVM then gives + it the name '__unnamed_#_#'. This causes troubles with the runtime, which + expects the name to be internal. Give it an internal name here. */ +#define TARGET_ADJUST_CFSTRING_NAME(GV, SEC) \ + do { \ + if (strcmp((SEC), "__DATA, __cfstring") == 0) { \ + static unsigned i = 0; \ + const char *fmt = "\01L_unnamed_cfstring_%d"; \ + char *N = (char *)alloca(strlen(fmt) + 37); \ + sprintf(N, fmt, i++); \ + GV->setName(N); \ + } \ + } while (0) + #endif /* LLVM LOCAL end */ Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=59991&r1=59990&r2=59991&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 17:21:13 2008 @@ -1133,6 +1133,11 @@ if (const char *Section = LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { GV->setSection(Section); + +#ifdef TARGET_ADJUST_CFSTRING_NAME + if (!GV->hasName() && GV->hasInternalLinkage()) + TARGET_ADJUST_CFSTRING_NAME(GV, Section); +#endif } #endif } From isanbard at gmail.com Mon Nov 24 17:28:09 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 23:28:09 -0000 Subject: [llvm-commits] [llvm] r59992 - /llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m Message-ID: <200811242328.mAONS9cF030495@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 17:28:09 2008 New Revision: 59992 URL: http://llvm.org/viewvc/llvm-project?rev=59992&view=rev Log: Testcase for constant CFStrings. Added: llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m Added: llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m?rev=59992&view=auto ============================================================================== --- llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m (added) +++ llvm/trunk/test/FrontendObjC/2008-11-24-ConstCFStrings.m Mon Nov 24 17:28:09 2008 @@ -0,0 +1,11 @@ +// RUN: %llvmgcc -x objective-c -m64 -S %s -o - | grep {L_unnamed_cfstring_} + + at class NSString; + + at interface A +- (void)bork:(NSString*)msg; + at end + +void func(A *a) { + [a bork:@"Hello world!"]; +} From isanbard at gmail.com Mon Nov 24 17:34:08 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 23:34:08 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59993 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp Message-ID: <200811242334.mAONY8vA030697@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 17:34:07 2008 New Revision: 59993 URL: http://llvm.org/viewvc/llvm-project?rev=59993&view=rev Log: Add LLVM local markers. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.h?rev=59993&r1=59992&r2=59993&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.h Mon Nov 24 17:34:07 2008 @@ -695,6 +695,7 @@ } \ } while (0) +/* LLVM LOCAL - begin radar 6389998 */ /* A const CFString is created as an anonymous global variable. LLVM then gives it the name '__unnamed_#_#'. This causes troubles with the runtime, which expects the name to be internal. Give it an internal name here. */ @@ -708,6 +709,7 @@ GV->setName(N); \ } \ } while (0) +/* LLVM LOCAL - end radar 6389998 */ #endif /* LLVM LOCAL end */ Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=59993&r1=59992&r2=59993&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 17:34:07 2008 @@ -1134,10 +1134,12 @@ LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { GV->setSection(Section); + /* LLVM LOCAL - begin radar 6389998 */ #ifdef TARGET_ADJUST_CFSTRING_NAME if (!GV->hasName() && GV->hasInternalLinkage()) TARGET_ADJUST_CFSTRING_NAME(GV, Section); #endif + /* LLVM LOCAL - end radar 6389998 */ } #endif } From dpatel at apple.com Mon Nov 24 17:40:33 2008 From: dpatel at apple.com (Devang Patel) Date: Mon, 24 Nov 2008 15:40:33 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r59991 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp In-Reply-To: <200811242321.mAONLDqI030273@zion.cs.uiuc.edu> References: <200811242321.mAONLDqI030273@zion.cs.uiuc.edu> Message-ID: Bill, One nit-pick On Nov 24, 2008, at 3:21 PM, Bill Wendling wrote: > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 17:21:13 2008 > @@ -1133,6 +1133,11 @@ > if (const char *Section = > LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { > GV->setSection(Section); > + > +#ifdef TARGET_ADJUST_CFSTRING_NAME > + if (!GV->hasName() && GV->hasInternalLinkage()) pl. move this check inside darwin.c TARGET_ADJUST_CFSTRING_NAME macro. > > + TARGET_ADJUST_CFSTRING_NAME(GV, Section); > +#endif > } > #endif > } Thanks! - Devang From isanbard at gmail.com Mon Nov 24 17:41:38 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 15:41:38 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r59991 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp In-Reply-To: References: <200811242321.mAONLDqI030273@zion.cs.uiuc.edu> Message-ID: <16e5fdf90811241541j29b3ac6clb1cbcea7c230a6a7@mail.gmail.com> On Mon, Nov 24, 2008 at 3:40 PM, Devang Patel wrote: > Bill, > > One nit-pick > >> --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 17:21:13 2008 >> @@ -1133,6 +1133,11 @@ >> if (const char *Section = >> LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { >> GV->setSection(Section); >> + >> +#ifdef TARGET_ADJUST_CFSTRING_NAME >> + if (!GV->hasName() && GV->hasInternalLinkage()) > > pl. move this check inside darwin.c TARGET_ADJUST_CFSTRING_NAME macro. > Okay. -bw From isanbard at gmail.com Mon Nov 24 17:43:34 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 23:43:34 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59994 - in /llvm-gcc-4.2/trunk/gcc: config/darwin.h llvm-backend.cpp Message-ID: <200811242343.mAONhZat031010@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 17:43:34 2008 New Revision: 59994 URL: http://llvm.org/viewvc/llvm-project?rev=59994&view=rev Log: Move check inside of the macro. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.h?rev=59994&r1=59993&r2=59994&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.h Mon Nov 24 17:43:34 2008 @@ -701,7 +701,8 @@ expects the name to be internal. Give it an internal name here. */ #define TARGET_ADJUST_CFSTRING_NAME(GV, SEC) \ do { \ - if (strcmp((SEC), "__DATA, __cfstring") == 0) { \ + if (!GV->hasName() && GV->hasInternalLinkage() && \ + strcmp((SEC), "__DATA, __cfstring") == 0) { \ static unsigned i = 0; \ const char *fmt = "\01L_unnamed_cfstring_%d"; \ char *N = (char *)alloca(strlen(fmt) + 37); \ Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=59994&r1=59993&r2=59994&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 17:43:34 2008 @@ -1136,8 +1136,7 @@ /* LLVM LOCAL - begin radar 6389998 */ #ifdef TARGET_ADJUST_CFSTRING_NAME - if (!GV->hasName() && GV->hasInternalLinkage()) - TARGET_ADJUST_CFSTRING_NAME(GV, Section); + TARGET_ADJUST_CFSTRING_NAME(GV, Section); #endif /* LLVM LOCAL - end radar 6389998 */ } From isanbard at gmail.com Mon Nov 24 18:05:07 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 00:05:07 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r59996 - /llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Message-ID: <200811250005.mAP057GF031970@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 18:05:06 2008 New Revision: 59996 URL: http://llvm.org/viewvc/llvm-project?rev=59996&view=rev Log: Update to add the correct header file. Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=59996&r1=59995&r2=59996&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Mon Nov 24 18:05:06 2008 @@ -28,7 +28,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/CodeGen/ScheduleDAGSDNodes.h" +#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Streams.h" From scottm at aero.org Mon Nov 24 18:23:16 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 25 Nov 2008 00:23:16 -0000 Subject: [llvm-commits] [llvm] r59998 - in /llvm/trunk/lib/Target/CellSPU: SPUISelLowering.cpp SPUInstrInfo.td Message-ID: <200811250023.mAP0NHCB032612@zion.cs.uiuc.edu> Author: pingbak Date: Mon Nov 24 18:23:16 2008 New Revision: 59998 URL: http://llvm.org/viewvc/llvm-project?rev=59998&view=rev Log: CellSPU: Fix mnemonic typo in pattern; "shlqbyi" -> "shlqby". Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59998&r1=59997&r2=59998&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Nov 24 18:23:16 2008 @@ -177,7 +177,9 @@ setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); +#if 0 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); +#endif // SPU has no intrinsics for these particular operations: setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=59998&r1=59997&r2=59998&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Mon Nov 24 18:23:16 2008 @@ -1982,7 +1982,7 @@ // not by bits. See notes above on SHLQBI. class SHLQBYInst pattern>: - RI7Form<0b11111011100, OOL, IOL, "shlqbyi\t$rT, $rA, $rB", + RI7Form<0b11111011100, OOL, IOL, "shlqby\t$rT, $rA, $rB", RotateShift, pattern>; class SHLQBYVecInst: From isanbard at gmail.com Mon Nov 24 18:31:27 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 Nov 2008 16:31:27 -0800 Subject: [llvm-commits] [llvm] r59998 - in /llvm/trunk/lib/Target/CellSPU: SPUISelLowering.cpp SPUInstrInfo.td In-Reply-To: <200811250023.mAP0NHCB032612@zion.cs.uiuc.edu> References: <200811250023.mAP0NHCB032612@zion.cs.uiuc.edu> Message-ID: <16e5fdf90811241631w493539c7m222b6b0698092a2@mail.gmail.com> Hi Scott, I think this failed the "make check": http://google1.osuosl.org:8011/builders/llvm-x86_64-linux/builds/541 Please investigate. Thanks! -bw On Mon, Nov 24, 2008 at 4:23 PM, Scott Michel wrote: > Author: pingbak > Date: Mon Nov 24 18:23:16 2008 > New Revision: 59998 > > URL: http://llvm.org/viewvc/llvm-project?rev=59998&view=rev > Log: > CellSPU: Fix mnemonic typo in pattern; "shlqbyi" -> "shlqby". > > Modified: > llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp > llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td > > Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=59998&r1=59997&r2=59998&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Nov 24 18:23:16 2008 > @@ -177,7 +177,9 @@ > setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); > setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); > setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); > +#if 0 > setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); > +#endif > > // SPU has no intrinsics for these particular operations: > setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); > > Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=59998&r1=59997&r2=59998&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) > +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Mon Nov 24 18:23:16 2008 > @@ -1982,7 +1982,7 @@ > // not by bits. See notes above on SHLQBI. > > class SHLQBYInst pattern>: > - RI7Form<0b11111011100, OOL, IOL, "shlqbyi\t$rT, $rA, $rB", > + RI7Form<0b11111011100, OOL, IOL, "shlqby\t$rT, $rA, $rB", > RotateShift, pattern>; > > class SHLQBYVecInst: > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From gohman at apple.com Mon Nov 24 18:52:40 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 25 Nov 2008 00:52:40 -0000 Subject: [llvm-commits] [llvm] r59999 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/PostRASchedulerList.cpp lib/CodeGen/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp test/CodeGen/X86/break-anti-dependencies.ll Message-ID: <200811250052.mAP0qe1F001167@zion.cs.uiuc.edu> Author: djg Date: Mon Nov 24 18:52:40 2008 New Revision: 59999 URL: http://llvm.org/viewvc/llvm-project?rev=59999&view=rev Log: Initial support for anti-dependence breaking. Currently this code does not introduce any new spilling; it just uses unused registers. Refactor the SUnit topological sort code out of the RRList scheduler and make use of it to help with the post-pass scheduler. Added: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/ScheduleDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59999&r1=59998&r2=59999&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Nov 24 18:52:40 2008 @@ -17,6 +17,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallVector.h" @@ -148,7 +149,9 @@ unsigned PhyReg = 0, int Cost = 1, bool isAntiDep = false) { for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i) if (Preds[i].Dep == N && - Preds[i].isCtrl == isCtrl && Preds[i].isArtificial == isArtificial) + Preds[i].isCtrl == isCtrl && + Preds[i].isArtificial == isArtificial && + Preds[i].isAntiDep == isAntiDep) return false; Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isArtificial, isAntiDep)); N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, @@ -167,7 +170,10 @@ bool removePred(SUnit *N, bool isCtrl, bool isArtificial, bool isAntiDep) { for (SmallVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) - if (I->Dep == N && I->isCtrl == isCtrl && I->isArtificial == isArtificial) { + if (I->Dep == N && + I->isCtrl == isCtrl && + I->isArtificial == isArtificial && + I->isAntiDep == isAntiDep) { bool FoundSucc = false; for (SmallVector::iterator II = N->Succs.begin(), EE = N->Succs.end(); II != EE; ++II) @@ -404,6 +410,73 @@ return G->SUnits.end(); } }; + + /// ScheduleDAGTopologicalSort is a class that computes a topological + /// ordering for SUnits and provides methods for dynamically updating + /// the ordering as new edges are added. + /// + /// This allows a very fast implementation of IsReachable, for example. + /// + class ScheduleDAGTopologicalSort { + /// SUnits - A reference to the ScheduleDAG's SUnits. + std::vector &SUnits; + + /// Index2Node - Maps topological index to the node number. + std::vector Index2Node; + /// Node2Index - Maps the node number to its topological index. + std::vector Node2Index; + /// Visited - a set of nodes visited during a DFS traversal. + BitVector Visited; + + /// DFS - make a DFS traversal and mark all nodes affected by the + /// edge insertion. These nodes will later get new topological indexes + /// by means of the Shift method. + void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); + + /// Shift - reassign topological indexes for the nodes in the DAG + /// to preserve the topological ordering. + void Shift(BitVector& Visited, int LowerBound, int UpperBound); + + /// Allocate - assign the topological index to the node n. + void Allocate(int n, int index); + + public: + explicit ScheduleDAGTopologicalSort(std::vector &SUnits); + + /// InitDAGTopologicalSorting - create the initial topological + /// ordering from the DAG to be scheduled. + void InitDAGTopologicalSorting(); + + /// IsReachable - Checks if SU is reachable from TargetSU. + bool IsReachable(const SUnit *SU, const SUnit *TargetSU); + + /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU + /// will create a cycle. + bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); + + /// AddPred - Updates the topological ordering to accomodate an edge + /// to be added from SUnit X to SUnit Y. + void AddPred(SUnit *Y, SUnit *X); + + /// RemovePred - Updates the topological ordering to accomodate an + /// an edge to be removed from the specified node N from the predecessors + /// of the current node M. + void RemovePred(SUnit *M, SUnit *N); + + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + iterator begin() { return Index2Node.begin(); } + const_iterator begin() const { return Index2Node.begin(); } + iterator end() { return Index2Node.end(); } + const_iterator end() const { return Index2Node.end(); } + + typedef std::vector::reverse_iterator reverse_iterator; + typedef std::vector::const_reverse_iterator const_reverse_iterator; + reverse_iterator rbegin() { return Index2Node.rbegin(); } + const_reverse_iterator rbegin() const { return Index2Node.rbegin(); } + reverse_iterator rend() { return Index2Node.rend(); } + const_reverse_iterator rend() const { return Index2Node.rend(); } + }; } #endif Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=59999&r1=59998&r2=59999&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Nov 24 18:52:40 2008 @@ -24,24 +24,32 @@ #include "llvm/CodeGen/LatencyPriorityQueue.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/DenseSet.h" +#include +#include using namespace llvm; STATISTIC(NumStalls, "Number of pipeline stalls"); +static cl::opt +EnableAntiDepBreaking("break-anti-dependencies", + cl::desc("Break scheduling anti-dependencies"), + cl::init(false)); + namespace { class VISIBILITY_HIDDEN PostRAScheduler : public MachineFunctionPass { public: static char ID; PostRAScheduler() : MachineFunctionPass(&ID) {} - private: - MachineFunction *MF; - const TargetMachine *TM; - public: + const char *getPassName() const { - return "Post RA top-down list latency scheduler (STUB)"; + return "Post RA top-down list latency scheduler"; } bool runOnMachineFunction(MachineFunction &Fn); @@ -49,13 +57,6 @@ char PostRAScheduler::ID = 0; class VISIBILITY_HIDDEN SchedulePostRATDList : public ScheduleDAGInstrs { - public: - SchedulePostRATDList(MachineBasicBlock *mbb, const TargetMachine &tm) - : ScheduleDAGInstrs(mbb, tm) {} - private: - MachineFunction *MF; - const TargetMachine *TM; - /// AvailableQueue - The priority queue to use for the available SUnits. /// LatencyPriorityQueue AvailableQueue; @@ -66,12 +67,12 @@ /// added to the AvailableQueue. std::vector PendingQueue; - public: - const char *getPassName() const { - return "Post RA top-down list latency scheduler (STUB)"; - } + /// Topo - A topological ordering for SUnits. + ScheduleDAGTopologicalSort Topo; - bool runOnMachineFunction(MachineFunction &Fn); + public: + SchedulePostRATDList(MachineBasicBlock *mbb, const TargetMachine &tm) + : ScheduleDAGInstrs(mbb, tm), Topo(SUnits) {} void Schedule(); @@ -79,19 +80,18 @@ void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); + bool BreakAntiDependencies(); }; } bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { DOUT << "PostRAScheduler\n"; - MF = &Fn; - TM = &MF->getTarget(); // Loop over all of the basic blocks for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) { - SchedulePostRATDList Scheduler(MBB, *TM); + SchedulePostRATDList Scheduler(MBB, Fn.getTarget()); Scheduler.Run(); @@ -108,13 +108,407 @@ // Build scheduling units. BuildSchedUnits(); + if (EnableAntiDepBreaking) { + if (BreakAntiDependencies()) { + // We made changes. Update the dependency graph. + // Theoretically we could update the graph in place: + // When a live range is changed to use a different register, remove + // the def's anti-dependence *and* output-dependence edges due to + // that register, and add new anti-dependence and output-dependence + // edges based on the next live range of the register. + SUnits.clear(); + BuildSchedUnits(); + } + } + AvailableQueue.initNodes(SUnits); - + ListScheduleTopDown(); AvailableQueue.releaseState(); } +/// getInstrOperandRegClass - Return register class of the operand of an +/// instruction of the specified TargetInstrDesc. +static const TargetRegisterClass* +getInstrOperandRegClass(const TargetRegisterInfo *TRI, + const TargetInstrInfo *TII, const TargetInstrDesc &II, + unsigned Op) { + if (Op >= II.getNumOperands()) + return NULL; + if (II.OpInfo[Op].isLookupPtrRegClass()) + return TII->getPointerRegClass(); + return TRI->getRegClass(II.OpInfo[Op].RegClass); +} + +/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path +/// of the ScheduleDAG and break them by renaming registers. +/// +bool SchedulePostRATDList::BreakAntiDependencies() { + // The code below assumes that there is at least one instruction, + // so just duck out immediately if the block is empty. + if (BB->empty()) return false; + + Topo.InitDAGTopologicalSorting(); + + // Compute a critical path for the DAG. + SUnit *Max = 0; + std::vector CriticalPath(SUnits.size()); + for (ScheduleDAGTopologicalSort::const_iterator I = Topo.begin(), + E = Topo.end(); I != E; ++I) { + SUnit *SU = &SUnits[*I]; + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) { + SUnit *PredSU = P->Dep; + unsigned PredLatency = PredSU->CycleBound + PredSU->Latency; + if (SU->CycleBound < PredLatency) { + SU->CycleBound = PredLatency; + CriticalPath[*I] = &*P; + } + } + // Keep track of the node at the end of the critical path. + if (!Max || SU->CycleBound + SU->Latency > Max->CycleBound + Max->Latency) + Max = SU; + } + + DOUT << "Critical path has total latency " + << (Max ? Max->CycleBound + Max->Latency : 0) << "\n"; + + // Walk the critical path from the bottom up. Collect all anti-dependence + // edges on the critical path. Skip anti-dependencies between SUnits that + // are connected with other edges, since such units won't be able to be + // scheduled past each other anyway. + // + // The heuristic is that edges on the critical path are more important to + // break than other edges. And since there are a limited number of + // registers, we don't want to waste them breaking edges that aren't + // important. + // + // TODO: Instructions with multiple defs could have multiple + // anti-dependencies. The current code here only knows how to break one + // edge per instruction. Note that we'd have to be able to break all of + // the anti-dependencies in an instruction in order to be effective. + BitVector AllocatableSet = TRI->getAllocatableSet(*MF); + DenseMap CriticalAntiDeps; + for (SUnit *SU = Max; CriticalPath[SU->NodeNum]; + SU = CriticalPath[SU->NodeNum]->Dep) { + SDep *Edge = CriticalPath[SU->NodeNum]; + SUnit *NextSU = Edge->Dep; + unsigned AntiDepReg = Edge->Reg; + // Don't break anti-dependencies on non-allocatable registers. + if (!AllocatableSet.test(AntiDepReg)) + continue; + // If the SUnit has other dependencies on the SUnit that it + // anti-depends on, don't bother breaking the anti-dependency. + // Also, if there are dependencies on other SUnits with the + // same register as the anti-dependency, don't attempt to + // break it. + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) + if (P->Dep == NextSU ? + (!P->isAntiDep || P->Reg != AntiDepReg) : + (!P->isCtrl && !P->isAntiDep && P->Reg == AntiDepReg)) { + AntiDepReg = 0; + break; + } + if (AntiDepReg != 0) + CriticalAntiDeps[SU->getInstr()] = AntiDepReg; + } + + // For live regs that are only used in one register class in a live range, + // the register class. If the register is not live or is referenced in + // multiple register classes, the corresponding value is null. If the + // register is used in multiple register classes, the corresponding value + // is -1 casted to a pointer. + const TargetRegisterClass * + Classes[TargetRegisterInfo::FirstVirtualRegister] = {}; + + // Map registers to all their references within a live range. + std::multimap RegRefs; + + // The index of the most recent kill (proceding bottom-up), or -1 if + // the register is not live. + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; + std::fill(KillIndices, array_endof(KillIndices), -1); + // The index of the most recent def (proceding bottom up), or -1 if + // the register is live. + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; + std::fill(DefIndices, array_endof(DefIndices), BB->size()); + + // Determine the live-out physregs for this block. + if (!BB->empty() && BB->back().getDesc().isReturn()) + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = -1; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = -1; + } + } + else + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = -1; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = -1; + } + } + + // Consider callee-saved registers as live-out, since we're running after + // prologue/epilogue insertion so there's no way to add additional + // saved registers. + // + // TODO: If the callee saves and restores these, then we can potentially + // use them between the save and the restore. To do that, we could scan + // the exit blocks to see which of these registers are defined. + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = -1; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = -1; + } + } + + // Consider this pattern: + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // There are three anti-dependencies here, and without special care, + // we'd break all of them using the same register: + // A = ... + // ... = A + // B = ... + // ... = B + // B = ... + // ... = B + // B = ... + // ... = B + // because at each anti-dependence, B is the first register that + // isn't A which is free. This re-introduces anti-dependencies + // at all but one of the original anti-dependencies that we were + // trying to break. To avoid this, keep track of the most recent + // register that each register was replaced with, avoid avoid + // using it to repair an anti-dependence on the same register. + // This lets us produce this: + // A = ... + // ... = A + // B = ... + // ... = B + // C = ... + // ... = C + // B = ... + // ... = B + // This still has an anti-dependence on B, but at least it isn't on the + // original critical path. + // + // TODO: If we tracked more than one register here, we could potentially + // fix that remaining critical edge too. This is a little more involved, + // because unlike the most recent register, less recent registers should + // still be considered, though only if no other registers are available. + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; + + // A registers defined and not used in an instruction. This is used for + // liveness tracking and is declared outside the loop only to avoid + // having it be re-allocated on each iteration. + DenseSet Defs; + + // Attempt to break anti-dependence edges on the critical path. Walk the + // instructions from the bottom up, tracking information about liveness + // as we go to help determine which registers are available. + bool Changed = false; + unsigned Count = BB->size() - 1; + for (MachineBasicBlock::reverse_iterator I = BB->rbegin(), E = BB->rend(); + I != E; ++I, --Count) { + MachineInstr *MI = &*I; + + // Check if this instruction has an anti-dependence that we're + // interested in. + DenseMap::iterator C = CriticalAntiDeps.find(MI); + unsigned AntiDepReg = C != CriticalAntiDeps.end() ? + C->second : 0; + + // Scan the register operands for this instruction and update + // Classes and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + const TargetRegisterClass *NewRC = + getInstrOperandRegClass(TRI, TII, MI->getDesc(), i); + + // If this instruction has a use of AntiDepReg, breaking it + // is invalid. + if (MO.isUse() && AntiDepReg == Reg) + AntiDepReg = 0; + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast(-1); + + // Now check for aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + // If an alias of the reg is used during the live range, give up. + // Note that this allows us to skip checking if AntiDepReg + // overlaps with any of the aliases, among other things. + unsigned AliasReg = *Alias; + if (Classes[AliasReg]) { + Classes[AliasReg] = reinterpret_cast(-1); + Classes[Reg] = reinterpret_cast(-1); + } + } + + // If we're still willing to consider this register, note the reference. + if (Classes[Reg] != reinterpret_cast(-1)) + RegRefs.insert(std::make_pair(Reg, &MO)); + } + + // Determine AntiDepReg's register class, if it is live and is + // consistently used within a single class. + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; + assert(AntiDepReg == 0 || RC != NULL && + "Register should be live if it's causing an anti-dependence!"); + if (RC == reinterpret_cast(-1)) + AntiDepReg = 0; + + // Look for a suitable register to use to break the anti-depenence. + // + // TODO: Instead of picking the first free register, consider which might + // be the best. + if (AntiDepReg != 0) { + for (TargetRegisterClass::iterator R = RC->allocation_order_begin(*MF), + RE = RC->allocation_order_end(*MF); R != RE; ++R) { + unsigned NewReg = *R; + // Don't replace a register with itself. + if (NewReg == AntiDepReg) continue; + // Don't replace a register with one that was recently used to repair + // an anti-dependence with this AntiDepReg, because that would + // re-introduce that anti-dependence. + if (NewReg == LastNewReg[AntiDepReg]) continue; + // If NewReg is dead and NewReg's most recent def is not before + // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. + assert(((KillIndices[AntiDepReg] == -1) != (DefIndices[AntiDepReg] == -1)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + assert(((KillIndices[NewReg] == -1) != (DefIndices[NewReg] == -1)) && + "Kill and Def maps aren't consistent for NewReg!"); + if (KillIndices[NewReg] == -1 && + KillIndices[AntiDepReg] <= DefIndices[NewReg]) { + DOUT << "Breaking anti-dependence edge on reg " << AntiDepReg + << " with reg " << NewReg << "!\n"; + + // Update the references to the old register to refer to the new + // register. + std::pair::iterator, + std::multimap::iterator> + Range = RegRefs.equal_range(AntiDepReg); + for (std::multimap::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) + Q->second->setReg(NewReg); + + // We just went back in time and modified history; the + // liveness information for the anti-depenence reg is now + // inconsistent. Set the state as if it were dead. + Classes[NewReg] = Classes[AntiDepReg]; + DefIndices[NewReg] = DefIndices[AntiDepReg]; + KillIndices[NewReg] = KillIndices[AntiDepReg]; + + Classes[AntiDepReg] = 0; + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; + KillIndices[AntiDepReg] = -1; + + RegRefs.erase(AntiDepReg); + Changed = true; + LastNewReg[AntiDepReg] = NewReg; + break; + } + } + } + + // Update liveness. + Defs.clear(); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (MO.isDef()) + Defs.insert(Reg); + else { + // Treat a use in the same instruction as a def as an extension of + // a live range. + Defs.erase(Reg); + // It wasn't previously live but now it is, this is a kill. + if (KillIndices[Reg] == -1) { + KillIndices[Reg] = Count; + DefIndices[Reg] = -1; + } + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Defs.erase(AliasReg); + if (KillIndices[AliasReg] == -1) { + KillIndices[AliasReg] = Count; + DefIndices[AliasReg] = -1; + } + } + } + } + // Proceding upwards, registers that are defed but not used in this + // instruction are now dead. + for (DenseSet::iterator D = Defs.begin(), DE = Defs.end(); + D != DE; ++D) { + unsigned Reg = *D; + DefIndices[Reg] = Count; + KillIndices[Reg] = -1; + Classes[Reg] = 0; + RegRefs.erase(Reg); + // Repeat, for all subregs. + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + DefIndices[SubregReg] = Count; + KillIndices[SubregReg] = -1; + Classes[SubregReg] = 0; + RegRefs.erase(SubregReg); + } + } + } + assert(Count == -1u && "Count mismatch!"); + + return Changed; +} + //===----------------------------------------------------------------------===// // Top-Down Scheduling //===----------------------------------------------------------------------===// @@ -202,8 +596,7 @@ } } - // If there are no instructions available, don't try to issue anything, and - // don't advance the hazard recognizer. + // If there are no instructions available, don't try to issue anything. if (AvailableQueue.empty()) { ++CurCycle; continue; Modified: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?rev=59999&r1=59998&r2=59999&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Mon Nov 24 18:52:40 2008 @@ -263,3 +263,204 @@ "The number of nodes scheduled doesn't match the expected number!"); } #endif + +/// InitDAGTopologicalSorting - create the initial topological +/// ordering from the DAG to be scheduled. +/// +/// The idea of the algorithm is taken from +/// "Online algorithms for managing the topological order of +/// a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly +/// This is the MNR algorithm, which was first introduced by +/// A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in +/// "Maintaining a topological order under edge insertions". +/// +/// Short description of the algorithm: +/// +/// Topological ordering, ord, of a DAG maps each node to a topological +/// index so that for all edges X->Y it is the case that ord(X) < ord(Y). +/// +/// This means that if there is a path from the node X to the node Z, +/// then ord(X) < ord(Z). +/// +/// This property can be used to check for reachability of nodes: +/// if Z is reachable from X, then an insertion of the edge Z->X would +/// create a cycle. +/// +/// The algorithm first computes a topological ordering for the DAG by +/// initializing the Index2Node and Node2Index arrays and then tries to keep +/// the ordering up-to-date after edge insertions by reordering the DAG. +/// +/// On insertion of the edge X->Y, the algorithm first marks by calling DFS +/// the nodes reachable from Y, and then shifts them using Shift to lie +/// immediately after X in Index2Node. +void ScheduleDAGTopologicalSort::InitDAGTopologicalSorting() { + unsigned DAGSize = SUnits.size(); + std::vector WorkList; + WorkList.reserve(DAGSize); + + Index2Node.resize(DAGSize); + Node2Index.resize(DAGSize); + + // Initialize the data structures. + for (unsigned i = 0, e = DAGSize; i != e; ++i) { + SUnit *SU = &SUnits[i]; + int NodeNum = SU->NodeNum; + unsigned Degree = SU->Succs.size(); + // Temporarily use the Node2Index array as scratch space for degree counts. + Node2Index[NodeNum] = Degree; + + // Is it a node without dependencies? + if (Degree == 0) { + assert(SU->Succs.empty() && "SUnit should have no successors"); + // Collect leaf nodes. + WorkList.push_back(SU); + } + } + + int Id = DAGSize; + while (!WorkList.empty()) { + SUnit *SU = WorkList.back(); + WorkList.pop_back(); + Allocate(SU->NodeNum, --Id); + for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + SUnit *SU = I->Dep; + if (!--Node2Index[SU->NodeNum]) + // If all dependencies of the node are processed already, + // then the node can be computed now. + WorkList.push_back(SU); + } + } + + Visited.resize(DAGSize); + +#ifndef NDEBUG + // Check correctness of the ordering + for (unsigned i = 0, e = DAGSize; i != e; ++i) { + SUnit *SU = &SUnits[i]; + for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + assert(Node2Index[SU->NodeNum] > Node2Index[I->Dep->NodeNum] && + "Wrong topological sorting"); + } + } +#endif +} + +/// AddPred - Updates the topological ordering to accomodate an edge +/// to be added from SUnit X to SUnit Y. +void ScheduleDAGTopologicalSort::AddPred(SUnit *Y, SUnit *X) { + int UpperBound, LowerBound; + LowerBound = Node2Index[Y->NodeNum]; + UpperBound = Node2Index[X->NodeNum]; + bool HasLoop = false; + // Is Ord(X) < Ord(Y) ? + if (LowerBound < UpperBound) { + // Update the topological order. + Visited.reset(); + DFS(Y, UpperBound, HasLoop); + assert(!HasLoop && "Inserted edge creates a loop!"); + // Recompute topological indexes. + Shift(Visited, LowerBound, UpperBound); + } +} + +/// RemovePred - Updates the topological ordering to accomodate an +/// an edge to be removed from the specified node N from the predecessors +/// of the current node M. +void ScheduleDAGTopologicalSort::RemovePred(SUnit *M, SUnit *N) { + // InitDAGTopologicalSorting(); +} + +/// DFS - Make a DFS traversal to mark all nodes reachable from SU and mark +/// all nodes affected by the edge insertion. These nodes will later get new +/// topological indexes by means of the Shift method. +void ScheduleDAGTopologicalSort::DFS(const SUnit *SU, int UpperBound, bool& HasLoop) { + std::vector WorkList; + WorkList.reserve(SUnits.size()); + + WorkList.push_back(SU); + while (!WorkList.empty()) { + SU = WorkList.back(); + WorkList.pop_back(); + Visited.set(SU->NodeNum); + for (int I = SU->Succs.size()-1; I >= 0; --I) { + int s = SU->Succs[I].Dep->NodeNum; + if (Node2Index[s] == UpperBound) { + HasLoop = true; + return; + } + // Visit successors if not already and in affected region. + if (!Visited.test(s) && Node2Index[s] < UpperBound) { + WorkList.push_back(SU->Succs[I].Dep); + } + } + } +} + +/// Shift - Renumber the nodes so that the topological ordering is +/// preserved. +void ScheduleDAGTopologicalSort::Shift(BitVector& Visited, int LowerBound, + int UpperBound) { + std::vector L; + int shift = 0; + int i; + + for (i = LowerBound; i <= UpperBound; ++i) { + // w is node at topological index i. + int w = Index2Node[i]; + if (Visited.test(w)) { + // Unmark. + Visited.reset(w); + L.push_back(w); + shift = shift + 1; + } else { + Allocate(w, i - shift); + } + } + + for (unsigned j = 0; j < L.size(); ++j) { + Allocate(L[j], i - shift); + i = i + 1; + } +} + + +/// WillCreateCycle - Returns true if adding an edge from SU to TargetSU will +/// create a cycle. +bool ScheduleDAGTopologicalSort::WillCreateCycle(SUnit *SU, SUnit *TargetSU) { + if (IsReachable(TargetSU, SU)) + return true; + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) + if (I->Cost < 0 && IsReachable(TargetSU, I->Dep)) + return true; + return false; +} + +/// IsReachable - Checks if SU is reachable from TargetSU. +bool ScheduleDAGTopologicalSort::IsReachable(const SUnit *SU, const SUnit *TargetSU) { + // If insertion of the edge SU->TargetSU would create a cycle + // then there is a path from TargetSU to SU. + int UpperBound, LowerBound; + LowerBound = Node2Index[TargetSU->NodeNum]; + UpperBound = Node2Index[SU->NodeNum]; + bool HasLoop = false; + // Is Ord(TargetSU) < Ord(SU) ? + if (LowerBound < UpperBound) { + Visited.reset(); + // There may be a path from TargetSU to SU. Check for it. + DFS(TargetSU, UpperBound, HasLoop); + } + return HasLoop; +} + +/// Allocate - assign the topological index to the node n. +void ScheduleDAGTopologicalSort::Allocate(int n, int index) { + Node2Index[n] = index; + Index2Node[index] = n; +} + +ScheduleDAGTopologicalSort::ScheduleDAGTopologicalSort( + std::vector &sunits) + : SUnits(sunits) {} Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59999&r1=59998&r2=59999&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Nov 24 18:52:40 2008 @@ -69,12 +69,16 @@ std::vector LiveRegDefs; std::vector LiveRegCycles; + /// Topo - A topological ordering for SUnits which permits fast IsReachable + /// and similar queries. + ScheduleDAGTopologicalSort Topo; + public: ScheduleDAGRRList(SelectionDAG *dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, SchedulingPriorityQueue *availqueue) : ScheduleDAGSDNodes(dag, bb, tm), isBottomUp(isbottomup), - AvailableQueue(availqueue) { + AvailableQueue(availqueue), Topo(SUnits) { } ~ScheduleDAGRRList() { @@ -84,22 +88,32 @@ void Schedule(); /// IsReachable - Checks if SU is reachable from TargetSU. - bool IsReachable(const SUnit *SU, const SUnit *TargetSU); + bool IsReachable(const SUnit *SU, const SUnit *TargetSU) { + return Topo.IsReachable(SU, TargetSU); + } /// willCreateCycle - Returns true if adding an edge from SU to TargetSU will /// create a cycle. - bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); + bool WillCreateCycle(SUnit *SU, SUnit *TargetSU) { + return Topo.WillCreateCycle(SU, TargetSU); + } /// AddPred - This adds the specified node X as a predecessor of /// the current node Y if not already. /// This returns true if this is a new predecessor. /// Updates the topological ordering if required. bool AddPred(SUnit *Y, SUnit *X, bool isCtrl, bool isArtificial, - unsigned PhyReg = 0, int Cost = 1); + unsigned PhyReg = 0, int Cost = 1) { + Topo.AddPred(Y, X); + return Y->addPred(X, isCtrl, isArtificial, PhyReg, Cost); + } /// RemovePred - This removes the specified node N from the predecessors of /// the current node M. Updates the topological ordering if required. - bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial); + bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isArtificial) { + Topo.RemovePred(M, N); + return M->removePred(N, isCtrl, isArtificial, false); + } private: void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain); @@ -123,49 +137,24 @@ /// CreateNewSUnit - Creates a new SUnit and returns a pointer to it. /// Updates the topological ordering if required. SUnit *CreateNewSUnit(SDNode *N) { + unsigned NumSUnits = SUnits.size(); SUnit *NewNode = NewSUnit(N); // Update the topological ordering. - if (NewNode->NodeNum >= Node2Index.size()) - InitDAGTopologicalSorting(); + if (NewNode->NodeNum >= NumSUnits) + Topo.InitDAGTopologicalSorting(); return NewNode; } /// CreateClone - Creates a new SUnit from an existing one. /// Updates the topological ordering if required. SUnit *CreateClone(SUnit *N) { + unsigned NumSUnits = SUnits.size(); SUnit *NewNode = Clone(N); // Update the topological ordering. - if (NewNode->NodeNum >= Node2Index.size()) - InitDAGTopologicalSorting(); + if (NewNode->NodeNum >= NumSUnits) + Topo.InitDAGTopologicalSorting(); return NewNode; } - - /// Functions for preserving the topological ordering - /// even after dynamic insertions of new edges. - /// This allows a very fast implementation of IsReachable. - - /// InitDAGTopologicalSorting - create the initial topological - /// ordering from the DAG to be scheduled. - void InitDAGTopologicalSorting(); - - /// DFS - make a DFS traversal and mark all nodes affected by the - /// edge insertion. These nodes will later get new topological indexes - /// by means of the Shift method. - void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); - - /// Shift - reassign topological indexes for the nodes in the DAG - /// to preserve the topological ordering. - void Shift(BitVector& Visited, int LowerBound, int UpperBound); - - /// Allocate - assign the topological index to the node n. - void Allocate(int n, int index); - - /// Index2Node - Maps topological index to the node number. - std::vector Index2Node; - /// Node2Index - Maps the node number to its topological index. - std::vector Node2Index; - /// Visited - a set of nodes visited during a DFS traversal. - BitVector Visited; }; } // end anonymous namespace @@ -185,7 +174,7 @@ SUnits[su].dumpAll(this)); CalculateDepths(); CalculateHeights(); - InitDAGTopologicalSorting(); + Topo.InitDAGTopologicalSorting(); AvailableQueue->initNodes(SUnits); @@ -374,207 +363,6 @@ AvailableQueue->push(SU); } -/// IsReachable - Checks if SU is reachable from TargetSU. -bool ScheduleDAGRRList::IsReachable(const SUnit *SU, const SUnit *TargetSU) { - // If insertion of the edge SU->TargetSU would create a cycle - // then there is a path from TargetSU to SU. - int UpperBound, LowerBound; - LowerBound = Node2Index[TargetSU->NodeNum]; - UpperBound = Node2Index[SU->NodeNum]; - bool HasLoop = false; - // Is Ord(TargetSU) < Ord(SU) ? - if (LowerBound < UpperBound) { - Visited.reset(); - // There may be a path from TargetSU to SU. Check for it. - DFS(TargetSU, UpperBound, HasLoop); - } - return HasLoop; -} - -/// Allocate - assign the topological index to the node n. -inline void ScheduleDAGRRList::Allocate(int n, int index) { - Node2Index[n] = index; - Index2Node[index] = n; -} - -/// InitDAGTopologicalSorting - create the initial topological -/// ordering from the DAG to be scheduled. - -/// The idea of the algorithm is taken from -/// "Online algorithms for managing the topological order of -/// a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly -/// This is the MNR algorithm, which was first introduced by -/// A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in -/// "Maintaining a topological order under edge insertions". -/// -/// Short description of the algorithm: -/// -/// Topological ordering, ord, of a DAG maps each node to a topological -/// index so that for all edges X->Y it is the case that ord(X) < ord(Y). -/// -/// This means that if there is a path from the node X to the node Z, -/// then ord(X) < ord(Z). -/// -/// This property can be used to check for reachability of nodes: -/// if Z is reachable from X, then an insertion of the edge Z->X would -/// create a cycle. -/// -/// The algorithm first computes a topological ordering for the DAG by -/// initializing the Index2Node and Node2Index arrays and then tries to keep -/// the ordering up-to-date after edge insertions by reordering the DAG. -/// -/// On insertion of the edge X->Y, the algorithm first marks by calling DFS -/// the nodes reachable from Y, and then shifts them using Shift to lie -/// immediately after X in Index2Node. -void ScheduleDAGRRList::InitDAGTopologicalSorting() { - unsigned DAGSize = SUnits.size(); - std::vector WorkList; - WorkList.reserve(DAGSize); - - Index2Node.resize(DAGSize); - Node2Index.resize(DAGSize); - - // Initialize the data structures. - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - int NodeNum = SU->NodeNum; - unsigned Degree = SU->Succs.size(); - // Temporarily use the Node2Index array as scratch space for degree counts. - Node2Index[NodeNum] = Degree; - - // Is it a node without dependencies? - if (Degree == 0) { - assert(SU->Succs.empty() && "SUnit should have no successors"); - // Collect leaf nodes. - WorkList.push_back(SU); - } - } - - int Id = DAGSize; - while (!WorkList.empty()) { - SUnit *SU = WorkList.back(); - WorkList.pop_back(); - Allocate(SU->NodeNum, --Id); - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - SUnit *SU = I->Dep; - if (!--Node2Index[SU->NodeNum]) - // If all dependencies of the node are processed already, - // then the node can be computed now. - WorkList.push_back(SU); - } - } - - Visited.resize(DAGSize); - -#ifndef NDEBUG - // Check correctness of the ordering - for (unsigned i = 0, e = DAGSize; i != e; ++i) { - SUnit *SU = &SUnits[i]; - for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) { - assert(Node2Index[SU->NodeNum] > Node2Index[I->Dep->NodeNum] && - "Wrong topological sorting"); - } - } -#endif -} - -/// AddPred - adds an edge from SUnit X to SUnit Y. -/// Updates the topological ordering if required. -bool ScheduleDAGRRList::AddPred(SUnit *Y, SUnit *X, bool isCtrl, - bool isArtificial, unsigned PhyReg, int Cost) { - int UpperBound, LowerBound; - LowerBound = Node2Index[Y->NodeNum]; - UpperBound = Node2Index[X->NodeNum]; - bool HasLoop = false; - // Is Ord(X) < Ord(Y) ? - if (LowerBound < UpperBound) { - // Update the topological order. - Visited.reset(); - DFS(Y, UpperBound, HasLoop); - assert(!HasLoop && "Inserted edge creates a loop!"); - // Recompute topological indexes. - Shift(Visited, LowerBound, UpperBound); - } - // Now really insert the edge. - return Y->addPred(X, isCtrl, isArtificial, PhyReg, Cost); -} - -/// RemovePred - This removes the specified node N from the predecessors of -/// the current node M. Updates the topological ordering if required. -bool ScheduleDAGRRList::RemovePred(SUnit *M, SUnit *N, - bool isCtrl, bool isArtificial) { - // InitDAGTopologicalSorting(); - return M->removePred(N, isCtrl, isArtificial, false); -} - -/// DFS - Make a DFS traversal to mark all nodes reachable from SU and mark -/// all nodes affected by the edge insertion. These nodes will later get new -/// topological indexes by means of the Shift method. -void ScheduleDAGRRList::DFS(const SUnit *SU, int UpperBound, bool& HasLoop) { - std::vector WorkList; - WorkList.reserve(SUnits.size()); - - WorkList.push_back(SU); - while (!WorkList.empty()) { - SU = WorkList.back(); - WorkList.pop_back(); - Visited.set(SU->NodeNum); - for (int I = SU->Succs.size()-1; I >= 0; --I) { - int s = SU->Succs[I].Dep->NodeNum; - if (Node2Index[s] == UpperBound) { - HasLoop = true; - return; - } - // Visit successors if not already and in affected region. - if (!Visited.test(s) && Node2Index[s] < UpperBound) { - WorkList.push_back(SU->Succs[I].Dep); - } - } - } -} - -/// Shift - Renumber the nodes so that the topological ordering is -/// preserved. -void ScheduleDAGRRList::Shift(BitVector& Visited, int LowerBound, - int UpperBound) { - std::vector L; - int shift = 0; - int i; - - for (i = LowerBound; i <= UpperBound; ++i) { - // w is node at topological index i. - int w = Index2Node[i]; - if (Visited.test(w)) { - // Unmark. - Visited.reset(w); - L.push_back(w); - shift = shift + 1; - } else { - Allocate(w, i - shift); - } - } - - for (unsigned j = 0; j < L.size(); ++j) { - Allocate(L[j], i - shift); - i = i + 1; - } -} - - -/// WillCreateCycle - Returns true if adding an edge from SU to TargetSU will -/// create a cycle. -bool ScheduleDAGRRList::WillCreateCycle(SUnit *SU, SUnit *TargetSU) { - if (IsReachable(TargetSU, SU)) - return true; - for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); - I != E; ++I) - if (I->Cost < 0 && IsReachable(TargetSU, I->Dep)) - return true; - return false; -} - /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in /// BTCycle in order to schedule a specific node. Returns the last unscheduled /// SUnit. Also returns if a successor is unscheduled in the process. Added: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=59999&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (added) +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Nov 24 18:52:40 2008 @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s | llc -march=x86-64 -disable-post-RA-scheduler=false > %t +; RUN: grep {%xmm0} %t | count 14 +; RUN: not grep {%xmm1} %t +; RUN: llvm-as < %s | llc -march=x86-64 -disable-post-RA-scheduler=false -break-anti-dependencies > %t +; RUN: grep {%xmm0} %t | count 7 +; RUN: grep {%xmm1} %t | count 7 + +define void @goo(double* %r, double* %p, double* %q) nounwind { +entry: + %0 = load double* %p, align 8 + %1 = add double %0, 1.100000e+00 + %2 = mul double %1, 1.200000e+00 + %3 = add double %2, 1.300000e+00 + %4 = mul double %3, 1.400000e+00 + %5 = add double %4, 1.500000e+00 + %6 = fptosi double %5 to i32 + %7 = load double* %r, align 8 + %8 = add double %7, 7.100000e+00 + %9 = mul double %8, 7.200000e+00 + %10 = add double %9, 7.300000e+00 + %11 = mul double %10, 7.400000e+00 + %12 = add double %11, 7.500000e+00 + %13 = fptosi double %12 to i32 + %14 = icmp slt i32 %6, %13 + br i1 %14, label %bb, label %return + +bb: + store double 9.300000e+00, double* %q, align 8 + ret void + +return: + ret void +} From isanbard at gmail.com Mon Nov 24 18:56:34 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 00:56:34 -0000 Subject: [llvm-commits] [llvm] r60000 - /llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Message-ID: <200811250056.mAP0uYRC001314@zion.cs.uiuc.edu> Author: void Date: Mon Nov 24 18:56:34 2008 New Revision: 60000 URL: http://llvm.org/viewvc/llvm-project?rev=60000&view=rev Log: XFAIL this test. A recent CellSPU check-in broke it. Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll?rev=60000&r1=59999&r2=60000&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Mon Nov 24 18:56:34 2008 @@ -28,6 +28,7 @@ ; RUN: grep 32782 %t1.s | count 1 ; RUN: grep 32783 %t1.s | count 1 ; RUN: grep 32896 %t1.s | count 24 +; XFAIL: * target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" From scottm at aero.org Mon Nov 24 19:30:37 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 25 Nov 2008 01:30:37 -0000 Subject: [llvm-commits] [llvm] r60001 - /llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Message-ID: <200811250130.mAP1UbXF002526@zion.cs.uiuc.edu> Author: pingbak Date: Mon Nov 24 19:30:37 2008 New Revision: 60001 URL: http://llvm.org/viewvc/llvm-project?rev=60001&view=rev Log: CellSPU: test should use shlqby, not shlqbyi Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll?rev=60001&r1=60000&r2=60001&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Mon Nov 24 19:30:37 2008 @@ -3,7 +3,7 @@ ; RUN: grep ilhu %t1.s | count 27 ; RUN: grep iohl %t1.s | count 27 ; RUN: grep lqa %t1.s | count 10 -; RUN: grep shlqbyi %t1.s | count 12 +; RUN: grep shlqby %t1.s | count 12 ; RUN: grep 515 %t1.s | count 1 ; RUN: grep 1029 %t1.s | count 2 ; RUN: grep 1543 %t1.s | count 2 @@ -28,7 +28,6 @@ ; RUN: grep 32782 %t1.s | count 1 ; RUN: grep 32783 %t1.s | count 1 ; RUN: grep 32896 %t1.s | count 24 -; XFAIL: * target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" From dalej at apple.com Mon Nov 24 20:15:57 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Nov 2008 02:15:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60003 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200811250215.mAP2Fvrf004027@zion.cs.uiuc.edu> Author: johannes Date: Mon Nov 24 20:15:57 2008 New Revision: 60003 URL: http://llvm.org/viewvc/llvm-project?rev=60003&view=rev Log: Get rid of that annoying leading _ on ObjC constructed function names. Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=60003&r1=60002&r2=60003&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Mon Nov 24 20:15:57 2008 @@ -18296,6 +18296,11 @@ get_arg_type_list (METHOD_SEL_NAME (method), method, METHOD_DEF, 0)); /* APPLE LOCAL radar 5839812 - location for synthesized methods */ objc_start_function (method_id, meth_type, NULL_TREE, parmlist, method); +/* LLVM LOCAL begin prevent llvm from adding leading _ */ +#ifdef ENABLE_LLVM + set_user_assembler_name(current_function_decl, buf); +#endif +/* LLVM LOCAL end prevent llvm from adding leading _ */ /* Set self_decl from the first argument. */ self_decl = DECL_ARGUMENTS (current_function_decl); From dpatel at apple.com Mon Nov 24 20:34:50 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Nov 2008 02:34:50 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60004 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200811250234.mAP2YoTW004695@zion.cs.uiuc.edu> Author: dpatel Date: Mon Nov 24 20:34:49 2008 New Revision: 60004 URL: http://llvm.org/viewvc/llvm-project?rev=60004&view=rev Log: Disable loop-index-split for now. It has a bug that is encouraging me to rewrite large portion of this pass. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=60004&r1=60003&r2=60004&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 20:34:49 2008 @@ -444,7 +444,7 @@ PM->add(createLoopRotatePass()); // Rotate Loop PM->add(createLICMPass()); // Hoist loop invariants PM->add(createLoopUnswitchPass(optimize_size ? true : false)); - PM->add(createLoopIndexSplitPass()); // Split loop index + // PM->add(createLoopIndexSplitPass()); // Split loop index PM->add(createInstructionCombiningPass()); PM->add(createIndVarSimplifyPass()); // Canonicalize indvars PM->add(createLoopDeletionPass()); // Delete dead loops From scottm at aero.org Mon Nov 24 22:03:48 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 25 Nov 2008 04:03:48 -0000 Subject: [llvm-commits] [llvm] r60006 - /llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Message-ID: <200811250403.mAP43mnm007474@zion.cs.uiuc.edu> Author: pingbak Date: Mon Nov 24 22:03:47 2008 New Revision: 60006 URL: http://llvm.org/viewvc/llvm-project?rev=60006&view=rev Log: CellSPU: Relax constraints on when to generate a X-form address, evidently they were too tight according to bug 3126. Fix bug 3126. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=60006&r1=60005&r2=60006&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Mon Nov 24 22:03:47 2008 @@ -591,6 +591,7 @@ SDValue &Index) { if (!SelectAFormAddr(Op, N, Base, Index) && !SelectDFormAddr(Op, N, Base, Index)) { +#if 0 // Default form of a X-form address is r(r) in operands 0 and 1: SDValue Op0 = N.getOperand(0); SDValue Op1 = N.getOperand(1); @@ -611,6 +612,12 @@ return true; } +#else + // All else fails, punt and use an X-form address: + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; +#endif } return false; From ofv at wanadoo.es Mon Nov 24 22:23:40 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 25 Nov 2008 04:23:40 -0000 Subject: [llvm-commits] [llvm] r60008 - /llvm/trunk/docs/CMake.html Message-ID: <200811250423.mAP4Ne8q008261@zion.cs.uiuc.edu> Author: ofv Date: Mon Nov 24 22:23:36 2008 New Revision: 60008 URL: http://llvm.org/viewvc/llvm-project?rev=60008&view=rev Log: CMake: Documented two cmake variables. Modified: llvm/trunk/docs/CMake.html Modified: llvm/trunk/docs/CMake.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CMake.html?rev=60008&r1=60007&r2=60008&view=diff ============================================================================== --- llvm/trunk/docs/CMake.html (original) +++ llvm/trunk/docs/CMake.html Mon Nov 24 22:23:36 2008 @@ -213,6 +213,12 @@

    Path where LLVM will be installed if "make install" is invoked or the "INSTALL" target is built.
    +
    CMAKE_C_FLAGS:STRING
    +
    Extra flags to use when compiling C source files.
    + +
    CMAKE_CXX_FLAGS:STRING
    +
    Extra flags to use when compiling C++ source files.
    +
    BUILD_SHARED_LIBS:BOOL
    Flag indicating is shared libraries will be built. Its default value is OFF. Shared libraries are not supported on Windows and From sabre at nondot.org Mon Nov 24 22:42:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 04:42:10 -0000 Subject: [llvm-commits] [llvm] r60009 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811250442.mAP4gA3g008796@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 22:42:10 2008 New Revision: 60009 URL: http://llvm.org/viewvc/llvm-project?rev=60009&view=rev Log: minor cleanups no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60009&r1=60008&r2=60009&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 22:42:10 2008 @@ -33,7 +33,9 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Support/PatternMatch.h" using namespace llvm; +using namespace llvm::PatternMatch; namespace { class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass { @@ -537,41 +539,38 @@ if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) return false; - ExtAddrMode InputAddrMode = AddrMode; + ExtAddrMode TestAddrMode = AddrMode; // Add scale to turn X*4+X*3 -> X*7. This could also do things like // [A+B + A*7] -> [B+A*8]. - AddrMode.Scale += Scale; - AddrMode.ScaledReg = ScaleReg; + TestAddrMode.Scale += Scale; + TestAddrMode.ScaledReg = ScaleReg; - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) { - // Okay, we decided that we can add ScaleReg+Scale to AddrMode. Check now - // to see if ScaleReg is actually X+C. If so, we can turn this into adding - // X*Scale + C*Scale to addr mode. - BinaryOperator *BinOp = dyn_cast(ScaleReg); - if (BinOp && BinOp->getOpcode() == Instruction::Add && - isa(BinOp->getOperand(1)) && InputAddrMode.ScaledReg ==0) { - - InputAddrMode.Scale = Scale; - InputAddrMode.ScaledReg = BinOp->getOperand(0); - InputAddrMode.BaseOffs += - cast(BinOp->getOperand(1))->getSExtValue()*Scale; - if (TLI.isLegalAddressingMode(InputAddrMode, AccessTy)) { - AddrModeInsts.push_back(BinOp); - AddrMode = InputAddrMode; - return true; - } - } + // If the new address isn't legal, bail out. + if (!TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) + return false; - // Otherwise, not (x+c)*scale, just return what we have. - return true; + // It was legal, so commit it. + AddrMode = TestAddrMode; + + // Okay, we decided that we can add ScaleReg+Scale to AddrMode. Check now + // to see if ScaleReg is actually X+C. If so, we can turn this into adding + // X*Scale + C*Scale to addr mode. + ConstantInt *CI; Value *AddLHS; + if (match(ScaleReg, m_Add(m_Value(AddLHS), m_ConstantInt(CI)))) { + TestAddrMode.ScaledReg = AddLHS; + TestAddrMode.BaseOffs += CI->getSExtValue()*TestAddrMode.Scale; + + // If this addressing mode is legal, commit it and remember that we folded + // this instruction. + if (TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) { + AddrModeInsts.push_back(cast(ScaleReg)); + AddrMode = TestAddrMode; + } } - // Otherwise, back this attempt out. - AddrMode.Scale -= Scale; - if (AddrMode.Scale == 0) AddrMode.ScaledReg = 0; - - return false; + // Otherwise, not (x+c)*scale, just return what we have. + return true; } @@ -584,7 +583,7 @@ /// operands. static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, ExtAddrMode &AddrMode, - SmallVector &AddrModeInsts, + SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI, unsigned Depth) { @@ -672,8 +671,8 @@ break; } case Instruction::Or: { - ConstantInt *RHS = dyn_cast(AddrInst->getOperand(1)); - if (!RHS) break; + //ConstantInt *RHS = dyn_cast(AddrInst->getOperand(1)); + //if (!RHS) break; // TODO: We can handle "Or Val, Imm" iff this OR is equivalent to an ADD. break; } From sabre at nondot.org Mon Nov 24 22:47:41 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 04:47:41 -0000 Subject: [llvm-commits] [llvm] r60010 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811250447.mAP4lfui008986@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 22:47:41 2008 New Revision: 60010 URL: http://llvm.org/viewvc/llvm-project?rev=60010&view=rev Log: another minor tweak Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60010&r1=60009&r2=60010&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 22:47:41 2008 @@ -532,7 +532,7 @@ /// false if not. static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale, const Type *AccessTy, ExtAddrMode &AddrMode, - SmallVector &AddrModeInsts, + SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI, unsigned Depth) { // If we already have a scale of this value, we can add to it, otherwise, we // need an available scale field. @@ -678,8 +678,7 @@ } case Instruction::Mul: case Instruction::Shl: { - // Can only handle X*C and X << C, and can only handle this when the scale - // field is available. + // Can only handle X*C and X << C. ConstantInt *RHS = dyn_cast(AddrInst->getOperand(1)); if (!RHS) break; int64_t Scale = RHS->getSExtValue(); From sabre at nondot.org Mon Nov 24 23:15:49 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 05:15:49 -0000 Subject: [llvm-commits] [llvm] r60011 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811250515.mAP5FnJi009813@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 24 23:15:49 2008 New Revision: 60011 URL: http://llvm.org/viewvc/llvm-project?rev=60011&view=rev Log: refactor all the constantexpr/instruction handling code out into a new FindMaximalLegalAddressingModeForOperation helper method. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60011&r1=60010&r2=60011&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Mon Nov 24 23:15:49 2008 @@ -573,61 +573,22 @@ return true; } - -/// FindMaximalLegalAddressingMode - If we can, try to merge the computation of -/// Addr into the specified addressing mode. If Addr can't be added to AddrMode -/// this returns false. This assumes that Addr is either a pointer type or -/// intptr_t for the target. -/// -/// This method is used to optimize both load/store and inline asms with memory -/// operands. static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, ExtAddrMode &AddrMode, + SmallVectorImpl &AMI, + const TargetLowering &TLI, + unsigned Depth); + +/// FindMaximalLegalAddressingModeForOperation - Given an instruction or +/// constant expr, see if we can fold the operation into the addressing mode. +/// If so, update the addressing mode and return true, otherwise return false. +static bool +FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode, + const Type *AccessTy, + ExtAddrMode &AddrMode, SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI, unsigned Depth) { - - // If this is a global variable, fold it into the addressing mode if possible. - if (GlobalValue *GV = dyn_cast(Addr)) { - if (AddrMode.BaseGV == 0) { - AddrMode.BaseGV = GV; - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) - return true; - AddrMode.BaseGV = 0; - } - } else if (ConstantInt *CI = dyn_cast(Addr)) { - AddrMode.BaseOffs += CI->getSExtValue(); - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) - return true; - AddrMode.BaseOffs -= CI->getSExtValue(); - } else if (isa(Addr)) { - return true; - } - - // Look through constant exprs and instructions. - unsigned Opcode = ~0U; - User *AddrInst = 0; - if (Instruction *I = dyn_cast(Addr)) { - Opcode = I->getOpcode(); - AddrInst = I; - } else if (ConstantExpr *CE = dyn_cast(Addr)) { - Opcode = CE->getOpcode(); - AddrInst = CE; - } - - // Limit recursion to avoid exponential behavior. - if (Depth == 5) { AddrInst = 0; Opcode = ~0U; } - - // If this is really an instruction, add it to our list of related - // instructions. - if (Instruction *I = dyn_cast_or_null(AddrInst)) - AddrModeInsts.push_back(I); - -#if 0 - if (AddrInst && !AddrInst->hasOneUse()) - ; - else -#endif switch (Opcode) { case Instruction::PtrToInt: // PtrToInt is always a noop, as we know that the int type is pointer sized. @@ -653,18 +614,18 @@ FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, AddrMode, AddrModeInsts, TLI, Depth+1)) return true; - + // Restore the old addr mode info. AddrMode = BackupAddrMode; AddrModeInsts.resize(OldSize); - + // Otherwise this was over-aggressive. Try merging in the LHS then the RHS. if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, AddrMode, AddrModeInsts, TLI, Depth+1) && FindMaximalLegalAddressingMode(AddrInst->getOperand(1), AccessTy, AddrMode, AddrModeInsts, TLI, Depth+1)) return true; - + // Otherwise we definitely can't merge the ADD in. AddrMode = BackupAddrMode; AddrModeInsts.resize(OldSize); @@ -684,7 +645,7 @@ int64_t Scale = RHS->getSExtValue(); if (Opcode == Instruction::Shl) Scale = 1 << Scale; - + if (TryMatchingScaledValue(AddrInst->getOperand(0), Scale, AccessTy, AddrMode, AddrModeInsts, TLI, Depth)) return true; @@ -695,7 +656,7 @@ // one variable offset. int VariableOperand = -1; unsigned VariableScale = 0; - + int64_t ConstantOffset = 0; const TargetData *TD = TLI.getTargetData(); gep_type_iterator GTI = gep_type_begin(AddrInst); @@ -703,7 +664,7 @@ if (const StructType *STy = dyn_cast(*GTI)) { const StructLayout *SL = TD->getStructLayout(STy); unsigned Idx = - cast(AddrInst->getOperand(i))->getZExtValue(); + cast(AddrInst->getOperand(i))->getZExtValue(); ConstantOffset += SL->getElementOffset(Idx); } else { uint64_t TypeSize = TD->getABITypeSize(GTI.getIndexedType()); @@ -715,18 +676,18 @@ VariableOperand = -2; break; } - + // Remember the variable index. VariableOperand = i; VariableScale = TypeSize; } } } - + // If the GEP had multiple variable indices, punt. if (VariableOperand == -2) break; - + // A common case is for the GEP to only do a constant offset. In this case, // just add it to the disp field and check validity. if (VariableOperand == -1) { @@ -751,14 +712,14 @@ AddrMode.BaseReg = AddrInst->getOperand(0); SetBaseReg = true; } - + // See if the scale amount is valid for this target. AddrMode.BaseOffs += ConstantOffset; if (TryMatchingScaledValue(AddrInst->getOperand(VariableOperand), VariableScale, AccessTy, AddrMode, AddrModeInsts, TLI, Depth)) { if (!SetBaseReg) return true; - + // If this match succeeded, we know that we can form an address with the // GepBase as the basereg. See if we can match *more*. AddrMode.HasBaseReg = false; @@ -773,7 +734,7 @@ AddrMode.BaseReg = AddrInst->getOperand(0); return true; } - + AddrMode.BaseOffs -= ConstantOffset; if (SetBaseReg) { AddrMode.HasBaseReg = false; @@ -783,12 +744,54 @@ break; } } + return false; +} - if (Instruction *I = dyn_cast_or_null(AddrInst)) { - assert(AddrModeInsts.back() == I && "Stack imbalance"); I = I; - AddrModeInsts.pop_back(); +/// FindMaximalLegalAddressingMode - If we can, try to merge the computation of +/// Addr into the specified addressing mode. If Addr can't be added to AddrMode +/// this returns false. This assumes that Addr is either a pointer type or +/// intptr_t for the target. +/// +/// This method is used to optimize both load/store and inline asms with memory +/// operands. +static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, + ExtAddrMode &AddrMode, + SmallVectorImpl &AddrModeInsts, + const TargetLowering &TLI, + unsigned Depth) { + if (ConstantInt *CI = dyn_cast(Addr)) { + // Fold in immediates if legal for the target. + AddrMode.BaseOffs += CI->getSExtValue(); + if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + return true; + AddrMode.BaseOffs -= CI->getSExtValue(); + } else if (GlobalValue *GV = dyn_cast(Addr)) { + // If this is a global variable, fold it into the addressing mode if possible. + if (AddrMode.BaseGV == 0) { + AddrMode.BaseGV = GV; + if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) + return true; + AddrMode.BaseGV = 0; + } + } else if (Instruction *I = dyn_cast(Addr)) { + if (Depth < 5 && // Limit recursion to avoid exponential behavior. + FindMaximalLegalAddressingModeForOperation(I, I->getOpcode(), + AccessTy, AddrMode, + AddrModeInsts, TLI, Depth)) { + AddrModeInsts.push_back(I); + return true; + } + } else if (ConstantExpr *CE = dyn_cast(Addr)) { + if (Depth < 5 && // Limit recursion to avoid exponential behavior. + FindMaximalLegalAddressingModeForOperation(CE, CE->getOpcode(), + AccessTy, AddrMode, + AddrModeInsts, TLI, Depth)) + return true; + } else if (isa(Addr)) { + return true; } + // Worse case, the target should support [reg] addressing modes. :) if (!AddrMode.HasBaseReg) { AddrMode.HasBaseReg = true; From sabre at nondot.org Tue Nov 25 01:09:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 07:09:13 -0000 Subject: [llvm-commits] [llvm] r60012 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811250709.mAP79EmZ013377@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 01:09:13 2008 New Revision: 60012 URL: http://llvm.org/viewvc/llvm-project?rev=60012&view=rev Log: significantly refactor all the addressing mode matching logic into a new AddressingModeMatcher class. This makes it easier to reason about and reduces passing around of stuff, but has no functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60012&r1=60011&r2=60012&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 01:09:13 2008 @@ -53,9 +53,8 @@ bool CanMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const; void EliminateMostlyEmptyBlock(BasicBlock *BB); bool OptimizeBlock(BasicBlock &BB); - bool OptimizeLoadStoreInst(Instruction *I, Value *Addr, - const Type *AccessTy, - DenseMap &SunkAddrs); + bool OptimizeMemoryInst(Instruction *I, Value *Addr, const Type *AccessTy, + DenseMap &SunkAddrs); bool OptimizeInlineAsmInst(Instruction *I, CallSite CS, DenseMap &SunkAddrs); bool OptimizeExtUses(Instruction *I); @@ -486,6 +485,10 @@ } } +//===----------------------------------------------------------------------===// +// Addressing Mode Analysis and Optimization +//===----------------------------------------------------------------------===// + namespace { /// ExtAddrMode - This is an extended version of TargetLowering::AddrMode /// which holds actual Value*'s for register values. @@ -506,7 +509,6 @@ return OS; } - void ExtAddrMode::print(OStream &OS) const { bool NeedPlus = false; OS << "["; @@ -527,13 +529,44 @@ OS << ']'; } -/// TryMatchingScaledValue - Try adding ScaleReg*Scale to the specified -/// addressing mode. Return true if this addr mode is legal for the target, +namespace { +/// AddressingModeMatcher - This class exposes a single public method, which is +/// used to construct a "maximal munch" of the addressing mode for the target +/// specified by TLI for an access to "V" with an access type of AccessTy. This +/// returns the addressing mode that is actually matched by value, but also +/// returns the list of instructions involved in that addressing computation in +/// AddrModeInsts. +class AddressingModeMatcher { + SmallVectorImpl &AddrModeInsts; + const TargetLowering &TLI; + const Type *AccessTy; + ExtAddrMode &AddrMode; + AddressingModeMatcher(SmallVectorImpl &AMI, + const TargetLowering &T, const Type *AT,ExtAddrMode &AM) + : AddrModeInsts(AMI), TLI(T), AccessTy(AT), AddrMode(AM) {} +public: + + static ExtAddrMode Match(Value *V, const Type *AccessTy, + SmallVectorImpl &AddrModeInsts, + const TargetLowering &TLI) { + ExtAddrMode Result; + + bool Success = + AddressingModeMatcher(AddrModeInsts,TLI,AccessTy,Result).MatchAddr(V, 0); + Success = Success; assert(Success && "Couldn't select *anything*?"); + return Result; + } +private: + bool MatchScaledValue(Value *ScaleReg, int64_t Scale); + bool MatchAddr(Value *V, unsigned Depth); + bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth); +}; +} // end anonymous namespace + +/// MatchScaledValue - Try adding ScaleReg*Scale to the current addressing mode. +/// Return true and update AddrMode if this addr mode is legal for the target, /// false if not. -static bool TryMatchingScaledValue(Value *ScaleReg, int64_t Scale, - const Type *AccessTy, ExtAddrMode &AddrMode, - SmallVectorImpl &AddrModeInsts, - const TargetLowering &TLI, unsigned Depth) { +bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale) { // If we already have a scale of this value, we can add to it, otherwise, we // need an available scale field. if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) @@ -566,6 +599,7 @@ if (TLI.isLegalAddressingMode(TestAddrMode, AccessTy)) { AddrModeInsts.push_back(cast(ScaleReg)); AddrMode = TestAddrMode; + return true; } } @@ -573,46 +607,31 @@ return true; } -static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, - ExtAddrMode &AddrMode, - SmallVectorImpl &AMI, - const TargetLowering &TLI, - unsigned Depth); - -/// FindMaximalLegalAddressingModeForOperation - Given an instruction or -/// constant expr, see if we can fold the operation into the addressing mode. -/// If so, update the addressing mode and return true, otherwise return false. -static bool -FindMaximalLegalAddressingModeForOperation(User *AddrInst, unsigned Opcode, - const Type *AccessTy, - ExtAddrMode &AddrMode, - SmallVectorImpl &AddrModeInsts, - const TargetLowering &TLI, - unsigned Depth) { + +/// MatchOperationAddr - Given an instruction or constant expr, see if we can +/// fold the operation into the addressing mode. If so, update the addressing +/// mode and return true, otherwise return false without modifying AddrMode. +bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode, + unsigned Depth) { + // Avoid exponential behavior on extremely deep expression trees. + if (Depth >= 5) return false; + switch (Opcode) { case Instruction::PtrToInt: // PtrToInt is always a noop, as we know that the int type is pointer sized. - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth)) - return true; - break; + return MatchAddr(AddrInst->getOperand(0), Depth); case Instruction::IntToPtr: // This inttoptr is a no-op if the integer type is pointer sized. if (TLI.getValueType(AddrInst->getOperand(0)->getType()) == - TLI.getPointerTy()) { - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth)) - return true; - } - break; + TLI.getPointerTy()) + return MatchAddr(AddrInst->getOperand(0), Depth); + return false; case Instruction::Add: { // Check to see if we can merge in the RHS then the LHS. If so, we win. ExtAddrMode BackupAddrMode = AddrMode; unsigned OldSize = AddrModeInsts.size(); - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(1), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth+1) && - FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth+1)) + if (MatchAddr(AddrInst->getOperand(1), Depth+1) && + MatchAddr(AddrInst->getOperand(0), Depth+1)) return true; // Restore the old addr mode info. @@ -620,10 +639,8 @@ AddrModeInsts.resize(OldSize); // Otherwise this was over-aggressive. Try merging in the LHS then the RHS. - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth+1) && - FindMaximalLegalAddressingMode(AddrInst->getOperand(1), AccessTy, - AddrMode, AddrModeInsts, TLI, Depth+1)) + if (MatchAddr(AddrInst->getOperand(0), Depth+1) && + MatchAddr(AddrInst->getOperand(1), Depth+1)) return true; // Otherwise we definitely can't merge the ADD in. @@ -641,15 +658,12 @@ case Instruction::Shl: { // Can only handle X*C and X << C. ConstantInt *RHS = dyn_cast(AddrInst->getOperand(1)); - if (!RHS) break; + if (!RHS) return false; int64_t Scale = RHS->getSExtValue(); if (Opcode == Instruction::Shl) Scale = 1 << Scale; - if (TryMatchingScaledValue(AddrInst->getOperand(0), Scale, AccessTy, - AddrMode, AddrModeInsts, TLI, Depth)) - return true; - break; + return MatchScaledValue(AddrInst->getOperand(0), Scale); } case Instruction::GetElementPtr: { // Scan the GEP. We check it if it contains constant offsets and at most @@ -664,7 +678,7 @@ if (const StructType *STy = dyn_cast(*GTI)) { const StructLayout *SL = TD->getStructLayout(STy); unsigned Idx = - cast(AddrInst->getOperand(i))->getZExtValue(); + cast(AddrInst->getOperand(i))->getZExtValue(); ConstantOffset += SL->getElementOffset(Idx); } else { uint64_t TypeSize = TD->getABITypeSize(GTI.getIndexedType()); @@ -672,10 +686,8 @@ ConstantOffset += CI->getSExtValue()*TypeSize; } else if (TypeSize) { // Scales of zero don't do anything. // We only allow one variable index at the moment. - if (VariableOperand != -1) { - VariableOperand = -2; - break; - } + if (VariableOperand != -1) + return false; // Remember the variable index. VariableOperand = i; @@ -684,81 +696,70 @@ } } - // If the GEP had multiple variable indices, punt. - if (VariableOperand == -2) - break; - // A common case is for the GEP to only do a constant offset. In this case, // just add it to the disp field and check validity. if (VariableOperand == -1) { AddrMode.BaseOffs += ConstantOffset; if (ConstantOffset == 0 || TLI.isLegalAddressingMode(AddrMode, AccessTy)){ // Check to see if we can fold the base pointer in too. - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, - Depth+1)) - return true; - } - AddrMode.BaseOffs -= ConstantOffset; - } else { - // Check that this has no base reg yet. If so, we won't have a place to - // put the base of the GEP (assuming it is not a null ptr). - bool SetBaseReg = false; - if (AddrMode.HasBaseReg) { - if (!isa(AddrInst->getOperand(0))) - break; - } else { - AddrMode.HasBaseReg = true; - AddrMode.BaseReg = AddrInst->getOperand(0); - SetBaseReg = true; - } - - // See if the scale amount is valid for this target. - AddrMode.BaseOffs += ConstantOffset; - if (TryMatchingScaledValue(AddrInst->getOperand(VariableOperand), - VariableScale, AccessTy, AddrMode, - AddrModeInsts, TLI, Depth)) { - if (!SetBaseReg) return true; - - // If this match succeeded, we know that we can form an address with the - // GepBase as the basereg. See if we can match *more*. - AddrMode.HasBaseReg = false; - AddrMode.BaseReg = 0; - if (FindMaximalLegalAddressingMode(AddrInst->getOperand(0), AccessTy, - AddrMode, AddrModeInsts, TLI, - Depth+1)) + if (MatchAddr(AddrInst->getOperand(0), Depth+1)) return true; - // Strange, shouldn't happen. Restore the base reg and succeed the easy - // way. - AddrMode.HasBaseReg = true; - AddrMode.BaseReg = AddrInst->getOperand(0); - return true; } - AddrMode.BaseOffs -= ConstantOffset; - if (SetBaseReg) { - AddrMode.HasBaseReg = false; - AddrMode.BaseReg = 0; - } + return false; } - break; + + // Save the valid addressing mode in case we can't match. + ExtAddrMode BackupAddrMode = AddrMode; + + // Check that this has no base reg yet. If so, we won't have a place to + // put the base of the GEP (assuming it is not a null ptr). + bool SetBaseReg = true; + if (isa(AddrInst->getOperand(0))) + SetBaseReg = false; // null pointer base doesn't need representation. + else if (AddrMode.HasBaseReg) + return false; // Base register already specified, can't match GEP. + else { + // Otherwise, we'll use the GEP base as the BaseReg. + AddrMode.HasBaseReg = true; + AddrMode.BaseReg = AddrInst->getOperand(0); + } + + // See if the scale and offset amount is valid for this target. + AddrMode.BaseOffs += ConstantOffset; + + // FIXME: If VariableScale = 1, just call MatchAddr recursively? + if (!MatchScaledValue(AddrInst->getOperand(VariableOperand),VariableScale)){ + AddrMode = BackupAddrMode; + return false; + } + + // If we have a null as the base of the GEP, folding in the constant offset + // plus variable scale is all we can do. + if (!SetBaseReg) return true; + + // If this match succeeded, we know that we can form an address with the + // GepBase as the basereg. Match the base pointer of the GEP more + // aggressively by zeroing out BaseReg and rematching. If the base is + // (for example) another GEP, this allows merging in that other GEP into + // the addressing mode we're forming. + AddrMode.HasBaseReg = false; + AddrMode.BaseReg = 0; + bool Success = MatchAddr(AddrInst->getOperand(0), Depth+1); + assert(Success && "MatchAddr should be able to fill in BaseReg!"); + Success=Success; + return true; } } return false; } -/// FindMaximalLegalAddressingMode - If we can, try to merge the computation of -/// Addr into the specified addressing mode. If Addr can't be added to AddrMode -/// this returns false. This assumes that Addr is either a pointer type or -/// intptr_t for the target. +/// MatchAddr - If we can, try to add the value of 'Addr' into the current +/// addressing mode. If Addr can't be added to AddrMode this returns false and +/// leaves AddrMode unmodified. This assumes that Addr is either a pointer type +/// or intptr_t for the target. /// -/// This method is used to optimize both load/store and inline asms with memory -/// operands. -static bool FindMaximalLegalAddressingMode(Value *Addr, const Type *AccessTy, - ExtAddrMode &AddrMode, - SmallVectorImpl &AddrModeInsts, - const TargetLowering &TLI, - unsigned Depth) { +bool AddressingModeMatcher::MatchAddr(Value *Addr, unsigned Depth) { if (ConstantInt *CI = dyn_cast(Addr)) { // Fold in immediates if legal for the target. AddrMode.BaseOffs += CI->getSExtValue(); @@ -766,7 +767,7 @@ return true; AddrMode.BaseOffs -= CI->getSExtValue(); } else if (GlobalValue *GV = dyn_cast(Addr)) { - // If this is a global variable, fold it into the addressing mode if possible. + // If this is a global variable, try to fold it into the addressing mode. if (AddrMode.BaseGV == 0) { AddrMode.BaseGV = GV; if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) @@ -774,24 +775,18 @@ AddrMode.BaseGV = 0; } } else if (Instruction *I = dyn_cast(Addr)) { - if (Depth < 5 && // Limit recursion to avoid exponential behavior. - FindMaximalLegalAddressingModeForOperation(I, I->getOpcode(), - AccessTy, AddrMode, - AddrModeInsts, TLI, Depth)) { + if (MatchOperationAddr(I, I->getOpcode(), Depth)) { AddrModeInsts.push_back(I); return true; } } else if (ConstantExpr *CE = dyn_cast(Addr)) { - if (Depth < 5 && // Limit recursion to avoid exponential behavior. - FindMaximalLegalAddressingModeForOperation(CE, CE->getOpcode(), - AccessTy, AddrMode, - AddrModeInsts, TLI, Depth)) + if (MatchOperationAddr(CE, CE->getOpcode(), Depth)) return true; } else if (isa(Addr)) { + // Null pointer gets folded without affecting the addressing mode. return true; } - // Worse case, the target should support [reg] addressing modes. :) if (!AddrMode.HasBaseReg) { AddrMode.HasBaseReg = true; @@ -817,6 +812,10 @@ } +//===----------------------------------------------------------------------===// +// Memory Optimization +//===----------------------------------------------------------------------===// + /// IsNonLocalValue - Return true if the specified values are defined in a /// different basic block than BB. static bool IsNonLocalValue(Value *V, BasicBlock *BB) { @@ -825,21 +824,22 @@ return false; } -/// OptimizeLoadStoreInst - Load and Store Instructions have often have +/// OptimizeMemoryInst - Load and Store Instructions have often have /// addressing modes that can do significant amounts of computation. As such, /// instruction selection will try to get the load or store to do as much /// computation as possible for the program. The problem is that isel can only /// see within a single block. As such, we sink as much legal addressing mode /// stuff into the block as possible. -bool CodeGenPrepare::OptimizeLoadStoreInst(Instruction *LdStInst, Value *Addr, - const Type *AccessTy, - DenseMap &SunkAddrs) { +/// +/// This method is used to optimize both load/store and inline asms with memory +/// operands. +bool CodeGenPrepare::OptimizeMemoryInst(Instruction *LdStInst, Value *Addr, + const Type *AccessTy, + DenseMap &SunkAddrs) { // Figure out what addressing mode will be built up for this operation. SmallVector AddrModeInsts; - ExtAddrMode AddrMode; - bool Success = FindMaximalLegalAddressingMode(Addr, AccessTy, AddrMode, - AddrModeInsts, *TLI, 0); - Success = Success; assert(Success && "Couldn't select *anything*?"); + ExtAddrMode AddrMode = + AddressingModeMatcher::Match(Addr, AccessTy, AddrModeInsts, *TLI); // Check to see if any of the instructions supersumed by this addr mode are // non-local to I's BB. @@ -940,7 +940,7 @@ } /// OptimizeInlineAsmInst - If there are any memory operands, use -/// OptimizeLoadStoreInt to sink their address computing into the block when +/// OptimizeMemoryInst to sink their address computing into the block when /// possible / profitable. bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS, DenseMap &SunkAddrs) { @@ -981,8 +981,7 @@ if (OpInfo.ConstraintType == TargetLowering::C_Memory && OpInfo.isIndirect) { Value *OpVal = OpInfo.CallOperandVal; - MadeChange |= OptimizeLoadStoreInst(I, OpVal, OpVal->getType(), - SunkAddrs); + MadeChange |= OptimizeMemoryInst(I, OpVal, OpVal->getType(), SunkAddrs); } } @@ -1111,13 +1110,13 @@ MadeChange |= OptimizeCmpExpression(CI); } else if (LoadInst *LI = dyn_cast(I)) { if (TLI) - MadeChange |= OptimizeLoadStoreInst(I, I->getOperand(0), LI->getType(), - SunkAddrs); + MadeChange |= OptimizeMemoryInst(I, I->getOperand(0), LI->getType(), + SunkAddrs); } else if (StoreInst *SI = dyn_cast(I)) { if (TLI) - MadeChange |= OptimizeLoadStoreInst(I, SI->getOperand(1), - SI->getOperand(0)->getType(), - SunkAddrs); + MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1), + SI->getOperand(0)->getType(), + SunkAddrs); } else if (GetElementPtrInst *GEPI = dyn_cast(I)) { if (GEPI->hasAllZeroIndices()) { /// The GEP operand must be a pointer, so must its result -> BitCast From sabre at nondot.org Tue Nov 25 01:25:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 07:25:26 -0000 Subject: [llvm-commits] [llvm] r60013 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811250725.mAP7PQcc014178@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 01:25:26 2008 New Revision: 60013 URL: http://llvm.org/viewvc/llvm-project?rev=60013&view=rev Log: Teach MatchScaledValue to handle Scales by 1 with MatchAddr (which can recursively match things) and scales by 0 by ignoring them. This triggers once in 403.gcc, saving 1 (!!!!) instruction in the whole huge app. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60013&r1=60012&r2=60013&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 01:25:26 2008 @@ -557,7 +557,7 @@ return Result; } private: - bool MatchScaledValue(Value *ScaleReg, int64_t Scale); + bool MatchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth); bool MatchAddr(Value *V, unsigned Depth); bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth); }; @@ -566,7 +566,17 @@ /// MatchScaledValue - Try adding ScaleReg*Scale to the current addressing mode. /// Return true and update AddrMode if this addr mode is legal for the target, /// false if not. -bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale) { +bool AddressingModeMatcher::MatchScaledValue(Value *ScaleReg, int64_t Scale, + unsigned Depth) { + // If Scale is 1, then this is the same as adding ScaleReg to the addressing + // mode. Just process that directly. + if (Scale == 1) + return MatchAddr(ScaleReg, Depth); + + // If the scale is 0, it takes nothing to add this. + if (Scale == 0) + return true; + // If we already have a scale of this value, we can add to it, otherwise, we // need an available scale field. if (AddrMode.Scale != 0 && AddrMode.ScaledReg != ScaleReg) @@ -663,7 +673,7 @@ if (Opcode == Instruction::Shl) Scale = 1 << Scale; - return MatchScaledValue(AddrInst->getOperand(0), Scale); + return MatchScaledValue(AddrInst->getOperand(0), Scale, Depth); } case Instruction::GetElementPtr: { // Scan the GEP. We check it if it contains constant offsets and at most @@ -728,8 +738,8 @@ // See if the scale and offset amount is valid for this target. AddrMode.BaseOffs += ConstantOffset; - // FIXME: If VariableScale = 1, just call MatchAddr recursively? - if (!MatchScaledValue(AddrInst->getOperand(VariableOperand),VariableScale)){ + if (!MatchScaledValue(AddrInst->getOperand(VariableOperand), VariableScale, + Depth)) { AddrMode = BackupAddrMode; return false; } From isanbard at gmail.com Tue Nov 25 02:12:20 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 08:12:20 -0000 Subject: [llvm-commits] [llvm] r60014 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811250812.mAP8CK2B015555@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 02:12:19 2008 New Revision: 60014 URL: http://llvm.org/viewvc/llvm-project?rev=60014&view=rev Log: Hacker's Delight says, "Signed integer overflow of addition occurs if and only if the operands have the same sign and the sum has sign opposite to that of the operands." Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60014&r1=60013&r2=60014&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Nov 25 02:12:19 2008 @@ -4170,7 +4170,53 @@ break; } - case ISD::SADDO: + case ISD::SADDO: { + MVT VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action not supported for this op yet!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Op, DAG); + if (Result.getNode()) break; + // FALLTHROUGH + case TargetLowering::Legal: { + SDValue LHS = LegalizeOp(Node->getOperand(0)); + SDValue RHS = LegalizeOp(Node->getOperand(1)); + + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + MVT SType = Node->getValueType(0); + MVT OType = Node->getValueType(1); + + SDValue Zero = DAG.getConstant(0, OType); + + SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); + SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); + SDValue And1 = DAG.getNode(ISD::AND, OType, LHSPos, RHSPos); + + And1 = DAG.getNode(ISD::AND, OType, And1, + DAG.getSetCC(OType, Sum, Zero, ISD::SETLT)); + + SDValue LHSNeg = DAG.getSetCC(OType, LHS, Zero, ISD::SETLT); + SDValue RHSNeg = DAG.getSetCC(OType, RHS, Zero, ISD::SETLT); + SDValue And2 = DAG.getNode(ISD::AND, OType, LHSNeg, RHSNeg); + + And2 = DAG.getNode(ISD::AND, OType, And2, + DAG.getSetCC(OType, Sum, Zero, ISD::SETGE)); + + SDValue Cmp = DAG.getNode(ISD::OR, OType, And1, And2); + + MVT ValueVTs[] = { LHS.getValueType(), OType }; + SDValue Ops[] = { Sum, Cmp }; + + Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); + SDNode *RNode = Result.getNode(); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); + break; + } + } + + break; + } case ISD::UADDO: { MVT VT = Node->getValueType(0); switch (TLI.getOperationAction(Node->getOpcode(), VT)) { @@ -4185,9 +4231,7 @@ SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); MVT OType = Node->getValueType(1); - SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, - (Node->getOpcode() == ISD::SADDO) ? - ISD::SETLT : ISD::SETULT); + SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, ISD::SETULT); MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; From isanbard at gmail.com Tue Nov 25 02:13:21 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 08:13:21 -0000 Subject: [llvm-commits] [llvm] r60015 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811250813.mAP8DL6S015590@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 02:13:20 2008 New Revision: 60015 URL: http://llvm.org/viewvc/llvm-project?rev=60015&view=rev Log: Get rid of unused variable. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60015&r1=60014&r2=60015&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Nov 25 02:13:20 2008 @@ -4183,7 +4183,6 @@ SDValue RHS = LegalizeOp(Node->getOperand(1)); SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); - MVT SType = Node->getValueType(0); MVT OType = Node->getValueType(1); SDValue Zero = DAG.getConstant(0, OType); From isanbard at gmail.com Tue Nov 25 02:19:22 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 08:19:22 -0000 Subject: [llvm-commits] [llvm] r60016 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811250819.mAP8JM06015754@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 02:19:22 2008 New Revision: 60016 URL: http://llvm.org/viewvc/llvm-project?rev=60016&view=rev Log: Now with the correct type for the 0. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60016&r1=60015&r2=60016&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Nov 25 02:19:22 2008 @@ -4185,7 +4185,7 @@ SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); MVT OType = Node->getValueType(1); - SDValue Zero = DAG.getConstant(0, OType); + SDValue Zero = DAG.getConstant(0, LHS.getValueType()); SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); From baldrick at free.fr Tue Nov 25 03:00:53 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 Nov 2008 10:00:53 +0100 Subject: [llvm-commits] [llvm] r60014 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: <200811250812.mAP8CK2B015555@zion.cs.uiuc.edu> References: <200811250812.mAP8CK2B015555@zion.cs.uiuc.edu> Message-ID: <200811251000.54181.baldrick@free.fr> Hi Bill, > + SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); > + SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); > + SDValue And1 = DAG.getNode(ISD::AND, OType, LHSPos, RHSPos); can't you just do: overflowed = (LHSPos == RHSPos) && (LHSPos != SumPos)? (Positive means >= 0). Ciao, Duncan. From isanbard at gmail.com Tue Nov 25 04:07:02 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 02:07:02 -0800 Subject: [llvm-commits] [llvm] r60014 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: <200811251000.54181.baldrick@free.fr> References: <200811250812.mAP8CK2B015555@zion.cs.uiuc.edu> <200811251000.54181.baldrick@free.fr> Message-ID: <463A66EE-2E3B-4124-A0A1-8B17E9DDA73E@gmail.com> Yeah. I was going to optimize it later. But got a bit lazy. -bw On Nov 25, 2008, at 1:00 AM, Duncan Sands wrote: > Hi Bill, > >> + SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); >> + SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); >> + SDValue And1 = DAG.getNode(ISD::AND, OType, LHSPos, RHSPos); > > can't you just do: overflowed = (LHSPos == RHSPos) && (LHSPos != > SumPos)? > (Positive means >= 0). > > Ciao, > > Duncan. From nunoplopes at sapo.pt Tue Nov 25 09:58:04 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Tue, 25 Nov 2008 15:58:04 -0000 Subject: [llvm-commits] [llvm] r60030 - /llvm/trunk/docs/TestingGuide.html Message-ID: <200811251558.mAPFw5gh010529@zion.cs.uiuc.edu> Author: nlopes Date: Tue Nov 25 09:57:52 2008 New Revision: 60030 URL: http://llvm.org/viewvc/llvm-project?rev=60030&view=rev Log: add info about how to run the tests with valgrind Modified: llvm/trunk/docs/TestingGuide.html Modified: llvm/trunk/docs/TestingGuide.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TestingGuide.html?rev=60030&r1=60029&r2=60030&view=diff ============================================================================== --- llvm/trunk/docs/TestingGuide.html (original) +++ llvm/trunk/docs/TestingGuide.html Tue Nov 25 09:57:52 2008 @@ -228,6 +228,15 @@
    +

    To run the tests with Valgrind (Memcheck by default), just append +VG=1 to the commands above, e.g.:

    + +
    +
    +% gmake check VG=1
    +
    +
    + From scottm at aero.org Tue Nov 25 11:29:47 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 25 Nov 2008 17:29:47 -0000 Subject: [llvm-commits] [llvm] r60034 - in /llvm/trunk: lib/Target/CellSPU/SPUISelDAGToDAG.cpp test/CodeGen/CellSPU/stores.ll Message-ID: <200811251729.mAPHTmVM014260@zion.cs.uiuc.edu> Author: pingbak Date: Tue Nov 25 11:29:43 2008 New Revision: 60034 URL: http://llvm.org/viewvc/llvm-project?rev=60034&view=rev Log: CellSPU: (a) Remove conditionally removed code in SelectXAddr. Basically, hope for the best that the A-form and D-form address predicates catch everything before the code decides to emit a X-form address. (b) Expand vector store test cases to include the usual suspects. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/test/CodeGen/CellSPU/stores.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=60034&r1=60033&r2=60034&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Tue Nov 25 11:29:43 2008 @@ -591,33 +591,11 @@ SDValue &Index) { if (!SelectAFormAddr(Op, N, Base, Index) && !SelectDFormAddr(Op, N, Base, Index)) { -#if 0 - // Default form of a X-form address is r(r) in operands 0 and 1: - SDValue Op0 = N.getOperand(0); - SDValue Op1 = N.getOperand(1); - - if ((Op0.getOpcode() == ISD::Register - || Op.getOpcode() == ISD::CopyFromReg) - && (Op1.getOpcode() == ISD::Register - || Op.getOpcode() == ISD::CopyFromReg)) { - if (Op.getOpcode() == ISD::Register) - Base = Op0; - else - Base = Op0.getOperand(1); - - if (Op1.getOpcode() == ISD::Register) - Index = Op1; - else - Index = Op1.getOperand(1); - - return true; - } -#else - // All else fails, punt and use an X-form address: + // If the address is neither A-form or D-form, punt and use an X-form + // address: Base = N.getOperand(0); Index = N.getOperand(1); return true; -#endif } return false; Modified: llvm/trunk/test/CodeGen/CellSPU/stores.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/stores.ll?rev=60034&r1=60033&r2=60034&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/stores.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/stores.ll Tue Nov 25 11:29:43 2008 @@ -1,13 +1,75 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s -; RUN: grep {stqd.*0(\$3)} %t1.s | count 1 -; RUN: grep {stqd.*16(\$3)} %t1.s | count 1 -; RUN: grep 16256 %t1.s | count 1 -; RUN: grep 16384 %t1.s | count 1 +; RUN: grep {stqd.*0(\$3)} %t1.s | count 4 +; RUN: grep {stqd.*16(\$3)} %t1.s | count 4 +; RUN: grep 16256 %t1.s | count 2 +; RUN: grep 16384 %t1.s | count 1 +; RUN: grep {shli.*, 4} %t1.s | count 4 +; RUN: grep stqx %t1.s | count 4 ; ModuleID = 'stores.bc' target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" +define void @store_v16i8_1(<16 x i8>* %a) nounwind { +entry: + store <16 x i8> < i8 1, i8 2, i8 1, i8 1, i8 1, i8 2, i8 1, i8 1, i8 1, i8 2, i8 1, i8 1, i8 1, i8 2, i8 1, i8 1 >, <16 x i8>* %a + ret void +} + +define void @store_v16i8_2(<16 x i8>* %a) nounwind { +entry: + %arrayidx = getelementptr <16 x i8>* %a, i32 1 + store <16 x i8> < i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2 >, <16 x i8>* %arrayidx + ret void +} + +define void @store_v16i8_3(<16 x i8>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <16 x i8>* %a, i32 %i + store <16 x i8> < i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1 >, <16 x i8>* %arrayidx + ret void +} + +define void @store_v8i16_1(<8 x i16>* %a) nounwind { +entry: + store <8 x i16> < i16 1, i16 2, i16 1, i16 1, i16 1, i16 2, i16 1, i16 1 >, <8 x i16>* %a + ret void +} + +define void @store_v8i16_2(<8 x i16>* %a) nounwind { +entry: + %arrayidx = getelementptr <8 x i16>* %a, i16 1 + store <8 x i16> < i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2 >, <8 x i16>* %arrayidx + ret void +} + +define void @store_v8i16_3(<8 x i16>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <8 x i16>* %a, i32 %i + store <8 x i16> < i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1 >, <8 x i16>* %arrayidx + ret void +} + +define void @store_v4i32_1(<4 x i32>* %a) nounwind { +entry: + store <4 x i32> < i32 1, i32 2, i32 1, i32 1 >, <4 x i32>* %a + ret void +} + +define void @store_v4i32_2(<4 x i32>* %a) nounwind { +entry: + %arrayidx = getelementptr <4 x i32>* %a, i32 1 + store <4 x i32> < i32 2, i32 2, i32 2, i32 2 >, <4 x i32>* %arrayidx + ret void +} + +define void @store_v4i32_3(<4 x i32>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <4 x i32>* %a, i32 %i + store <4 x i32> < i32 1, i32 1, i32 1, i32 1 >, <4 x i32>* %arrayidx + ret void +} + define void @store_v4f32_1(<4 x float>* %a) nounwind { entry: store <4 x float> < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >, <4 x float>* %a @@ -20,3 +82,10 @@ store <4 x float> < float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00 >, <4 x float>* %arrayidx ret void } + +define void @store_v4f32_3(<4 x float>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <4 x float>* %a, i32 %i + store <4 x float> < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >, <4 x float>* %arrayidx + ret void +} From sabre at nondot.org Tue Nov 25 12:34:50 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 Nov 2008 18:34:50 -0000 Subject: [llvm-commits] [llvm] r60039 - /llvm/trunk/docs/ProgrammersManual.html Message-ID: <200811251834.mAPIYoDv017646@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 12:34:50 2008 New Revision: 60039 URL: http://llvm.org/viewvc/llvm-project?rev=60039&view=rev Log: This method got renamed, thanks to Mattias Holm for pointing this out. Modified: llvm/trunk/docs/ProgrammersManual.html Modified: llvm/trunk/docs/ProgrammersManual.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ProgrammersManual.html?rev=60039&r1=60038&r2=60039&view=diff ============================================================================== --- llvm/trunk/docs/ProgrammersManual.html (original) +++ llvm/trunk/docs/ProgrammersManual.html Tue Nov 25 12:34:50 2008 @@ -3169,7 +3169,7 @@ will automatically be inserted into that module's list of functions.

    -
  • bool isExternal() +
  • bool isDeclaration()

    Return whether or not the Function has a body defined. If the function is "external", it does not have a body, and thus must be resolved From dpatel at apple.com Tue Nov 25 12:41:17 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Nov 2008 18:41:17 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60040 - /llvm-gcc-4.2/trunk/gcc/config/darwin.h Message-ID: <200811251841.mAPIfH70017927@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 25 12:41:17 2008 New Revision: 60040 URL: http://llvm.org/viewvc/llvm-project?rev=60040&view=rev Log: %(darwin_dsymutil) was removed for some reason. Directly invooke dsymutil. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.h?rev=60040&r1=60039&r2=60040&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.h Tue Nov 25 12:41:17 2008 @@ -357,9 +357,10 @@ %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}}\n\ %{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ "/* APPLE LOCAL end mainline 4.3 2006-10-31 4370146 */"\ -"/* LLVM LOCAL do not use dsymutil with -O1 or higher */"\ %{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm: \ - %{!O: %{!O1: %{!O2: %{!O3: %{!O4: %{!Os: %(darwin_dsymutil) }}}}}}}}}}}}}}" + %{!O: %{!O1: %{!O2: %{!O3: %{!O4: %{!Os: \ +"/* LLVM LOCAL do not use dsymutil with -O1 or higher */"\ + %{g*:%{!gstabs*:%{!g0: dsymutil %{o*:%*}%{!o:a.out}}}}}}}}}}}}}}}}}}" #else #define LINK_COMMAND_SPEC "\ %{!fdump=*:%{!fsyntax-only:%{!precomp:%{!c:%{!M:%{!MM:%{!E:%{!S:\ From clattner at apple.com Tue Nov 25 12:43:42 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Nov 2008 10:43:42 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r60004 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp In-Reply-To: <200811250234.mAP2YoTW004695@zion.cs.uiuc.edu> References: <200811250234.mAP2YoTW004695@zion.cs.uiuc.edu> Message-ID: <0C437144-13F9-40AD-80AE-A897727C1049@apple.com> On Nov 24, 2008, at 6:34 PM, Devang Patel wrote: > Author: dpatel > Date: Mon Nov 24 20:34:49 2008 > New Revision: 60004 > > URL: http://llvm.org/viewvc/llvm-project?rev=60004&view=rev > Log: > > Disable loop-index-split for now. > It has a bug that is encouraging me to rewrite large portion of this > pass. Should this also be disabled from opt? -Chris > > > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=60004&r1=60003&r2=60004&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 20:34:49 2008 > @@ -444,7 +444,7 @@ > PM->add(createLoopRotatePass()); // Rotate Loop > PM->add(createLICMPass()); // Hoist loop > invariants > PM->add(createLoopUnswitchPass(optimize_size ? true : false)); > - PM->add(createLoopIndexSplitPass()); // Split loop index > + // PM->add(createLoopIndexSplitPass()); // Split loop > index > PM->add(createInstructionCombiningPass()); > PM->add(createIndVarSimplifyPass()); // Canonicalize > indvars > PM->add(createLoopDeletionPass()); // Delete dead loops > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Tue Nov 25 12:53:55 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 25 Nov 2008 18:53:55 -0000 Subject: [llvm-commits] [llvm] r60041 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200811251853.mAPIrtVE018637@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 25 12:53:54 2008 New Revision: 60041 URL: http://llvm.org/viewvc/llvm-project?rev=60041&view=rev Log: Suppress warnings. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60041&r1=60040&r2=60041&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Tue Nov 25 12:53:54 2008 @@ -418,11 +418,11 @@ if (NewReg == LastNewReg[AntiDepReg]) continue; // If NewReg is dead and NewReg's most recent def is not before // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. - assert(((KillIndices[AntiDepReg] == -1) != (DefIndices[AntiDepReg] == -1)) && + assert(((KillIndices[AntiDepReg] == -1u) != (DefIndices[AntiDepReg] == -1u)) && "Kill and Def maps aren't consistent for AntiDepReg!"); - assert(((KillIndices[NewReg] == -1) != (DefIndices[NewReg] == -1)) && + assert(((KillIndices[NewReg] == -1u) != (DefIndices[NewReg] == -1u)) && "Kill and Def maps aren't consistent for NewReg!"); - if (KillIndices[NewReg] == -1 && + if (KillIndices[NewReg] == -1u && KillIndices[AntiDepReg] <= DefIndices[NewReg]) { DOUT << "Breaking anti-dependence edge on reg " << AntiDepReg << " with reg " << NewReg << "!\n"; @@ -469,17 +469,17 @@ // a live range. Defs.erase(Reg); // It wasn't previously live but now it is, this is a kill. - if (KillIndices[Reg] == -1) { + if (KillIndices[Reg] == -1u) { KillIndices[Reg] = Count; - DefIndices[Reg] = -1; + DefIndices[Reg] = -1u; } // Repeat, for all aliases. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; Defs.erase(AliasReg); - if (KillIndices[AliasReg] == -1) { + if (KillIndices[AliasReg] == -1u) { KillIndices[AliasReg] = Count; - DefIndices[AliasReg] = -1; + DefIndices[AliasReg] = -1u; } } } From dpatel at apple.com Tue Nov 25 12:54:25 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 Nov 2008 10:54:25 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r60004 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp In-Reply-To: <0C437144-13F9-40AD-80AE-A897727C1049@apple.com> References: <200811250234.mAP2YoTW004695@zion.cs.uiuc.edu> <0C437144-13F9-40AD-80AE-A897727C1049@apple.com> Message-ID: <40624AAE-3ED4-44C3-B505-24C5C53BEDD4@apple.com> On Nov 25, 2008, at 10:43 AM, Chris Lattner wrote: > > On Nov 24, 2008, at 6:34 PM, Devang Patel wrote: > >> Author: dpatel >> Date: Mon Nov 24 20:34:49 2008 >> New Revision: 60004 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60004&view=rev >> Log: >> >> Disable loop-index-split for now. >> It has a bug that is encouraging me to rewrite large portion of this >> pass. > > Should this also be disabled from opt? I intend to fix loop-index-split today. If I can't make it then I'll disable it from opt before the end of the day. Hey, the bug is a major oops and I'm kind of astonished that nightly testers did not catch it. But we should fix it soon. int main() { int i; for (i =0; i < 6; ++i) if (i < 3) printf ("%d < 3\n", i); else printf ("%d >= 3\n", i); return 0; } prints 0 < 3 1 < 3 2 < 3 3 < 3 3 >= 3 4 >= 3 5 >= 3 - Devang > > > -Chris > >> >> >> >> Modified: >> llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=60004&r1=60003&r2=60004&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Nov 24 20:34:49 2008 >> @@ -444,7 +444,7 @@ >> PM->add(createLoopRotatePass()); // Rotate Loop >> PM->add(createLICMPass()); // Hoist loop >> invariants >> PM->add(createLoopUnswitchPass(optimize_size ? true : false)); >> - PM->add(createLoopIndexSplitPass()); // Split loop index >> + // PM->add(createLoopIndexSplitPass()); // Split loop >> index >> PM->add(createInstructionCombiningPass()); >> PM->add(createIndVarSimplifyPass()); // Canonicalize >> indvars >> PM->add(createLoopDeletionPass()); // Delete dead loops >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits - Devang From evan.cheng at apple.com Tue Nov 25 13:00:29 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Nov 2008 19:00:29 -0000 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll Message-ID: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 25 13:00:29 2008 New Revision: 60042 URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev Log: convertToSignExtendedInteger should return opInvalidOp instead of asserting if sematics of float does not allow arithmetics. Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 @@ -117,6 +117,11 @@ && "Compile-time arithmetic does not support these semantics"); } + static inline bool + isArithmeticOk(const llvm::fltSemantics &semantics) { + return semantics.arithmeticOK; + } + /* Return the value of a decimal exponent of the form [+-]ddddddd. @@ -1787,7 +1792,8 @@ const integerPart *src; unsigned int dstPartsCount, truncatedBits; - assertArithmeticOK(*semantics); + if (!isArithmeticOk(*semantics)) + return opInvalidOp; *isExact = false; Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll (added) +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll Tue Nov 25 13:00:29 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -indvars + +define void @t() nounwind { +entry: + br label %bb23.i91 + +bb23.i91: ; preds = %bb23.i91, %entry + %result.0.i89 = phi ppc_fp128 [ 0xM00000000000000000000000000000000, %entry ], [ %0, %bb23.i91 ] ; [#uses=2] + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; [#uses=1] + br label %bb23.i91 +} From clattner at apple.com Tue Nov 25 13:14:49 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Nov 2008 11:14:49 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> Message-ID: <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: > Author: evancheng > Date: Tue Nov 25 13:00:29 2008 > New Revision: 60042 > > URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev > Log: > convertToSignExtendedInteger should return opInvalidOp instead of > asserting if sematics of float does not allow arithmetics. Are you sure? This behavior was consistent with all the other methods. Usually the client has to check to see if it is hacking on ppc long double and not do the optimization in question. -Chris > > > Added: > llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- > APFloatAssert.ll > Modified: > llvm/trunk/lib/Support/APFloat.cpp > > Modified: llvm/trunk/lib/Support/APFloat.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Support/APFloat.cpp (original) > +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 > @@ -117,6 +117,11 @@ > && "Compile-time arithmetic does not support these > semantics"); > } > > + static inline bool > + isArithmeticOk(const llvm::fltSemantics &semantics) { > + return semantics.arithmeticOK; > + } > + > /* Return the value of a decimal exponent of the form > [+-]ddddddd. > > @@ -1787,7 +1792,8 @@ > const integerPart *src; > unsigned int dstPartsCount, truncatedBits; > > - assertArithmeticOK(*semantics); > + if (!isArithmeticOk(*semantics)) > + return opInvalidOp; > > *isExact = false; > > > Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- > APFloatAssert.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- > APFloatAssert.ll (added) > +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- > APFloatAssert.ll Tue Nov 25 13:00:29 2008 > @@ -0,0 +1,11 @@ > +; RUN: llvm-as < %s | opt -indvars > + > +define void @t() nounwind { > +entry: > + br label %bb23.i91 > + > +bb23.i91: ; preds = %bb23.i91, %entry > + %result.0.i89 = phi ppc_fp128 > [ 0xM00000000000000000000000000000000, %entry ], [ %0, > %bb23.i91 ] ; [#uses=2] > + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; > [#uses=1] > + br label %bb23.i91 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Nov 25 13:40:19 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 19:40:19 -0000 Subject: [llvm-commits] [llvm] r60043 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811251940.mAPJeJp3020542@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 13:40:17 2008 New Revision: 60043 URL: http://llvm.org/viewvc/llvm-project?rev=60043&view=rev Log: A simplification for checking whether the signs of the operands and sum differ. Thanks, Duncan. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60043&r1=60042&r2=60043&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Nov 25 13:40:17 2008 @@ -4187,21 +4187,20 @@ SDValue Zero = DAG.getConstant(0, LHS.getValueType()); - SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); - SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); - SDValue And1 = DAG.getNode(ISD::AND, OType, LHSPos, RHSPos); + // LHSSign -> LHS >= 0 + // RHSSign -> RHS >= 0 + // SumSign -> Sum >= 0 + // + // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) + // + SDValue LHSSign = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); + SDValue RHSSign = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); + SDValue SignsEq = DAG.getSetCC(OType, LHSSign, RHSSign, ISD::SETEQ); - And1 = DAG.getNode(ISD::AND, OType, And1, - DAG.getSetCC(OType, Sum, Zero, ISD::SETLT)); + SDValue SumSign = DAG.getSetCC(OType, Sum, Zero, ISD::SETGE); + SDValue SumSignNE = DAG.getSetCC(OType, LHSSign, SumSign, ISD::SETNE); - SDValue LHSNeg = DAG.getSetCC(OType, LHS, Zero, ISD::SETLT); - SDValue RHSNeg = DAG.getSetCC(OType, RHS, Zero, ISD::SETLT); - SDValue And2 = DAG.getNode(ISD::AND, OType, LHSNeg, RHSNeg); - - And2 = DAG.getNode(ISD::AND, OType, And2, - DAG.getSetCC(OType, Sum, Zero, ISD::SETGE)); - - SDValue Cmp = DAG.getNode(ISD::OR, OType, And1, And2); + SDValue Cmp = DAG.getNode(ISD::AND, OType, SignsEq, SumSignNE); MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; From foldr at codedgers.com Tue Nov 25 15:34:02 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:34:02 -0000 Subject: [llvm-commits] [llvm] r60044 - /llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Message-ID: <200811252134.mAPLY2Dg024575@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:34:01 2008 New Revision: 60044 URL: http://llvm.org/viewvc/llvm-project?rev=60044&view=rev Log: Document the plugin priority feature. Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=60044&r1=60043&r2=60044&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Tue Nov 25 15:34:01 2008 @@ -121,7 +121,7 @@ $ mv Simple.td MyPlugin.td -Note that the plugin source directory should be placed under +Note that the plugin source directory must be placed under ``$LLVMC_DIR/plugins`` to make use of the existing build infrastructure. To build a version of the LLVMC executable called ``mydriver`` with your plugin compiled in, use the following command:: @@ -129,13 +129,6 @@ $ cd $LLVMC_DIR $ make BUILTIN_PLUGINS=MyPlugin DRIVER_NAME=mydriver -When linking plugins dynamically, you'll usually want a 'bare-bones' -version of LLVMC that has no built-in plugins. It can be compiled with -the following command:: - - $ cd $LLVMC_DIR - $ make BUILTIN_PLUGINS="" - To build your plugin as a dynamic library, just ``cd`` to its source directory and run ``make``. The resulting file will be called ``LLVMC$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case, @@ -146,7 +139,28 @@ $ make $ llvmc2 -load $LLVM_DIR/Release/lib/LLVMCSimple.so -In the future LLVMC will be able to load TableGen files directly. +Sometimes, you will want a 'bare-bones' version of LLVMC that has no +built-in plugins. It can be compiled with the following command:: + + $ cd $LLVMC_DIR + $ make BUILTIN_PLUGINS="" + +How plugins are loaded +====================== + +It is possible for LLVMC plugins to depend on each other. For example, +one can create edges between nodes defined in some other plugin. To +make this work, however, that plugin should be loaded first. To +achieve this, the concept of plugin priority was introduced. By +default, every plugin has priority zero; to specify the priority +explicitly, put the following line in your ``.td`` file:: + + def Priority : PluginPriority<$PRIORITY_VALUE>; + # Where PRIORITY_VALUE is some integer > 0 + +Plugins are loaded in order of their (increasing) priority, starting +with 0. Therefore, the plugin with the highest priority value will be +loaded last. Customizing LLVMC: the compilation graph @@ -194,9 +208,9 @@ As you can see, the edges can be either default or optional, where optional edges are differentiated by an additional ``case`` expression used to calculate the weight of this edge. Notice also that we refer -to tools via their names (as strings). This allows us to add edges to -an existing compilation graph without having to include all tool -definitions that it uses. +to tools via their names (as strings). This makes it possible to add +edges to an existing compilation graph in plugins without having to +know about all tool definitions used in the graph. The default edges are assigned a weight of 1, and optional edges get a weight of 0 + 2*N where N is the number of tests that evaluated to From foldr at codedgers.com Tue Nov 25 15:34:29 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:34:29 -0000 Subject: [llvm-commits] [llvm] r60045 - in /llvm/trunk/tools/llvmc2/doc: LLVMC-Reference.rst LLVMC-Tutorial.rst Message-ID: <200811252134.mAPLYTfX024606@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:34:29 2008 New Revision: 60045 URL: http://llvm.org/viewvc/llvm-project?rev=60045&view=rev Log: Small documentation update. Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=60045&r1=60044&r2=60045&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Tue Nov 25 15:34:29 2008 @@ -41,8 +41,8 @@ extensions). If you want to force files ending with ".c" to compile as C++, use the ``-x`` option, just like you would do it with ``gcc``:: - $ llvmc2 -x c hello.cpp - $ # hello.cpp is really a C file + $ # hello.c is really a C++ file + $ llvmc2 -x c++ hello.c $ ./a.out hello @@ -361,7 +361,7 @@ no meaning in the context of ``OptionList``, so the only properties allowed there are ``help`` and ``required``. -Option lists are used at the file scope. See file +Option lists are used at file scope. See the file ``plugins/Clang/Clang.td`` for an example of ``OptionList`` usage. .. _hooks: Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst?rev=60045&r1=60044&r2=60045&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Tue Nov 25 15:34:29 2008 @@ -23,8 +23,10 @@ $ ./a.out hello -For further help on command-line LLVMC usage, refer to the ``llvmc ---help`` output. +This will invoke ``llvm-g++`` under the hood (you can see which +commands are executed by using the ``-v`` option). For further help on +command-line LLVMC usage, refer to the ``llvmc --help`` output. + Using LLVMC to generate toolchain drivers ========================================= @@ -51,7 +53,7 @@ Contents of the file ``Simple.td`` look like this:: // Include common definitions - include "Common.td" + include "llvm/CompilerDriver/Common.td" // Tool descriptions def gcc : Tool< From foldr at codedgers.com Tue Nov 25 15:34:54 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:34:54 -0000 Subject: [llvm-commits] [llvm] r60046 - in /llvm/trunk/tools/llvmc2/doc: LLVMC-Reference.rst LLVMC-Tutorial.rst Message-ID: <200811252134.mAPLYsvl024634@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:34:53 2008 New Revision: 60046 URL: http://llvm.org/viewvc/llvm-project?rev=60046&view=rev Log: docs: Add author info + fix incorrect code example. Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=60046&r1=60045&r2=60046&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Tue Nov 25 15:34:53 2008 @@ -1,6 +1,7 @@ =================================== Customizing LLVMC: Reference Manual =================================== +:Author: Mikhail Glushenkov LLVMC is a generic compiler driver, designed to be customizable and extensible. It plays the same role for LLVM as the ``gcc`` program @@ -193,8 +194,10 @@ Edge<"llvm_gcc_cpp", "llc">, ... - OptionalEdge<"llvm_gcc_c", "opt", [(switch_on "opt")]>, - OptionalEdge<"llvm_gcc_cpp", "opt", [(switch_on "opt")]>, + OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), + (inc_weight))>, + OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), + (inc_weight))>, ... OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", @@ -437,7 +440,7 @@ * Possible tests are: - - ``switch_on`` - Returns true if a given command-line option is + - ``switch_on`` - Returns true if a given command-line switch is provided by the user. Example: ``(switch_on "opt")``. Note that you have to define all possible command-line options separately in the tool descriptions. See the next section for the discussion of @@ -481,8 +484,8 @@ One last thing that you will need to modify when adding support for a new language to LLVMC is the language map, which defines mappings from file extensions to language names. It is used to choose the proper -toolchain(s) for a given input file set. Language map definition is -located in the file ``Tools.td`` and looks like this:: +toolchain(s) for a given input file set. Language map definition looks +like this:: def LanguageMap : LanguageMap< [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst?rev=60046&r1=60045&r2=60046&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Tue Nov 25 15:34:53 2008 @@ -1,6 +1,7 @@ ====================== Tutorial - Using LLVMC ====================== +:Author: Mikhail Glushenkov LLVMC is a generic compiler driver, which plays the same role for LLVM as the ``gcc`` program does for GCC - the difference being that LLVMC From foldr at codedgers.com Tue Nov 25 15:35:20 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:35:20 -0000 Subject: [llvm-commits] [llvm] r60047 - /llvm/trunk/include/llvm/CompilerDriver/Tools.td Message-ID: <200811252135.mAPLZKpb024654@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:35:20 2008 New Revision: 60047 URL: http://llvm.org/viewvc/llvm-project?rev=60047&view=rev Log: Make -fsyntax-only, -include and -emit-llvm work for C++ and Objective-C/C++. Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=60047&r1=60046&r2=60047&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Tue Nov 25 15:35:20 2008 @@ -22,7 +22,7 @@ (default), "llvm-gcc -E -x c++ $INFILE"), (switch_on "fsyntax-only"), - "llvm-gcc -c -x c $INFILE", + "llvm-gcc -fsyntax-only -x c $INFILE", (default), "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm")), (switch_option "emit-llvm", (stop_compilation), @@ -46,9 +46,14 @@ "llvm-g++ -E -x c++ $INFILE -o $OUTFILE", (default), "llvm-g++ -E -x c++ $INFILE"), + (switch_on "fsyntax-only"), + "llvm-g++ -fsyntax-only -x c++ $INFILE", (default), "llvm-g++ -c -x c++ $INFILE -o $OUTFILE -emit-llvm")), + (switch_option "emit-llvm", (stop_compilation)), (switch_option "E", (stop_compilation)), + (switch_option "fsyntax-only", (stop_compilation)), + (parameter_list_option "include", (forward)), (sink) ]>; @@ -62,9 +67,14 @@ "llvm-gcc -E -x objective-c $INFILE -o $OUTFILE", (default), "llvm-gcc -E -x objective-c $INFILE"), + (switch_on "fsyntax-only"), + "llvm-gcc -fsyntax-only -x objective-c $INFILE", (default), "llvm-gcc -c -x objective-c $INFILE -o $OUTFILE -emit-llvm")), + (switch_option "emit-llvm", (stop_compilation)), (switch_option "E", (stop_compilation)), + (switch_option "fsyntax-only", (stop_compilation)), + (parameter_list_option "include", (forward)), (sink) ]>; @@ -78,9 +88,14 @@ "llvm-gcc -E -x objective-c++ $INFILE -o $OUTFILE", (default), "llvm-gcc -E -x objective-c++ $INFILE"), + (switch_on "fsyntax-only"), + "llvm-gcc -fsyntax-only -x objective-c++ $INFILE", (default), "llvm-gcc -c -x objective-c++ $INFILE -o $OUTFILE -emit-llvm")), + (switch_option "emit-llvm", (stop_compilation)), (switch_option "E", (stop_compilation)), + (switch_option "fsyntax-only", (stop_compilation)), + (parameter_list_option "include", (forward)), (sink) ]>; From foldr at codedgers.com Tue Nov 25 15:38:12 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:38:12 -0000 Subject: [llvm-commits] [llvm] r60048 - in /llvm/trunk: test/LLVMC/ tools/ tools/llvmc/ tools/llvmc/doc/ tools/llvmc/doc/img/ tools/llvmc/driver/ tools/llvmc/plugins/ tools/llvmc/plugins/Base/ tools/llvmc/plugins/Clang/ tools/llvmc/plugins/Hello/ tools/llvmc/plugins/Simple/ tools/llvmc2/ tools/llvmc2/doc/ tools/llvmc2/doc/img/ tools/llvmc2/driver/ tools/llvmc2/plugins/ tools/llvmc2/plugins/Base/ tools/llvmc2/plugins/Clang/ tools/llvmc2/plugins/Hello/ tools/llvmc2/plugins/Simple/ Message-ID: <200811252138.mAPLcEsL024826@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:38:12 2008 New Revision: 60048 URL: http://llvm.org/viewvc/llvm-project?rev=60048&view=rev Log: Since the old llvmc was removed, rename llvmc2 to llvmc. Added: llvm/trunk/tools/llvmc/ llvm/trunk/tools/llvmc/CMakeLists.txt - copied, changed from r60047, llvm/trunk/tools/llvmc2/CMakeLists.txt llvm/trunk/tools/llvmc/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/Makefile llvm/trunk/tools/llvmc/doc/ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst - copied, changed from r60047, llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc/doc/LLVMC-Tutorial.rst - copied, changed from r60047, llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst llvm/trunk/tools/llvmc/doc/Makefile llvm/trunk/tools/llvmc/doc/img/ llvm/trunk/tools/llvmc/doc/img/lines.gif - copied, changed from r60047, llvm/trunk/tools/llvmc2/doc/img/lines.gif llvm/trunk/tools/llvmc/doc/llvm.css - copied, changed from r60047, llvm/trunk/tools/llvmc2/doc/llvm.css llvm/trunk/tools/llvmc/driver/ llvm/trunk/tools/llvmc/driver/Action.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/Action.cpp llvm/trunk/tools/llvmc/driver/CMakeLists.txt - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/CMakeLists.txt llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp llvm/trunk/tools/llvmc/driver/Error.h - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/Error.h llvm/trunk/tools/llvmc/driver/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/Makefile llvm/trunk/tools/llvmc/driver/Plugin.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/Plugin.cpp llvm/trunk/tools/llvmc/driver/llvmc.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/driver/llvmc.cpp llvm/trunk/tools/llvmc/plugins/ llvm/trunk/tools/llvmc/plugins/Base/ llvm/trunk/tools/llvmc/plugins/Base/Base.td - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Base/Base.td llvm/trunk/tools/llvmc/plugins/Base/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Base/Makefile llvm/trunk/tools/llvmc/plugins/Base/PluginMain.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp llvm/trunk/tools/llvmc/plugins/Clang/ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td llvm/trunk/tools/llvmc/plugins/Clang/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/Makefile llvm/trunk/tools/llvmc/plugins/Clang/PluginMain.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp llvm/trunk/tools/llvmc/plugins/Hello/ llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp llvm/trunk/tools/llvmc/plugins/Hello/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Hello/Makefile llvm/trunk/tools/llvmc/plugins/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Makefile llvm/trunk/tools/llvmc/plugins/Simple/ llvm/trunk/tools/llvmc/plugins/Simple/Makefile - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/Makefile llvm/trunk/tools/llvmc/plugins/Simple/PluginMain.cpp - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp llvm/trunk/tools/llvmc/plugins/Simple/Simple.td - copied, changed from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td Removed: llvm/trunk/tools/llvmc2/CMakeLists.txt llvm/trunk/tools/llvmc2/Makefile llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst llvm/trunk/tools/llvmc2/doc/Makefile llvm/trunk/tools/llvmc2/doc/img/lines.gif llvm/trunk/tools/llvmc2/doc/llvm.css llvm/trunk/tools/llvmc2/driver/Action.cpp llvm/trunk/tools/llvmc2/driver/CMakeLists.txt llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp llvm/trunk/tools/llvmc2/driver/Error.h llvm/trunk/tools/llvmc2/driver/Makefile llvm/trunk/tools/llvmc2/driver/Plugin.cpp llvm/trunk/tools/llvmc2/driver/llvmc.cpp llvm/trunk/tools/llvmc2/plugins/Base/Base.td llvm/trunk/tools/llvmc2/plugins/Base/Makefile llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td llvm/trunk/tools/llvmc2/plugins/Clang/Makefile llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp llvm/trunk/tools/llvmc2/plugins/Hello/Makefile llvm/trunk/tools/llvmc2/plugins/Makefile llvm/trunk/tools/llvmc2/plugins/Simple/Makefile llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td Modified: llvm/trunk/test/LLVMC/emit-llvm.c llvm/trunk/test/LLVMC/false.c llvm/trunk/test/LLVMC/hello.c llvm/trunk/test/LLVMC/hello.cpp llvm/trunk/test/LLVMC/hello.m llvm/trunk/test/LLVMC/hello.mm llvm/trunk/test/LLVMC/include.c llvm/trunk/test/LLVMC/opt-test.c llvm/trunk/test/LLVMC/sink.c llvm/trunk/test/LLVMC/together.cpp llvm/trunk/test/LLVMC/wall.c llvm/trunk/tools/Makefile Modified: llvm/trunk/test/LLVMC/emit-llvm.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/emit-llvm.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/emit-llvm.c (original) +++ llvm/trunk/test/LLVMC/emit-llvm.c Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -// RUN: llvmc2 -c -emit-llvm -o - %s | llvm-dis | grep "@f0()" | count 1 +// RUN: llvmc -c -emit-llvm -o - %s | llvm-dis | grep "@f0()" | count 1 int f0(void) { } Modified: llvm/trunk/test/LLVMC/false.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/false.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/false.c (original) +++ llvm/trunk/test/LLVMC/false.c Tue Nov 25 15:38:12 2008 @@ -1,5 +1,5 @@ // Test that we can compile .c files as C++ and vice versa -// RUN: llvmc2 -x c++ %s -x c %p/test_data/false.cpp -x lisp -x whatnot -x none %p/test_data/false2.cpp -o %t +// RUN: llvmc -x c++ %s -x c %p/test_data/false.cpp -x lisp -x whatnot -x none %p/test_data/false2.cpp -o %t // RUN: ./%t | grep hello #include Modified: llvm/trunk/test/LLVMC/hello.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/hello.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/hello.c (original) +++ llvm/trunk/test/LLVMC/hello.c Tue Nov 25 15:38:12 2008 @@ -1,6 +1,6 @@ /* * Check that we can compile helloworld - * RUN: llvmc2 %s -o %t + * RUN: llvmc %s -o %t * RUN: ./%t | grep hello */ Modified: llvm/trunk/test/LLVMC/hello.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/hello.cpp?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/hello.cpp (original) +++ llvm/trunk/test/LLVMC/hello.cpp Tue Nov 25 15:38:12 2008 @@ -1,5 +1,5 @@ // Test that we can compile C++ code. -// RUN: llvmc2 %s -o %t +// RUN: llvmc %s -o %t // RUN: ./%t | grep hello #include Modified: llvm/trunk/test/LLVMC/hello.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/hello.m?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/hello.m (original) +++ llvm/trunk/test/LLVMC/hello.m Tue Nov 25 15:38:12 2008 @@ -1,6 +1,6 @@ /* * Check that we can compile helloworld - * RUN: llvmc2 %s -o %t + * RUN: llvmc %s -o %t * RUN: ./%t | grep hello */ Modified: llvm/trunk/test/LLVMC/hello.mm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/hello.mm?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/hello.mm (original) +++ llvm/trunk/test/LLVMC/hello.mm Tue Nov 25 15:38:12 2008 @@ -1,5 +1,5 @@ // Test that we can compile Objective-C++ code. -// RUN: llvmc2 %s -o %t +// RUN: llvmc %s -o %t // RUN: ./%t | grep hello #include Modified: llvm/trunk/test/LLVMC/include.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/include.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/include.c (original) +++ llvm/trunk/test/LLVMC/include.c Tue Nov 25 15:38:12 2008 @@ -1,7 +1,7 @@ /* * Check that the 'include' options work. * RUN: echo "int x;\n" > %t1.inc - * RUN: llvmc2 -include %t1.inc -fsyntax-only %s + * RUN: llvmc -include %t1.inc -fsyntax-only %s */ int f0(void) { Modified: llvm/trunk/test/LLVMC/opt-test.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/opt-test.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/opt-test.c (original) +++ llvm/trunk/test/LLVMC/opt-test.c Tue Nov 25 15:38:12 2008 @@ -1,6 +1,6 @@ /* * Check that the -opt switch works. - * RUN: llvmc2 %s -opt -o %t + * RUN: llvmc %s -opt -o %t * RUN: ./%t | grep hello */ Modified: llvm/trunk/test/LLVMC/sink.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/sink.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/sink.c (original) +++ llvm/trunk/test/LLVMC/sink.c Tue Nov 25 15:38:12 2008 @@ -1,6 +1,6 @@ /* * Check that the 'sink' options work. - * RUN: llvmc2 -v -Wall %s -o %t |& grep "Wall" + * RUN: llvmc -v -Wall %s -o %t |& grep "Wall" * RUN: ./%t | grep hello */ Modified: llvm/trunk/test/LLVMC/together.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/together.cpp?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/together.cpp (original) +++ llvm/trunk/test/LLVMC/together.cpp Tue Nov 25 15:38:12 2008 @@ -1,5 +1,5 @@ // Check that we can compile files of different types together. -// RUN: llvmc2 %s %p/test_data/together.c -o %t +// RUN: llvmc %s %p/test_data/together.c -o %t // RUN: ./%t | grep hello extern "C" void test(); Modified: llvm/trunk/test/LLVMC/wall.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/wall.c?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/wall.c (original) +++ llvm/trunk/test/LLVMC/wall.c Tue Nov 25 15:38:12 2008 @@ -1,6 +1,6 @@ /* * Check that -Wall works as intended - * RUN: llvmc2 -Wall %s -o %t + * RUN: llvmc -Wall %s -o %t * RUN: ./%t | grep hello */ Modified: llvm/trunk/tools/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=60048&r1=60047&r2=60048&view=diff ============================================================================== --- llvm/trunk/tools/Makefile (original) +++ llvm/trunk/tools/Makefile Tue Nov 25 15:38:12 2008 @@ -1,22 +1,22 @@ ##===- tools/Makefile --------------------------------------*- Makefile -*-===## -# +# # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. -# +# ##===----------------------------------------------------------------------===## LEVEL := .. -# NOTE: The tools are organized into five groups of four consisting of one -# large and three small executables. This is done to minimize memory load +# NOTE: The tools are organized into five groups of four consisting of one +# large and three small executables. This is done to minimize memory load # in parallel builds. Please retain this ordering. PARALLEL_DIRS := llvm-config \ opt llvm-as llvm-dis \ llc llvm-ranlib llvm-ar llvm-nm \ llvm-ld llvm-prof llvm-link \ lli gccas gccld llvm-extract llvm-db \ - bugpoint llvm-bcanalyzer llvm-stub llvmc2 + bugpoint llvm-bcanalyzer llvm-stub llvmc include $(LEVEL)/Makefile.config Copied: llvm/trunk/tools/llvmc/CMakeLists.txt (from r60047, llvm/trunk/tools/llvmc2/CMakeLists.txt) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/CMakeLists.txt?p2=llvm/trunk/tools/llvmc/CMakeLists.txt&p1=llvm/trunk/tools/llvmc2/CMakeLists.txt&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/Makefile (from r60047, llvm/trunk/tools/llvmc2/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/Makefile?p2=llvm/trunk/tools/llvmc/Makefile&p1=llvm/trunk/tools/llvmc2/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/Makefile (original) +++ llvm/trunk/tools/llvmc/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/Makefile -------------------------------*- Makefile -*-===## +##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -10,7 +10,7 @@ LEVEL = ../.. BUILTIN_PLUGINS = Base -DRIVER_NAME = llvmc2 +DRIVER_NAME = llvmc DIRS = plugins driver export BUILTIN_PLUGINS Copied: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (from r60047, llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?p2=llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst&p1=llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Tue Nov 25 15:38:12 2008 @@ -31,7 +31,7 @@ you shouldn't be able to notice them:: $ # This works as expected: - $ llvmc2 -O3 -Wall hello.cpp + $ llvmc -O3 -Wall hello.cpp $ ./a.out hello @@ -43,7 +43,7 @@ C++, use the ``-x`` option, just like you would do it with ``gcc``:: $ # hello.c is really a C++ file - $ llvmc2 -x c++ hello.c + $ llvmc -x c++ hello.c $ ./a.out hello @@ -51,10 +51,10 @@ object files you should provide the ``--linker`` option since it's impossible for LLVMC to choose the right linker in that case:: - $ llvmc2 -c hello.cpp - $ llvmc2 hello.o + $ llvmc -c hello.cpp + $ llvmc hello.o [A lot of link-time errors skipped] - $ llvmc2 --linker=c++ hello.o + $ llvmc --linker=c++ hello.o $ ./a.out hello @@ -138,7 +138,7 @@ $ cd $LLVMC_DIR/plugins/Simple $ make - $ llvmc2 -load $LLVM_DIR/Release/lib/LLVMCSimple.so + $ llvmc -load $LLVM_DIR/Release/lib/LLVMCSimple.so Sometimes, you will want a 'bare-bones' version of LLVMC that has no built-in plugins. It can be compiled with the following command:: @@ -229,7 +229,7 @@ default edge *per language*). To get a visual representation of the compilation graph (useful for -debugging), run ``llvmc2 --view-graph``. You will need ``dot`` and +debugging), run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for this to work properly. Copied: llvm/trunk/tools/llvmc/doc/LLVMC-Tutorial.rst (from r60047, llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Tutorial.rst?p2=llvm/trunk/tools/llvmc/doc/LLVMC-Tutorial.rst&p1=llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Tutorial.rst Tue Nov 25 15:38:12 2008 @@ -20,7 +20,7 @@ In general, LLVMC tries to be command-line compatible with ``gcc`` as much as possible, so most of the familiar options work:: - $ llvmc2 -O3 -Wall hello.cpp + $ llvmc -O3 -Wall hello.cpp $ ./a.out hello @@ -38,7 +38,7 @@ Start by compiling ``plugins/Simple/Simple.td``, which is a primitive wrapper for ``gcc``:: - $ cd $LLVM_DIR/tools/llvmc2 + $ cd $LLVM_DIR/tools/llvmc $ make DRIVER_NAME=mygcc BUILTIN_PLUGINS=Simple $ cat > hello.c [...] @@ -98,4 +98,3 @@ .. [1] TableGen Fundamentals http://llvm.cs.uiuc.edu/docs/TableGenFundamentals.html - Added: llvm/trunk/tools/llvmc/doc/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/Makefile?rev=60048&view=auto ============================================================================== --- llvm/trunk/tools/llvmc/doc/Makefile (added) +++ llvm/trunk/tools/llvmc/doc/Makefile Tue Nov 25 15:38:12 2008 @@ -0,0 +1,21 @@ +##===- tools/llvmc/doc/Makefile ----------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet + +all : LLVMC-Reference.html LLVMC-Tutorial.html + +LLVMC-Tutorial.html : LLVMC-Tutorial.rst llvm.css + $(RST2HTML) $< $@ + +LLVMC-Reference.html : LLVMC-Reference.rst llvm.css + $(RST2HTML) $< $@ + +clean : + rm *.html Copied: llvm/trunk/tools/llvmc/doc/img/lines.gif (from r60047, llvm/trunk/tools/llvmc2/doc/img/lines.gif) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/img/lines.gif?p2=llvm/trunk/tools/llvmc/doc/img/lines.gif&p1=llvm/trunk/tools/llvmc2/doc/img/lines.gif&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/doc/llvm.css (from r60047, llvm/trunk/tools/llvmc2/doc/llvm.css) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/llvm.css?p2=llvm/trunk/tools/llvmc/doc/llvm.css&p1=llvm/trunk/tools/llvmc2/doc/llvm.css&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/driver/Action.cpp (from r60047, llvm/trunk/tools/llvmc2/driver/Action.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/Action.cpp?p2=llvm/trunk/tools/llvmc/driver/Action.cpp&p1=llvm/trunk/tools/llvmc2/driver/Action.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/driver/CMakeLists.txt (from r60047, llvm/trunk/tools/llvmc2/driver/CMakeLists.txt) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CMakeLists.txt?p2=llvm/trunk/tools/llvmc/driver/CMakeLists.txt&p1=llvm/trunk/tools/llvmc2/driver/CMakeLists.txt&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp (from r60047, llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp?p2=llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp&p1=llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/driver/Error.h (from r60047, llvm/trunk/tools/llvmc2/driver/Error.h) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/Error.h?p2=llvm/trunk/tools/llvmc/driver/Error.h&p1=llvm/trunk/tools/llvmc2/driver/Error.h&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/driver/Makefile (from r60047, llvm/trunk/tools/llvmc2/driver/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/Makefile?p2=llvm/trunk/tools/llvmc/driver/Makefile&p1=llvm/trunk/tools/llvmc2/driver/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Makefile (original) +++ llvm/trunk/tools/llvmc/driver/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/src/Makefile ---------------------------*- Makefile -*-===## +##===- tools/llvmc/driver/Makefile -------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # Copied: llvm/trunk/tools/llvmc/driver/Plugin.cpp (from r60047, llvm/trunk/tools/llvmc2/driver/Plugin.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/Plugin.cpp?p2=llvm/trunk/tools/llvmc/driver/Plugin.cpp&p1=llvm/trunk/tools/llvmc2/driver/Plugin.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Plugin.cpp (original) +++ llvm/trunk/tools/llvmc/driver/Plugin.cpp Tue Nov 25 15:38:12 2008 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// Plugin support for llvmc2. +// Plugin support. // //===----------------------------------------------------------------------===// Copied: llvm/trunk/tools/llvmc/driver/llvmc.cpp (from r60047, llvm/trunk/tools/llvmc2/driver/llvmc.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/llvmc.cpp?p2=llvm/trunk/tools/llvmc/driver/llvmc.cpp&p1=llvm/trunk/tools/llvmc2/driver/llvmc.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/plugins/Base/Base.td (from r60047, llvm/trunk/tools/llvmc2/plugins/Base/Base.td) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Base.td?p2=llvm/trunk/tools/llvmc/plugins/Base/Base.td&p1=llvm/trunk/tools/llvmc2/plugins/Base/Base.td&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/plugins/Base/Makefile (from r60047, llvm/trunk/tools/llvmc2/plugins/Base/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Makefile?p2=llvm/trunk/tools/llvmc/plugins/Base/Makefile&p1=llvm/trunk/tools/llvmc2/plugins/Base/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Base/Makefile (original) +++ llvm/trunk/tools/llvmc/plugins/Base/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/plugins/Base/Makefile ------------------*- Makefile -*-===## +##===- tools/llvmc/plugins/Base/Makefile -------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # Copied: llvm/trunk/tools/llvmc/plugins/Base/PluginMain.cpp (from r60047, llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/PluginMain.cpp?p2=llvm/trunk/tools/llvmc/plugins/Base/PluginMain.cpp&p1=llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?p2=llvm/trunk/tools/llvmc/plugins/Clang/Clang.td&p1=llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Tue Nov 25 15:38:12 2008 @@ -83,4 +83,3 @@ Edge<"clang_cpp", "llvm_ld">, Edge<"clang_objective_c", "llvm_ld"> ]>; - Copied: llvm/trunk/tools/llvmc/plugins/Clang/Makefile (from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Makefile?p2=llvm/trunk/tools/llvmc/plugins/Clang/Makefile&p1=llvm/trunk/tools/llvmc2/plugins/Clang/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/Makefile (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/plugins/Clang/Makefile -----------------*- Makefile -*-===## +##===- tools/llvmc/plugins/Clang/Makefile ------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -11,4 +11,3 @@ BUILT_SOURCES = AutoGenerated.inc include ../Makefile - Copied: llvm/trunk/tools/llvmc/plugins/Clang/PluginMain.cpp (from r60047, llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/PluginMain.cpp?p2=llvm/trunk/tools/llvmc/plugins/Clang/PluginMain.cpp&p1=llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp (from r60047, llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp?p2=llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp&p1=llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp (original) +++ llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp Tue Nov 25 15:38:12 2008 @@ -28,5 +28,3 @@ static llvmc::RegisterPlugin RP("Hello", "Hello World plugin"); } - - Copied: llvm/trunk/tools/llvmc/plugins/Hello/Makefile (from r60047, llvm/trunk/tools/llvmc2/plugins/Hello/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Hello/Makefile?p2=llvm/trunk/tools/llvmc/plugins/Hello/Makefile&p1=llvm/trunk/tools/llvmc2/plugins/Hello/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Hello/Makefile (original) +++ llvm/trunk/tools/llvmc/plugins/Hello/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/plugins/Hello/Makefile -----------------*- Makefile -*-===## +##===- tools/llvmc/plugins/Hello/Makefile ------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # Copied: llvm/trunk/tools/llvmc/plugins/Makefile (from r60047, llvm/trunk/tools/llvmc2/plugins/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Makefile?p2=llvm/trunk/tools/llvmc/plugins/Makefile&p1=llvm/trunk/tools/llvmc2/plugins/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Makefile (original) +++ llvm/trunk/tools/llvmc/plugins/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/plugins/Makefile.plugins ----------------*- Makefile -*-===## +##===- tools/llvmc/plugins/Makefile.plugins ----------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # Copied: llvm/trunk/tools/llvmc/plugins/Simple/Makefile (from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/Makefile) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Simple/Makefile?p2=llvm/trunk/tools/llvmc/plugins/Simple/Makefile&p1=llvm/trunk/tools/llvmc2/plugins/Simple/Makefile&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Simple/Makefile (original) +++ llvm/trunk/tools/llvmc/plugins/Simple/Makefile Tue Nov 25 15:38:12 2008 @@ -1,4 +1,4 @@ -##===- tools/llvmc2/plugins/Simple/Makefile ------------------*- Makefile -*-===## +##===- tools/llvmc/plugins/Simple/Makefile -----------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # Copied: llvm/trunk/tools/llvmc/plugins/Simple/PluginMain.cpp (from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Simple/PluginMain.cpp?p2=llvm/trunk/tools/llvmc/plugins/Simple/PluginMain.cpp&p1=llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Copied: llvm/trunk/tools/llvmc/plugins/Simple/Simple.td (from r60047, llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Simple/Simple.td?p2=llvm/trunk/tools/llvmc/plugins/Simple/Simple.td&p1=llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td&r1=60047&r2=60048&rev=60048&view=diff ============================================================================== (empty) Removed: llvm/trunk/tools/llvmc2/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CMakeLists.txt?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/CMakeLists.txt (original) +++ llvm/trunk/tools/llvmc2/CMakeLists.txt (removed) @@ -1,4 +0,0 @@ -add_subdirectory(driver) - -# TODO: support plugins and user-configured builds. -# See ./doc/LLVMC-Reference.rst "Customizing LLVMC: the compilation graph" Removed: llvm/trunk/tools/llvmc2/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/Makefile (original) +++ llvm/trunk/tools/llvmc2/Makefile (removed) @@ -1,19 +0,0 @@ -##===- tools/llvmc2/Makefile -------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -BUILTIN_PLUGINS = Base -DRIVER_NAME = llvmc2 -DIRS = plugins driver - -export BUILTIN_PLUGINS -export DRIVER_NAME - -include $(LEVEL)/Makefile.common Removed: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (removed) @@ -1,517 +0,0 @@ -=================================== -Customizing LLVMC: Reference Manual -=================================== -:Author: Mikhail Glushenkov - -LLVMC is a generic compiler driver, designed to be customizable and -extensible. It plays the same role for LLVM as the ``gcc`` program -does for GCC - LLVMC's job is essentially to transform a set of input -files into a set of targets depending on configuration rules and user -options. What makes LLVMC different is that these transformation rules -are completely customizable - in fact, LLVMC knows nothing about the -specifics of transformation (even the command-line options are mostly -not hard-coded) and regards the transformation structure as an -abstract graph. The structure of this graph is completely determined -by plugins, which can be either statically or dynamically linked. This -makes it possible to easily adapt LLVMC for other purposes - for -example, as a build tool for game resources. - -Because LLVMC employs TableGen [1]_ as its configuration language, you -need to be familiar with it to customize LLVMC. - - -.. contents:: - - -Compiling with LLVMC -==================== - -LLVMC tries hard to be as compatible with ``gcc`` as possible, -although there are some small differences. Most of the time, however, -you shouldn't be able to notice them:: - - $ # This works as expected: - $ llvmc2 -O3 -Wall hello.cpp - $ ./a.out - hello - -One nice feature of LLVMC is that one doesn't have to distinguish -between different compilers for different languages (think ``g++`` and -``gcc``) - the right toolchain is chosen automatically based on input -language names (which are, in turn, determined from file -extensions). If you want to force files ending with ".c" to compile as -C++, use the ``-x`` option, just like you would do it with ``gcc``:: - - $ # hello.c is really a C++ file - $ llvmc2 -x c++ hello.c - $ ./a.out - hello - -On the other hand, when using LLVMC as a linker to combine several C++ -object files you should provide the ``--linker`` option since it's -impossible for LLVMC to choose the right linker in that case:: - - $ llvmc2 -c hello.cpp - $ llvmc2 hello.o - [A lot of link-time errors skipped] - $ llvmc2 --linker=c++ hello.o - $ ./a.out - hello - - -Predefined options -================== - -LLVMC has some built-in options that can't be overridden in the -configuration files: - -* ``-o FILE`` - Output file name. - -* ``-x LANGUAGE`` - Specify the language of the following input files - until the next -x option. - -* ``-load PLUGIN_NAME`` - Load the specified plugin DLL. Example: - ``-load $LLVM_DIR/Release/lib/LLVMCSimple.so``. - -* ``-v`` - Enable verbose mode, i.e. print out all executed commands. - -* ``--view-graph`` - Show a graphical representation of the compilation - graph. Requires that you have ``dot`` and ``gv`` programs - installed. Hidden option, useful for debugging. - -* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the - current directory with the compilation graph description in the - Graphviz format. Hidden option, useful for debugging. - -* ``--save-temps`` - Write temporary files to the current directory - and do not delete them on exit. Hidden option, useful for debugging. - -* ``--help``, ``--help-hidden``, ``--version`` - These options have - their standard meaning. - - -Compiling LLVMC plugins -======================= - -It's easiest to start working on your own LLVMC plugin by copying the -skeleton project which lives under ``$LLVMC_DIR/plugins/Simple``:: - - $ cd $LLVMC_DIR/plugins - $ cp -r Simple MyPlugin - $ cd MyPlugin - $ ls - Makefile PluginMain.cpp Simple.td - -As you can see, our basic plugin consists of only two files (not -counting the build script). ``Simple.td`` contains TableGen -description of the compilation graph; its format is documented in the -following sections. ``PluginMain.cpp`` is just a helper file used to -compile the auto-generated C++ code produced from TableGen source. It -can also contain hook definitions (see `below`__). - -__ hooks_ - -The first thing that you should do is to change the ``LLVMC_PLUGIN`` -variable in the ``Makefile`` to avoid conflicts (since this variable -is used to name the resulting library):: - - LLVMC_PLUGIN=MyPlugin - -It is also a good idea to rename ``Simple.td`` to something less -generic:: - - $ mv Simple.td MyPlugin.td - -Note that the plugin source directory must be placed under -``$LLVMC_DIR/plugins`` to make use of the existing build -infrastructure. To build a version of the LLVMC executable called -``mydriver`` with your plugin compiled in, use the following command:: - - $ cd $LLVMC_DIR - $ make BUILTIN_PLUGINS=MyPlugin DRIVER_NAME=mydriver - -To build your plugin as a dynamic library, just ``cd`` to its source -directory and run ``make``. The resulting file will be called -``LLVMC$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case, -``LLVMCMyPlugin.so``). This library can be then loaded in with the -``-load`` option. Example:: - - $ cd $LLVMC_DIR/plugins/Simple - $ make - $ llvmc2 -load $LLVM_DIR/Release/lib/LLVMCSimple.so - -Sometimes, you will want a 'bare-bones' version of LLVMC that has no -built-in plugins. It can be compiled with the following command:: - - $ cd $LLVMC_DIR - $ make BUILTIN_PLUGINS="" - -How plugins are loaded -====================== - -It is possible for LLVMC plugins to depend on each other. For example, -one can create edges between nodes defined in some other plugin. To -make this work, however, that plugin should be loaded first. To -achieve this, the concept of plugin priority was introduced. By -default, every plugin has priority zero; to specify the priority -explicitly, put the following line in your ``.td`` file:: - - def Priority : PluginPriority<$PRIORITY_VALUE>; - # Where PRIORITY_VALUE is some integer > 0 - -Plugins are loaded in order of their (increasing) priority, starting -with 0. Therefore, the plugin with the highest priority value will be -loaded last. - - -Customizing LLVMC: the compilation graph -======================================== - -Each TableGen configuration file should include the common -definitions:: - - include "llvm/CompilerDriver/Common.td" - // And optionally: - // include "llvm/CompilerDriver/Tools.td" - // which contains some useful tool definitions. - -Internally, LLVMC stores information about possible source -transformations in form of a graph. Nodes in this graph represent -tools, and edges between two nodes represent a transformation path. A -special "root" node is used to mark entry points for the -transformations. LLVMC also assigns a weight to each edge (more on -this later) to choose between several alternative edges. - -The definition of the compilation graph (see file -``plugins/Base/Base.td`` for an example) is just a list of edges:: - - def CompilationGraph : CompilationGraph<[ - Edge<"root", "llvm_gcc_c">, - Edge<"root", "llvm_gcc_assembler">, - ... - - Edge<"llvm_gcc_c", "llc">, - Edge<"llvm_gcc_cpp", "llc">, - ... - - OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), - (inc_weight))>, - OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), - (inc_weight))>, - ... - - OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case (input_languages_contain "c++"), (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))>, - ... - - ]>; - -As you can see, the edges can be either default or optional, where -optional edges are differentiated by an additional ``case`` expression -used to calculate the weight of this edge. Notice also that we refer -to tools via their names (as strings). This makes it possible to add -edges to an existing compilation graph in plugins without having to -know about all tool definitions used in the graph. - -The default edges are assigned a weight of 1, and optional edges get a -weight of 0 + 2*N where N is the number of tests that evaluated to -true in the ``case`` expression. It is also possible to provide an -integer parameter to ``inc_weight`` and ``dec_weight`` - in this case, -the weight is increased (or decreased) by the provided value instead -of the default 2. - -When passing an input file through the graph, LLVMC picks the edge -with the maximum weight. To avoid ambiguity, there should be only one -default edge between two nodes (with the exception of the root node, -which gets a special treatment - there you are allowed to specify one -default edge *per language*). - -To get a visual representation of the compilation graph (useful for -debugging), run ``llvmc2 --view-graph``. You will need ``dot`` and -``gsview`` installed for this to work properly. - - -Writing a tool description -========================== - -As was said earlier, nodes in the compilation graph represent tools, -which are described separately. A tool definition looks like this -(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: - - def llvm_gcc_cpp : Tool<[ - (in_language "c++"), - (out_language "llvm-assembler"), - (output_suffix "bc"), - (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), - (sink) - ]>; - -This defines a new tool called ``llvm_gcc_cpp``, which is an alias for -``llvm-g++``. As you can see, a tool definition is just a list of -properties; most of them should be self-explanatory. The ``sink`` -property means that this tool should be passed all command-line -options that lack explicit descriptions. - -The complete list of the currently implemented tool properties follows: - -* Possible tool properties: - - - ``in_language`` - input language name. Can be either a string or a - list, in case the tool supports multiple input languages. - - - ``out_language`` - output language name. - - - ``output_suffix`` - output file suffix. - - - ``cmd_line`` - the actual command used to run the tool. You can - use ``$INFILE`` and ``$OUTFILE`` variables, output redirection - with ``>``, hook invocations (``$CALL``), environment variables - (via ``$ENV``) and the ``case`` construct (more on this below). - - - ``join`` - this tool is a "join node" in the graph, i.e. it gets a - list of input files and joins them together. Used for linkers. - - - ``sink`` - all command-line options that are not handled by other - tools are passed to this tool. - -The next tool definition is slightly more complex:: - - def llvm_gcc_linker : Tool<[ - (in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), - (join), - (prefix_list_option "L", (forward), - (help "add a directory to link path")), - (prefix_list_option "l", (forward), - (help "search a library when linking")), - (prefix_list_option "Wl", (unpack_values), - (help "pass options to linker")) - ]>; - -This tool has a "join" property, which means that it behaves like a -linker. This tool also defines several command-line options: ``-l``, -``-L`` and ``-Wl`` which have their usual meaning. An option has two -attributes: a name and a (possibly empty) list of properties. All -currently implemented option types and properties are described below: - -* Possible option types: - - - ``switch_option`` - a simple boolean switch, for example ``-time``. - - - ``parameter_option`` - option that takes an argument, for example - ``-std=c99``; - - - ``parameter_list_option`` - same as the above, but more than one - occurence of the option is allowed. - - - ``prefix_option`` - same as the parameter_option, but the option name - and parameter value are not separated. - - - ``prefix_list_option`` - same as the above, but more than one - occurence of the option is allowed; example: ``-lm -lpthread``. - - - ``alias_option`` - a special option type for creating - aliases. Unlike other option types, aliases are not allowed to - have any properties besides the aliased option name. Usage - example: ``(alias_option "preprocess", "E")`` - - -* Possible option properties: - - - ``append_cmd`` - append a string to the tool invocation command. - - - ``forward`` - forward this option unchanged. - - - ``forward_as`` - Change the name of this option, but forward the - argument unchanged. Example: ``(forward_as "--disable-optimize")``. - - - ``output_suffix`` - modify the output suffix of this - tool. Example: ``(switch "E", (output_suffix "i")``. - - - ``stop_compilation`` - stop compilation after this phase. - - - ``unpack_values`` - used for for splitting and forwarding - comma-separated lists of options, e.g. ``-Wa,-foo=bar,-baz`` is - converted to ``-foo=bar -baz`` and appended to the tool invocation - command. - - - ``help`` - help string associated with this option. Used for - ``--help`` output. - - - ``required`` - this option is obligatory. - - -Option list - specifying all options in a single place -====================================================== - -It can be handy to have all information about options gathered in a -single place to provide an overview. This can be achieved by using a -so-called ``OptionList``:: - - def Options : OptionList<[ - (switch_option "E", (help "Help string")), - (alias_option "quiet", "q") - ... - ]>; - -``OptionList`` is also a good place to specify option aliases. - -Tool-specific option properties like ``append_cmd`` have (obviously) -no meaning in the context of ``OptionList``, so the only properties -allowed there are ``help`` and ``required``. - -Option lists are used at file scope. See the file -``plugins/Clang/Clang.td`` for an example of ``OptionList`` usage. - -.. _hooks: - -Using hooks and environment variables in the ``cmd_line`` property -================================================================== - -Normally, LLVMC executes programs from the system ``PATH``. Sometimes, -this is not sufficient: for example, we may want to specify tool names -in the configuration file. This can be achieved via the mechanism of -hooks - to write your own hooks, just add their definitions to the -``PluginMain.cpp`` or drop a ``.cpp`` file into the -``$LLVMC_DIR/driver`` directory. Hooks should live in the ``hooks`` -namespace and have the signature ``std::string hooks::MyHookName -(void)``. They can be used from the ``cmd_line`` tool property:: - - (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") - -It is also possible to use environment variables in the same manner:: - - (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") - -To change the command line string based on user-provided options use -the ``case`` expression (documented below):: - - (cmd_line - (case - (switch_on "E"), - "llvm-g++ -E -x c $INFILE -o $OUTFILE", - (default), - "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")) - -Conditional evaluation: the ``case`` expression -=============================================== - -The 'case' construct can be used to calculate weights of the optional -edges and to choose between several alternative command line strings -in the ``cmd_line`` tool property. It is designed after the -similarly-named construct in functional languages and takes the form -``(case (test_1), statement_1, (test_2), statement_2, ... (test_N), -statement_N)``. The statements are evaluated only if the corresponding -tests evaluate to true. - -Examples:: - - // Increases edge weight by 5 if "-A" is provided on the - // command-line, and by 5 more if "-B" is also provided. - (case - (switch_on "A"), (inc_weight 5), - (switch_on "B"), (inc_weight 5)) - - // Evaluates to "cmdline1" if option "-A" is provided on the - // command line, otherwise to "cmdline2" - (case - (switch_on "A"), "cmdline1", - (switch_on "B"), "cmdline2", - (default), "cmdline3") - -Note the slight difference in 'case' expression handling in contexts -of edge weights and command line specification - in the second example -the value of the ``"B"`` switch is never checked when switch ``"A"`` is -enabled, and the whole expression always evaluates to ``"cmdline1"`` in -that case. - -Case expressions can also be nested, i.e. the following is legal:: - - (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...) - (default), ...) - -You should, however, try to avoid doing that because it hurts -readability. It is usually better to split tool descriptions and/or -use TableGen inheritance instead. - -* Possible tests are: - - - ``switch_on`` - Returns true if a given command-line switch is - provided by the user. Example: ``(switch_on "opt")``. Note that - you have to define all possible command-line options separately in - the tool descriptions. See the next section for the discussion of - different kinds of command-line options. - - - ``parameter_equals`` - Returns true if a command-line parameter equals - a given value. Example: ``(parameter_equals "W", "all")``. - - - ``element_in_list`` - Returns true if a command-line parameter list - includes a given value. Example: ``(parameter_in_list "l", "pthread")``. - - - ``input_languages_contain`` - Returns true if a given language - belongs to the current input language set. Example: - ``(input_languages_contain "c++")``. - - - ``in_language`` - Evaluates to true if the language of the input - file equals to the argument. At the moment works only with - ``cmd_line`` property on non-join nodes. Example: ``(in_language - "c++")``. - - - ``not_empty`` - Returns true if a given option (which should be - either a parameter or a parameter list) is set by the - user. Example: ``(not_empty "o")``. - - - ``default`` - Always evaluates to true. Should always be the last - test in the ``case`` expression. - - - ``and`` - A standard logical combinator that returns true iff all - of its arguments return true. Used like this: ``(and (test1), - (test2), ... (testN))``. Nesting of ``and`` and ``or`` is allowed, - but not encouraged. - - - ``or`` - Another logical combinator that returns true only if any - one of its arguments returns true. Example: ``(or (test1), - (test2), ... (testN))``. - - -Language map -============ - -One last thing that you will need to modify when adding support for a -new language to LLVMC is the language map, which defines mappings from -file extensions to language names. It is used to choose the proper -toolchain(s) for a given input file set. Language map definition looks -like this:: - - def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c", ["c"]>, - ... - ]>; - -Debugging -========= - -When writing LLVMC plugins, it can be useful to get a visual view of -the resulting compilation graph. This can be achieved via the command -line option ``--view-graph``. This command assumes that Graphviz [2]_ and -Ghostview [3]_ are installed. There is also a ``--dump-graph`` option that -creates a Graphviz source file(``compilation-graph.dot``) in the -current directory. - - -References -========== - -.. [1] TableGen Fundamentals - http://llvm.cs.uiuc.edu/docs/TableGenFundamentals.html - -.. [2] Graphviz - http://www.graphviz.org/ - -.. [3] Ghostview - http://pages.cs.wisc.edu/~ghost/ Removed: llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original) +++ llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (removed) @@ -1,101 +0,0 @@ -====================== -Tutorial - Using LLVMC -====================== -:Author: Mikhail Glushenkov - -LLVMC is a generic compiler driver, which plays the same role for LLVM -as the ``gcc`` program does for GCC - the difference being that LLVMC -is designed to be more adaptable and easier to customize. Most of -LLVMC functionality is implemented via plugins, which can be loaded -dynamically or compiled in. This tutorial describes the basic usage -and configuration of LLVMC. - - -.. contents:: - - -Compiling with LLVMC -==================== - -In general, LLVMC tries to be command-line compatible with ``gcc`` as -much as possible, so most of the familiar options work:: - - $ llvmc2 -O3 -Wall hello.cpp - $ ./a.out - hello - -This will invoke ``llvm-g++`` under the hood (you can see which -commands are executed by using the ``-v`` option). For further help on -command-line LLVMC usage, refer to the ``llvmc --help`` output. - - -Using LLVMC to generate toolchain drivers -========================================= - -LLVMC plugins are written mostly using TableGen [1]_, so you need to -be familiar with it to get anything done. - -Start by compiling ``plugins/Simple/Simple.td``, which is a primitive -wrapper for ``gcc``:: - - $ cd $LLVM_DIR/tools/llvmc2 - $ make DRIVER_NAME=mygcc BUILTIN_PLUGINS=Simple - $ cat > hello.c - [...] - $ mygcc hello.c - $ ./hello.out - Hello - -Here we link our plugin with the LLVMC core statically to form an -executable file called ``mygcc``. It is also possible to build our -plugin as a standalone dynamic library; this is described in the -reference manual. - -Contents of the file ``Simple.td`` look like this:: - - // Include common definitions - include "llvm/CompilerDriver/Common.td" - - // Tool descriptions - def gcc : Tool< - [(in_language "c"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "gcc $INFILE -o $OUTFILE"), - (sink) - ]>; - - // Language map - def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; - - // Compilation graph - def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; - -As you can see, this file consists of three parts: tool descriptions, -language map, and the compilation graph definition. - -At the heart of LLVMC is the idea of a compilation graph: vertices in -this graph are tools, and edges represent a transformation path -between two tools (for example, assembly source produced by the -compiler can be transformed into executable code by an assembler). The -compilation graph is basically a list of edges; a special node named -``root`` is used to mark graph entry points. - -Tool descriptions are represented as property lists: most properties -in the example above should be self-explanatory; the ``sink`` property -means that all options lacking an explicit description should be -forwarded to this tool. - -The ``LanguageMap`` associates a language name with a list of suffixes -and is used for deciding which toolchain corresponds to a given input -file. - -To learn more about LLVMC customization, refer to the reference -manual and plugin source code in the ``plugins`` directory. - -References -========== - -.. [1] TableGen Fundamentals - http://llvm.cs.uiuc.edu/docs/TableGenFundamentals.html - Removed: llvm/trunk/tools/llvmc2/doc/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/doc/Makefile (original) +++ llvm/trunk/tools/llvmc2/doc/Makefile (removed) @@ -1,13 +0,0 @@ - -RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet - -all : LLVMC-Reference.html LLVMC-Tutorial.html - -LLVMC-Tutorial.html : LLVMC-Tutorial.rst llvm.css - $(RST2HTML) $< $@ - -LLVMC-Reference.html : LLVMC-Reference.rst llvm.css - $(RST2HTML) $< $@ - -clean : - rm *.html Removed: llvm/trunk/tools/llvmc2/doc/img/lines.gif URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/img/lines.gif?rev=60047&view=auto ============================================================================== Binary files llvm/trunk/tools/llvmc2/doc/img/lines.gif (original) and llvm/trunk/tools/llvmc2/doc/img/lines.gif (removed) differ Removed: llvm/trunk/tools/llvmc2/doc/llvm.css URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/llvm.css?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/doc/llvm.css (original) +++ llvm/trunk/tools/llvmc2/doc/llvm.css (removed) @@ -1,86 +0,0 @@ -/* - * LLVM documentation style sheet - */ - -/* Common styles */ -.body { color: black; background: white; margin: 0 0 0 0 } - -/* No borders on image links */ -a:link img, a:visited img {border-style: none} - -address img { float: right; width: 88px; height: 31px; } -address { clear: right; } - -TR, TD { border: 2px solid gray; padding: 4pt 4pt 2pt 2pt; } -TH { border: 2px solid gray; font-weight: bold; font-size: 105%; - background: url("img/lines.gif"); - font-family: "Georgia,Palatino,Times,Roman,SanSerif"; text-align:center; - vertical-align: middle; } -TABLE { text-align: center; border: 2px solid black; - border-collapse: collapse; margin-top: 1em; margin-left: 1em; - margin-right: 1em; margin-bottom: 1em; } -/* - * Documentation - */ -/* Common for title and header */ -h1 { - color: black; background: url("img/lines.gif"); - font-family: "Georgia,Palatino,Times,Roman,SanSerif"; font-weight: bold; - border-width: 1px; - border-style: solid none solid none; - text-align: center; - vertical-align: middle; - padding-left: 8pt; - padding-top: 1px; - padding-bottom: 2px -} - -.doc_title { text-align: left; font-size: 25pt } -.doc_section { text-align: center; font-size: 22pt; - margin: 20pt 0pt 5pt 0pt; } -.doc_subsection { width: 75%; - text-align: left; font-size: 12pt; padding: 4pt 4pt 4pt 4pt; - margin: 1.5em 0.5em 0.5em 0.5em } - -.doc_subsubsection { margin: 2.0em 0.5em 0.5em 0.5em; - font-weight: bold; font-style: oblique; - border-bottom: 1px solid #999999; font-size: 12pt; - width: 75%; } -.doc_author { text-align: left; font-weight: bold; padding-left: 20pt } -.doc_text { text-align: left; padding-left: 20pt; padding-right: 10pt } - -.doc_footer { text-align: left; padding: 0 0 0 0 } - -.doc_hilite { color: blue; font-weight: bold; } - -.doc_table { text-align: center; width: 90%; - padding: 1px 1px 1px 1px; border: 1px; } - -.doc_table_nw { text-align: center; border: 1px; - padding: 1px 1px 1px 1px; } - -.doc_warning { color: red; font-weight: bold } - -.literal-block { border: solid 1px gray; background: #eeeeee; - margin: 0 1em 0 1em; - padding: 0 1em 0 1em; - display:table; - } -.doc_notes { background: #fafafa; border: 1px solid #cecece; padding: 0.1em } - -TABLE.layout { text-align: left; border: none; border-collapse: collapse; - padding: 4px 4px 4px 4px; } -TR.layout { border: none; padding: 4pt 4pt 2pt 2pt; } -TD.layout { border: none; padding: 4pt 4pt 2pt 2pt; - vertical-align: top;} -TD.left { border: none; padding: 4pt 4pt 2pt 2pt; text-align: left; - vertical-align: top;} -TD.right { border: none; padding: 4pt 4pt 2pt 2pt; text-align: right; - vertical-align: top;} -TH.layout { border: none; font-weight: bold; font-size: 105%; - text-align:center; vertical-align: middle; } - -/* Left align table cell */ -.td_left { border: 2px solid gray; text-align: left; } - -.toc-backref { color: black; } Removed: llvm/trunk/tools/llvmc2/driver/Action.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/Action.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Action.cpp (original) +++ llvm/trunk/tools/llvmc2/driver/Action.cpp (removed) @@ -1,78 +0,0 @@ -//===--- Action.cpp - The LLVM Compiler Driver ------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Action class - implementation and auxiliary functions. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/Action.h" - -#include "llvm/Support/CommandLine.h" -#include "llvm/System/Program.h" - -#include -#include - -using namespace llvm; -using namespace llvmc; - -extern cl::opt DryRun; -extern cl::opt VerboseMode; - -namespace { - int ExecuteProgram(const std::string& name, - const StrVector& args) { - sys::Path prog = sys::Program::FindProgramByName(name); - - if (prog.isEmpty()) - throw std::runtime_error("Can't find program '" + name + "'"); - if (!prog.canExecute()) - throw std::runtime_error("Program '" + name + "' is not executable."); - - // Build the command line vector and the redirects array. - const sys::Path* redirects[3] = {0,0,0}; - sys::Path stdout_redirect; - - std::vector argv; - argv.reserve((args.size()+2)); - argv.push_back(name.c_str()); - - for (StrVector::const_iterator B = args.begin(), E = args.end(); - B!=E; ++B) { - if (*B == ">") { - ++B; - stdout_redirect.set(*B); - redirects[1] = &stdout_redirect; - } - else { - argv.push_back((*B).c_str()); - } - } - argv.push_back(0); // null terminate list. - - // Invoke the program. - return sys::Program::ExecuteAndWait(prog, &argv[0], 0, &redirects[0]); - } - - void print_string (const std::string& str) { - std::cerr << str << ' '; - } -} - -int llvmc::Action::Execute() const { - if (DryRun || VerboseMode) { - std::cerr << Command_ << " "; - std::for_each(Args_.begin(), Args_.end(), print_string); - std::cerr << '\n'; - } - if (DryRun) - return 0; - else - return ExecuteProgram(Command_, Args_); -} Removed: llvm/trunk/tools/llvmc2/driver/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/CMakeLists.txt?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/CMakeLists.txt (original) +++ llvm/trunk/tools/llvmc2/driver/CMakeLists.txt (removed) @@ -1,9 +0,0 @@ -set(LLVM_LINK_COMPONENTS support system) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvmc2 - Action.cpp - CompilationGraph.cpp - llvmc.cpp - Plugin.cpp - ) Removed: llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp (original) +++ llvm/trunk/tools/llvmc2/driver/CompilationGraph.cpp (removed) @@ -1,438 +0,0 @@ -//===--- CompilationGraph.cpp - The LLVM Compiler Driver --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Compilation graph - implementation. -// -//===----------------------------------------------------------------------===// - -#include "Error.h" -#include "llvm/CompilerDriver/CompilationGraph.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/GraphWriter.h" - -#include -#include -#include -#include -#include - -using namespace llvm; -using namespace llvmc; - -extern cl::list InputFilenames; -extern cl::opt OutputFilename; -extern cl::list Languages; - -namespace llvmc { - - const std::string& LanguageMap::GetLanguage(const sys::Path& File) const { - LanguageMap::const_iterator Lang = this->find(File.getSuffix()); - if (Lang == this->end()) - throw std::runtime_error("Unknown suffix: " + File.getSuffix()); - return Lang->second; - } -} - -namespace { - - /// ChooseEdge - Return the edge with the maximum weight. - template - const Edge* ChooseEdge(const C& EdgesContainer, - const InputLanguagesSet& InLangs, - const std::string& NodeName = "root") { - const Edge* MaxEdge = 0; - unsigned MaxWeight = 0; - bool SingleMax = true; - - for (typename C::const_iterator B = EdgesContainer.begin(), - E = EdgesContainer.end(); B != E; ++B) { - const Edge* e = B->getPtr(); - unsigned EW = e->Weight(InLangs); - if (EW > MaxWeight) { - MaxEdge = e; - MaxWeight = EW; - SingleMax = true; - } else if (EW == MaxWeight) { - SingleMax = false; - } - } - - if (!SingleMax) - throw std::runtime_error("Node " + NodeName + - ": multiple maximal outward edges found!" - " Most probably a specification error."); - if (!MaxEdge) - throw std::runtime_error("Node " + NodeName + - ": no maximal outward edge found!" - " Most probably a specification error."); - return MaxEdge; - } - -} - -CompilationGraph::CompilationGraph() { - NodesMap["root"] = Node(this); -} - -Node& CompilationGraph::getNode(const std::string& ToolName) { - nodes_map_type::iterator I = NodesMap.find(ToolName); - if (I == NodesMap.end()) - throw std::runtime_error("Node " + ToolName + " is not in the graph"); - return I->second; -} - -const Node& CompilationGraph::getNode(const std::string& ToolName) const { - nodes_map_type::const_iterator I = NodesMap.find(ToolName); - if (I == NodesMap.end()) - throw std::runtime_error("Node " + ToolName + " is not in the graph!"); - return I->second; -} - -// Find the tools list corresponding to the given language name. -const CompilationGraph::tools_vector_type& -CompilationGraph::getToolsVector(const std::string& LangName) const -{ - tools_map_type::const_iterator I = ToolsMap.find(LangName); - if (I == ToolsMap.end()) - throw std::runtime_error("No tool corresponding to the language " - + LangName + " found"); - return I->second; -} - -void CompilationGraph::insertNode(Tool* V) { - if (NodesMap.count(V->Name()) == 0) - NodesMap[V->Name()] = Node(this, V); -} - -void CompilationGraph::insertEdge(const std::string& A, Edge* Edg) { - Node& B = getNode(Edg->ToolName()); - if (A == "root") { - const char** InLangs = B.ToolPtr->InputLanguages(); - for (;*InLangs; ++InLangs) - ToolsMap[*InLangs].push_back(IntrusiveRefCntPtr(Edg)); - NodesMap["root"].AddEdge(Edg); - } - else { - Node& N = getNode(A); - N.AddEdge(Edg); - } - // Increase the inward edge counter. - B.IncrInEdges(); -} - -namespace { - sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName, - const std::string& Suffix) { - sys::Path Out; - - // Make sure we don't end up with path names like '/file.o' if the - // TempDir is empty. - if (TempDir.empty()) { - Out.set(BaseName); - } - else { - Out = TempDir; - Out.appendComponent(BaseName); - } - Out.appendSuffix(Suffix); - // NOTE: makeUnique always *creates* a unique temporary file, - // which is good, since there will be no races. However, some - // tools do not like it when the output file already exists, so - // they have to be placated with -f or something like that. - Out.makeUnique(true, NULL); - return Out; - } -} - -// Pass input file through the chain until we bump into a Join node or -// a node that says that it is the last. -void CompilationGraph::PassThroughGraph (const sys::Path& InFile, - const Node* StartNode, - const InputLanguagesSet& InLangs, - const sys::Path& TempDir, - const LanguageMap& LangMap) const { - bool Last = false; - sys::Path In = InFile; - const Node* CurNode = StartNode; - - while(!Last) { - sys::Path Out; - Tool* CurTool = CurNode->ToolPtr.getPtr(); - - if (CurTool->IsJoin()) { - JoinTool& JT = dynamic_cast(*CurTool); - JT.AddToJoinList(In); - break; - } - - // Since toolchains do not have to end with a Join node, we should - // check if this Node is the last. - if (!CurNode->HasChildren() || CurTool->IsLast()) { - if (!OutputFilename.empty()) { - Out.set(OutputFilename); - } - else { - Out.set(In.getBasename()); - Out.appendSuffix(CurTool->OutputSuffix()); - } - Last = true; - } - else { - Out = MakeTempFile(TempDir, In.getBasename(), CurTool->OutputSuffix()); - } - - if (int ret = CurTool->GenerateAction(In, Out, InLangs, LangMap).Execute()) - throw error_code(ret); - - if (Last) - return; - - CurNode = &getNode(ChooseEdge(CurNode->OutEdges, - InLangs, - CurNode->Name())->ToolName()); - In = Out; Out.clear(); - } -} - -// Find the head of the toolchain corresponding to the given file. -// Also, insert an input language into InLangs. -const Node* CompilationGraph:: -FindToolChain(const sys::Path& In, const std::string* ForceLanguage, - InputLanguagesSet& InLangs, const LanguageMap& LangMap) const { - - // Determine the input language. - const std::string& InLanguage = - ForceLanguage ? *ForceLanguage : LangMap.GetLanguage(In); - - // Add the current input language to the input language set. - InLangs.insert(InLanguage); - - // Find the toolchain for the input language. - const tools_vector_type& TV = getToolsVector(InLanguage); - if (TV.empty()) - throw std::runtime_error("No toolchain corresponding to language " - + InLanguage + " found"); - return &getNode(ChooseEdge(TV, InLangs)->ToolName()); -} - -// Helper function used by Build(). -// Traverses initial portions of the toolchains (up to the first Join node). -// This function is also responsible for handling the -x option. -void CompilationGraph::BuildInitial (InputLanguagesSet& InLangs, - const sys::Path& TempDir, - const LanguageMap& LangMap) { - // This is related to -x option handling. - cl::list::const_iterator xIter = Languages.begin(), - xBegin = xIter, xEnd = Languages.end(); - bool xEmpty = true; - const std::string* xLanguage = 0; - unsigned xPos = 0, xPosNext = 0, filePos = 0; - - if (xIter != xEnd) { - xEmpty = false; - xPos = Languages.getPosition(xIter - xBegin); - cl::list::const_iterator xNext = llvm::next(xIter); - xPosNext = (xNext == xEnd) ? std::numeric_limits::max() - : Languages.getPosition(xNext - xBegin); - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - - // For each input file: - for (cl::list::const_iterator B = InputFilenames.begin(), - CB = B, E = InputFilenames.end(); B != E; ++B) { - sys::Path In = sys::Path(*B); - - // Code for handling the -x option. - // Output: std::string* xLanguage (can be NULL). - if (!xEmpty) { - filePos = InputFilenames.getPosition(B - CB); - - if (xPos < filePos) { - if (filePos < xPosNext) { - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - else { // filePos >= xPosNext - // Skip xIters while filePos > xPosNext - while (filePos > xPosNext) { - ++xIter; - xPos = xPosNext; - - cl::list::const_iterator xNext = llvm::next(xIter); - if (xNext == xEnd) - xPosNext = std::numeric_limits::max(); - else - xPosNext = Languages.getPosition(xNext - xBegin); - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - } - } - } - - // Find the toolchain corresponding to this file. - const Node* N = FindToolChain(In, xLanguage, InLangs, LangMap); - // Pass file through the chain starting at head. - PassThroughGraph(In, N, InLangs, TempDir, LangMap); - } -} - -// Sort the nodes in topological order. -void CompilationGraph::TopologicalSort(std::vector& Out) { - std::queue Q; - Q.push(&getNode("root")); - - while (!Q.empty()) { - const Node* A = Q.front(); - Q.pop(); - Out.push_back(A); - for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd(); - EB != EE; ++EB) { - Node* B = &getNode((*EB)->ToolName()); - B->DecrInEdges(); - if (B->HasNoInEdges()) - Q.push(B); - } - } -} - -namespace { - bool NotJoinNode(const Node* N) { - return N->ToolPtr ? !N->ToolPtr->IsJoin() : true; - } -} - -// Call TopologicalSort and filter the resulting list to include -// only Join nodes. -void CompilationGraph:: -TopologicalSortFilterJoinNodes(std::vector& Out) { - std::vector TopSorted; - TopologicalSort(TopSorted); - std::remove_copy_if(TopSorted.begin(), TopSorted.end(), - std::back_inserter(Out), NotJoinNode); -} - -int CompilationGraph::Build (const sys::Path& TempDir, - const LanguageMap& LangMap) { - - InputLanguagesSet InLangs; - - // Traverse initial parts of the toolchains and fill in InLangs. - BuildInitial(InLangs, TempDir, LangMap); - - std::vector JTV; - TopologicalSortFilterJoinNodes(JTV); - - // For all join nodes in topological order: - for (std::vector::iterator B = JTV.begin(), E = JTV.end(); - B != E; ++B) { - - sys::Path Out; - const Node* CurNode = *B; - JoinTool* JT = &dynamic_cast(*CurNode->ToolPtr.getPtr()); - bool IsLast = false; - - // Are there any files in the join list? - if (JT->JoinListEmpty()) - continue; - - // Is this the last tool in the toolchain? - // NOTE: we can process several toolchains in parallel. - if (!CurNode->HasChildren() || JT->IsLast()) { - if (OutputFilename.empty()) { - Out.set("a"); - Out.appendSuffix(JT->OutputSuffix()); - } - else - Out.set(OutputFilename); - IsLast = true; - } - else { - Out = MakeTempFile(TempDir, "tmp", JT->OutputSuffix()); - } - - if (int ret = JT->GenerateAction(Out, InLangs, LangMap).Execute()) - throw error_code(ret); - - if (!IsLast) { - const Node* NextNode = - &getNode(ChooseEdge(CurNode->OutEdges, InLangs, - CurNode->Name())->ToolName()); - PassThroughGraph(Out, NextNode, InLangs, TempDir, LangMap); - } - } - - return 0; -} - -// Code related to graph visualization. - -namespace llvm { - template <> - struct DOTGraphTraits - : public DefaultDOTGraphTraits - { - - template - static std::string getNodeLabel(const Node* N, const GraphType&) - { - if (N->ToolPtr) - if (N->ToolPtr->IsJoin()) - return N->Name() + "\n (join" + - (N->HasChildren() ? ")" - : std::string(": ") + N->ToolPtr->OutputLanguage() + ')'); - else - return N->Name(); - else - return "root"; - } - - template - static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) { - if (N->ToolPtr) { - return N->ToolPtr->OutputLanguage(); - } - else { - const char** InLangs = I->ToolPtr->InputLanguages(); - std::string ret; - - for (; *InLangs; ++InLangs) { - if (*(InLangs + 1)) { - ret += *InLangs; - ret += ", "; - } - else { - ret += *InLangs; - } - } - - return ret; - } - } - }; - -} - -void CompilationGraph::writeGraph() { - std::ofstream O("compilation-graph.dot"); - - if (O.good()) { - llvm::WriteGraph(this, "compilation-graph"); - O.close(); - } - else { - throw std::runtime_error("Error opening file 'compilation-graph.dot'" - " for writing!"); - } -} - -void CompilationGraph::viewGraph() { - llvm::ViewGraph(this, "compilation-graph"); -} Removed: llvm/trunk/tools/llvmc2/driver/Error.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/Error.h?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Error.h (original) +++ llvm/trunk/tools/llvmc2/driver/Error.h (removed) @@ -1,33 +0,0 @@ -//===--- Error.h - The LLVM Compiler Driver ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Exception classes for LLVMC. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMC2_ERROR_H -#define LLVM_TOOLS_LLVMC2_ERROR_H - -#include - -namespace llvmc { - - class error_code: public std::runtime_error { - int Code_; - public: - error_code (int c) - : std::runtime_error("Tool returned error code"), Code_(c) - {} - - int code() const { return Code_; } - }; - -} - -#endif //LLVM_TOOLS_LLVMC2_ERROR_H Removed: llvm/trunk/tools/llvmc2/driver/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Makefile (original) +++ llvm/trunk/tools/llvmc2/driver/Makefile (removed) @@ -1,19 +0,0 @@ -##===- tools/llvmc2/src/Makefile ---------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -TOOLNAME = $(DRIVER_NAME) -LINK_COMPONENTS = support system -REQUIRES_EH := 1 - -ifneq ($(BUILTIN_PLUGINS),) -USEDLIBS = $(patsubst %,LLVMC%,$(BUILTIN_PLUGINS)) -endif - -include $(LEVEL)/Makefile.common Removed: llvm/trunk/tools/llvmc2/driver/Plugin.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/Plugin.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/Plugin.cpp (original) +++ llvm/trunk/tools/llvmc2/driver/Plugin.cpp (removed) @@ -1,73 +0,0 @@ -//===--- Plugin.cpp - The LLVM Compiler Driver ------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Plugin support for llvmc2. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/Plugin.h" - -#include -#include - -namespace { - - // Registry::Add<> does not do lifetime management (probably issues - // with static constructor/destructor ordering), so we have to - // implement it here. - // - // All this static registration/life-before-main model seems - // unnecessary convoluted to me. - - static bool pluginListInitialized = false; - typedef std::vector PluginList; - static PluginList Plugins; - - struct ByPriority { - bool operator()(const llvmc::BasePlugin* lhs, - const llvmc::BasePlugin* rhs) { - return lhs->Priority() < rhs->Priority(); - } - }; -} - -namespace llvmc { - - PluginLoader::PluginLoader() { - if (!pluginListInitialized) { - for (PluginRegistry::iterator B = PluginRegistry::begin(), - E = PluginRegistry::end(); B != E; ++B) - Plugins.push_back(B->instantiate()); - std::sort(Plugins.begin(), Plugins.end(), ByPriority()); - } - pluginListInitialized = true; - } - - PluginLoader::~PluginLoader() { - if (pluginListInitialized) { - for (PluginList::iterator B = Plugins.begin(), E = Plugins.end(); - B != E; ++B) - delete (*B); - } - pluginListInitialized = false; - } - - void PluginLoader::PopulateLanguageMap(LanguageMap& langMap) { - for (PluginList::iterator B = Plugins.begin(), E = Plugins.end(); - B != E; ++B) - (*B)->PopulateLanguageMap(langMap); - } - - void PluginLoader::PopulateCompilationGraph(CompilationGraph& graph) { - for (PluginList::iterator B = Plugins.begin(), E = Plugins.end(); - B != E; ++B) - (*B)->PopulateCompilationGraph(graph); - } - -} Removed: llvm/trunk/tools/llvmc2/driver/llvmc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/driver/llvmc.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/driver/llvmc.cpp (original) +++ llvm/trunk/tools/llvmc2/driver/llvmc.cpp (removed) @@ -1,119 +0,0 @@ -//===--- llvmc.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tool provides a single point of access to the LLVM -// compilation tools. It has many options. To discover the options -// supported please refer to the tools' manual page or run the tool -// with the --help option. -// -//===----------------------------------------------------------------------===// - -#include "Error.h" - -#include "llvm/CompilerDriver/CompilationGraph.h" -#include "llvm/CompilerDriver/Plugin.h" - -#include "llvm/System/Path.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/PluginLoader.h" - -#include -#include -#include - -namespace cl = llvm::cl; -namespace sys = llvm::sys; -using namespace llvmc; - -// Built-in command-line options. -// External linkage here is intentional. - -cl::list InputFilenames(cl::Positional, cl::desc(""), - cl::ZeroOrMore); -cl::opt OutputFilename("o", cl::desc("Output file name"), - cl::value_desc("file")); -cl::list Languages("x", - cl::desc("Specify the language of the following input files"), - cl::ZeroOrMore); -cl::opt DryRun("dry-run", - cl::desc("Only pretend to run commands")); -cl::opt VerboseMode("v", - cl::desc("Enable verbose mode")); -cl::opt WriteGraph("write-graph", - cl::desc("Write compilation-graph.dot file"), - cl::Hidden); -cl::opt ViewGraph("view-graph", - cl::desc("Show compilation graph in GhostView"), - cl::Hidden); -cl::opt SaveTemps("save-temps", - cl::desc("Keep temporary files"), - cl::Hidden); - -namespace { - /// BuildTargets - A small wrapper for CompilationGraph::Build. - int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) { - int ret; - const sys::Path& tempDir = SaveTemps - ? sys::Path("") - : sys::Path(sys::Path::GetTemporaryDirectory()); - - try { - ret = graph.Build(tempDir, langMap); - } - catch(...) { - tempDir.eraseFromDisk(true); - throw; - } - - if (!SaveTemps) - tempDir.eraseFromDisk(true); - return ret; - } -} - -int main(int argc, char** argv) { - try { - LanguageMap langMap; - CompilationGraph graph; - - cl::ParseCommandLineOptions - (argc, argv, "LLVM Compiler Driver (Work In Progress)", true); - - PluginLoader Plugins; - Plugins.PopulateLanguageMap(langMap); - Plugins.PopulateCompilationGraph(graph); - - if (WriteGraph) { - graph.writeGraph(); - if (!ViewGraph) - return 0; - } - - if (ViewGraph) { - graph.viewGraph(); - return 0; - } - - if (InputFilenames.empty()) { - throw std::runtime_error("no input files"); - } - - return BuildTargets(graph, langMap); - } - catch(llvmc::error_code& ec) { - return ec.code(); - } - catch(const std::exception& ex) { - std::cerr << argv[0] << ": " << ex.what() << '\n'; - } - catch(...) { - std::cerr << argv[0] << ": unknown error!\n"; - } - return 1; -} Removed: llvm/trunk/tools/llvmc2/plugins/Base/Base.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Base/Base.td?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Base/Base.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Base/Base.td (removed) @@ -1,59 +0,0 @@ -//===- Base.td - LLVMC2 toolchain descriptions -------------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc2. -// -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" -include "llvm/CompilerDriver/Tools.td" - -// Toolchains - -def CompilationGraph : CompilationGraph<[ - Edge<"root", "llvm_gcc_c">, - Edge<"root", "llvm_gcc_assembler">, - Edge<"root", "llvm_gcc_cpp">, - Edge<"root", "llvm_gcc_m">, - Edge<"root", "llvm_gcc_mxx">, - Edge<"root", "llvm_as">, - - Edge<"llvm_gcc_c", "llc">, - Edge<"llvm_gcc_cpp", "llc">, - Edge<"llvm_gcc_m", "llc">, - Edge<"llvm_gcc_mxx", "llc">, - Edge<"llvm_as", "llc">, - - OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_m", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_gcc_mxx", "opt", (case (switch_on "opt"), (inc_weight))>, - OptionalEdge<"llvm_as", "opt", (case (switch_on "opt"), (inc_weight))>, - Edge<"opt", "llc">, - - Edge<"llc", "llvm_gcc_assembler">, - Edge<"llvm_gcc_assembler", "llvm_gcc_linker">, - OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))>, - - - Edge<"root", "llvm_gcc_linker">, - OptionalEdge<"root", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))> - ]>; Removed: llvm/trunk/tools/llvmc2/plugins/Base/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Base/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Base/Makefile (original) +++ llvm/trunk/tools/llvmc2/plugins/Base/Makefile (removed) @@ -1,13 +0,0 @@ -##===- tools/llvmc2/plugins/Base/Makefile ------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLVMC_PLUGIN = Base -BUILT_SOURCES = AutoGenerated.inc - -include ../Makefile Removed: llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp (original) +++ llvm/trunk/tools/llvmc2/plugins/Base/PluginMain.cpp (removed) @@ -1 +0,0 @@ -#include "AutoGenerated.inc" Removed: llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td (removed) @@ -1,86 +0,0 @@ -// A (first stab at a) replacement for the Clang's ccc script. -// To compile, use this command: -// cd $LLVMC2_DIR -// make DRIVER_NAME=ccc2 BUILTIN_PLUGINS=Clang - -include "llvm/CompilerDriver/Common.td" - - -def Options : OptionList<[ -(switch_option "E", - (help "Stop after the preprocessing stage, do not run the compiler")) -]>; - -class clang_base : Tool< -[(in_language language), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (cmd_line cmdline), - (switch_option "E", (stop_compilation), (output_suffix "i")), - (sink) -]>; - -def clang_c : clang_base<"c", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x c $INFILE -o $OUTFILE", - (default), - "clang -E -x c $INFILE"), -(default), - "clang -emit-llvm-bc -x c $INFILE -o $OUTFILE")>; - -def clang_cpp : clang_base<"c++", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x c++ $INFILE -o $OUTFILE", - (default), - "clang -E -x c++ $INFILE"), -(default), - "clang -emit-llvm-bc -x c++ $INFILE -o $OUTFILE")>; - -def clang_objective_c : clang_base<"objective-c", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x objective-c $INFILE -o $OUTFILE", - (default), - "clang -E -x objective-c $INFILE"), -(default), - "clang -emit-llvm-bc -x objective-c $INFILE -o $OUTFILE")>; - -// Default linker -def llvm_ld : Tool< -[(in_language "llvm-bitcode"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "llvm-ld -native -disable-internalize $INFILE -o $OUTFILE"), - (prefix_list_option "L", (forward), (help "Specify a library search path")), - (join) -]>; - -// Language map - -def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c", ["c"]>, - LangToSuffixes<"objective-c", ["m"]>, - LangToSuffixes<"c-cpp-output", ["i"]>, - LangToSuffixes<"objective-c-cpp-output", ["mi"]> - ]>; - -// Compilation graph - -def CompilationGraph : CompilationGraph<[ - Edge<"root", "clang_c">, - Edge<"root", "clang_cpp">, - Edge<"root", "clang_objective_c">, - Edge<"clang_c", "llvm_ld">, - Edge<"clang_cpp", "llvm_ld">, - Edge<"clang_objective_c", "llvm_ld"> - ]>; - Removed: llvm/trunk/tools/llvmc2/plugins/Clang/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Clang/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/Makefile (original) +++ llvm/trunk/tools/llvmc2/plugins/Clang/Makefile (removed) @@ -1,14 +0,0 @@ -##===- tools/llvmc2/plugins/Clang/Makefile -----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLVMC_PLUGIN = Clang -BUILT_SOURCES = AutoGenerated.inc - -include ../Makefile - Removed: llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp (original) +++ llvm/trunk/tools/llvmc2/plugins/Clang/PluginMain.cpp (removed) @@ -1 +0,0 @@ -#include "AutoGenerated.inc" Removed: llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp (original) +++ llvm/trunk/tools/llvmc2/plugins/Hello/Hello.cpp (removed) @@ -1,32 +0,0 @@ -//===- Hello.cpp - Example code from "Writing an LLVM Pass" ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Test plugin for LLVMC. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/CompilationGraph.h" -#include "llvm/CompilerDriver/Plugin.h" - -#include - -namespace { -struct MyPlugin : public llvmc::BasePlugin { - void PopulateLanguageMap(llvmc::LanguageMap&) const - { std::cout << "Hello!\n"; } - - void PopulateCompilationGraph(llvmc::CompilationGraph&) const - {} -}; - -static llvmc::RegisterPlugin RP("Hello", "Hello World plugin"); - -} - - Removed: llvm/trunk/tools/llvmc2/plugins/Hello/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Hello/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Hello/Makefile (original) +++ llvm/trunk/tools/llvmc2/plugins/Hello/Makefile (removed) @@ -1,12 +0,0 @@ -##===- tools/llvmc2/plugins/Hello/Makefile -----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLVMC_PLUGIN = Hello - -include ../Makefile Removed: llvm/trunk/tools/llvmc2/plugins/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Makefile (original) +++ llvm/trunk/tools/llvmc2/plugins/Makefile (removed) @@ -1,55 +0,0 @@ -##===- tools/llvmc2/plugins/Makefile.plugins ----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -ifndef LLVMC_PLUGIN - -LEVEL = ../../.. -DIRS = $(BUILTIN_PLUGINS) - -# TOFIX: Should we also build DSO versions of plugins? -export BUILTIN_LLVMC_PLUGIN=1 - -include $(LEVEL)/Makefile.common - -else # LLVMC_PLUGIN - -LEVEL = ../../../.. - -LIBRARYNAME := $(patsubst %,LLVMC%,$(LLVMC_PLUGIN)) -REQUIRES_EH = 1 - -ifndef BUILTIN_LLVMC_PLUGIN -LOADABLE_MODULE = 1 -endif - -ifneq ($(BUILT_SOURCES),) -BUILD_AUTOGENERATED_INC=1 -endif - -include $(LEVEL)/Makefile.common - -# TOFIX: This probably should go into Makefile.rules - -ifdef BUILD_AUTOGENERATED_INC - -TOOLS_SOURCE := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) - -TD_COMMON :=$(strip $(wildcard \ - $(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td)) - -$(ObjDir)/AutoGenerated.inc.tmp: $(TOOLS_SOURCE) $(ObjDir)/.dir \ - $(TBLGEN) $(TD_COMMON) - $(Echo) "Building LLVMC configuration library with tblgen" - $(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $< - -AutoGenerated.inc : $(ObjDir)/AutoGenerated.inc.tmp - $(Verb) $(CMP) -s $@ $< || $(CP) $< $@ -endif # BUILD_AUTOGENERATED_INC - -endif # LLVMC_PLUGIN Removed: llvm/trunk/tools/llvmc2/plugins/Simple/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Simple/Makefile?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Simple/Makefile (original) +++ llvm/trunk/tools/llvmc2/plugins/Simple/Makefile (removed) @@ -1,13 +0,0 @@ -##===- tools/llvmc2/plugins/Simple/Makefile ------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLVMC_PLUGIN = Simple -BUILT_SOURCES = AutoGenerated.inc - -include ../Makefile Removed: llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp (original) +++ llvm/trunk/tools/llvmc2/plugins/Simple/PluginMain.cpp (removed) @@ -1 +0,0 @@ -#include "AutoGenerated.inc" Removed: llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td?rev=60047&view=auto ============================================================================== --- llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td (original) +++ llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td (removed) @@ -1,30 +0,0 @@ -// A simple wrapper for gcc. -// To compile, use this command: -// -// $ cd $LLVMC2_DIR -// $ make DRIVER_NAME=mygcc BUILTIN_PLUGINS=Simple -// -// To build this plugin as a dynamic library: -// -// $ cd $LLVMC2_DIR -// $ make BUILTIN_PLUGINS="" -// $ cd plugins/Simple -// $ make -// -// Run as: -// -// $ llvmc2 -load $LLVM_DIR/Release/lib/LLVMCSimple.so - -include "llvm/CompilerDriver/Common.td" - -def gcc : Tool< -[(in_language "c"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "gcc $INFILE -o $OUTFILE"), - (sink) -]>; - -def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; - -def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; From foldr at codedgers.com Tue Nov 25 15:38:38 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 25 Nov 2008 21:38:38 -0000 Subject: [llvm-commits] [llvm] r60049 - in /llvm/trunk/docs/CommandGuide: index.html llvmc.pod Message-ID: <200811252138.mAPLcclF024850@zion.cs.uiuc.edu> Author: foldr Date: Tue Nov 25 15:38:38 2008 New Revision: 60049 URL: http://llvm.org/viewvc/llvm-project?rev=60049&view=rev Log: Add a man page for llvmc. Really basic for now, will be updated later. Added: llvm/trunk/docs/CommandGuide/llvmc.pod Modified: llvm/trunk/docs/CommandGuide/index.html Modified: llvm/trunk/docs/CommandGuide/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/index.html?rev=60049&r1=60048&r2=60049&view=diff ============================================================================== --- llvm/trunk/docs/CommandGuide/index.html (original) +++ llvm/trunk/docs/CommandGuide/index.html Tue Nov 25 15:38:38 2008 @@ -15,8 +15,8 @@

    These documents are HTML versions of the man pages for all of the LLVM tools. These pages describe how to use the LLVM commands -and what their options are. Note that these pages do not describe all of the -options available for all tools. To get a complete listing, pass the +and what their options are. Note that these pages do not describe all of the +options available for all tools. To get a complete listing, pass the --help (general options) or --help-hidden (general+debugging options) arguments to the tool you are interested in.

    @@ -32,7 +32,7 @@
      -
    • llvm-as - +
    • llvm-as - assemble a human-readable .ll file into bytecode
    • llvm-dis - @@ -41,20 +41,20 @@
    • opt - run a series of LLVM-to-LLVM optimizations on a bytecode file
    • -
    • llc - +
    • llc - generate native machine code for a bytecode file
    • -
    • lli - - directly run a program compiled to bytecode using a JIT compiler or +
    • lli - + directly run a program compiled to bytecode using a JIT compiler or interpreter
    • llvm-link - link several bytecode files into one
    • -
    • llvm-ar - +
    • llvm-ar - archive bytecode files
    • -
    • llvm-ranlib - +
    • llvm-ranlib - create an index for archives made with llvm-ar
    • llvm-nm - @@ -66,9 +66,12 @@
    • llvm-ld - general purpose linker with loadable runtime optimization support
    • -
    • llvm-config - +
    • llvm-config - print out LLVM compilation options, libraries, etc. as configured.
    • +
    • llvmc - a generic +customizable compiler driver.
    • +
  • Added: llvm/trunk/docs/CommandGuide/llvmc.pod URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvmc.pod?rev=60049&view=auto ============================================================================== --- llvm/trunk/docs/CommandGuide/llvmc.pod (added) +++ llvm/trunk/docs/CommandGuide/llvmc.pod Tue Nov 25 15:38:38 2008 @@ -0,0 +1,70 @@ +=pod + +=head1 NAME + +llvmc - The LLVM Compiler Driver (WIP) + +=head1 SYNOPSIS + +B [I] I + +=head1 DESCRIPTION + +B is a configurable driver for invoking other LLVM (and non-LLVM) tools +in order to compile, optimize and link software for multiple languages. For +those familiar with FSF's B tool, it is very similar. Please note that +B is considered an experimental tool. + +=head1 OPTIONS + +=over + +=item B<--help> + +Print a summary of command line options. + +=item B<-o> I + +Specify the output file to be I. + +=item B<-I> I + +Add a directory to the header file search path. This option can be +repeated. + +=item B<-L> I + +Add I to the library search path. This option can be +repeated. + +=item B<-l>I + +Link in the library libI.[bc | a | so]. This library should +be a bitcode library. + +=item B<-emit-llvm> + +Make the output be LLVM bitcode (with B<-c>) or assembly (with B<-s>) instead +of native object (or assembly). If B<-emit-llvm> is given without either B<-c> +or B<-S> it has no effect. + +=back + +=head1 EXIT STATUS + +If B succeeds, it will exit with 0. Otherwise, if an error +occurs, it will exit with a non-zero value. If one of the compilation +tools returns a non-zero status, pending actions will be discarded and +B will return the same result code as the failing compilation +tool. + +=head1 SEE ALSO + +L, L, L, +L, L, L + +=head1 AUTHORS + +Maintained by the LLVM Team (L). + +=cut From ofv at wanadoo.es Tue Nov 25 16:18:50 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 25 Nov 2008 22:18:50 -0000 Subject: [llvm-commits] [llvm] r60052 - in /llvm/trunk/tools: CMakeLists.txt llvmc/driver/CMakeLists.txt Message-ID: <200811252218.mAPMIoN4026461@zion.cs.uiuc.edu> Author: ofv Date: Tue Nov 25 16:18:49 2008 New Revision: 60052 URL: http://llvm.org/viewvc/llvm-project?rev=60052&view=rev Log: CMake: llvmc2 is now known as llvmc. Modified: llvm/trunk/tools/CMakeLists.txt llvm/trunk/tools/llvmc/driver/CMakeLists.txt Modified: llvm/trunk/tools/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=60052&r1=60051&r2=60052&view=diff ============================================================================== --- llvm/trunk/tools/CMakeLists.txt (original) +++ llvm/trunk/tools/CMakeLists.txt Tue Nov 25 16:18:49 2008 @@ -29,7 +29,7 @@ add_subdirectory(bugpoint) add_subdirectory(llvm-bcanalyzer) add_subdirectory(llvm-stub) -add_subdirectory(llvmc2) +add_subdirectory(llvmc) if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/clang/CMakeLists.txt ) add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/clang ) Modified: llvm/trunk/tools/llvmc/driver/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CMakeLists.txt?rev=60052&r1=60051&r2=60052&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/driver/CMakeLists.txt (original) +++ llvm/trunk/tools/llvmc/driver/CMakeLists.txt Tue Nov 25 16:18:49 2008 @@ -1,7 +1,7 @@ set(LLVM_LINK_COMPONENTS support system) set(LLVM_REQUIRES_EH 1) -add_llvm_tool(llvmc2 +add_llvm_tool(llvmc Action.cpp CompilationGraph.cpp llvmc.cpp From isanbard at gmail.com Tue Nov 25 16:19:23 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:19:23 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60053 - /llvm-gcc-4.2/trunk/gcc/doc/invoke.texi Message-ID: <200811252219.mAPMJNgE026495@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:19:22 2008 New Revision: 60053 URL: http://llvm.org/viewvc/llvm-project?rev=60053&view=rev Log: Fix man page formatting. Modified: llvm-gcc-4.2/trunk/gcc/doc/invoke.texi Modified: llvm-gcc-4.2/trunk/gcc/doc/invoke.texi URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/doc/invoke.texi?rev=60053&r1=60052&r2=60053&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/doc/invoke.texi (original) +++ llvm-gcc-4.2/trunk/gcc/doc/invoke.texi Tue Nov 25 16:19:22 2008 @@ -3257,7 +3257,8 @@ will require, in particular when determining whether a loop will be executed at all. - at table @option + at c APPLE LOCAL mainline man page 6365204 + at table @gcctabopt @item -Wstrict-overflow=1 Warn about cases which are both questionable and easy to avoid. For example: @code{x + 1 > x}; with @option{-fstrict-overflow}, the From ofv at wanadoo.es Tue Nov 25 16:19:49 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 25 Nov 2008 22:19:49 -0000 Subject: [llvm-commits] [llvm] r60054 - /llvm/trunk/tools/llvmc2/ Message-ID: <200811252219.mAPMJn2b026524@zion.cs.uiuc.edu> Author: ofv Date: Tue Nov 25 16:19:48 2008 New Revision: 60054 URL: http://llvm.org/viewvc/llvm-project?rev=60054&view=rev Log: CMake: Removed tools/llvmc2 directory hierarchy. Removed: llvm/trunk/tools/llvmc2/ From isanbard at gmail.com Tue Nov 25 16:19:59 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:19:59 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60055 - /llvm-gcc-4.2/trunk/gcc/final.c Message-ID: <200811252219.mAPMJxJu026539@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:19:59 2008 New Revision: 60055 URL: http://llvm.org/viewvc/llvm-project?rev=60055&view=rev Log: Update comments. Modified: llvm-gcc-4.2/trunk/gcc/final.c Modified: llvm-gcc-4.2/trunk/gcc/final.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/final.c?rev=60055&r1=60054&r2=60055&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/final.c (original) +++ llvm-gcc-4.2/trunk/gcc/final.c Tue Nov 25 16:19:59 2008 @@ -255,11 +255,12 @@ static tree get_mem_expr_from_op (rtx, int *); static void output_asm_operand_names (rtx *, int *, int); static void output_operand (rtx, int); -/* APPLE LOCAL - begin ARM compact switch tables */ +/* LLVM LOCAL begin */ #ifndef ENABLE_LLVM +/* APPLE LOCAL ARM compact switch tables */ static void calculate_alignments (void); #endif -/* APPLE LOCAL - end ARM compact switch tables */ +/* LLVM LOCAL end */ #ifdef LEAF_REGISTERS static void leaf_renumber_regs (rtx); #endif From isanbard at gmail.com Tue Nov 25 16:21:03 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:21:03 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60056 - /llvm-gcc-4.2/trunk/gcc/gcc.c Message-ID: <200811252221.mAPML3WA026600@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:21:02 2008 New Revision: 60056 URL: http://llvm.org/viewvc/llvm-project?rev=60056&view=rev Log: Turn off for Mach-O targets. Modified: llvm-gcc-4.2/trunk/gcc/gcc.c Modified: llvm-gcc-4.2/trunk/gcc/gcc.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/gcc.c?rev=60056&r1=60055&r2=60056&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/gcc.c (original) +++ llvm-gcc-4.2/trunk/gcc/gcc.c Tue Nov 25 16:21:02 2008 @@ -3703,7 +3703,7 @@ if (is_cpp_driver) add_preprocessor_option ("--help", 6); /* APPLE LOCAL begin verbose help 2920964 */ -#if 0 +#if !TARGET_MACHO /* Our assembler and linkder do not support --help. */ /* APPLE LOCAL end verbose help 2920964 */ add_assembler_option ("--help", 6); From isanbard at gmail.com Tue Nov 25 16:23:35 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:23:35 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60059 - /llvm-gcc-4.2/trunk/gcc/gimplify.c Message-ID: <200811252223.mAPMNaQL026789@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:23:35 2008 New Revision: 60059 URL: http://llvm.org/viewvc/llvm-project?rev=60059&view=rev Log: Whitespace fix. Modified: llvm-gcc-4.2/trunk/gcc/gimplify.c Modified: llvm-gcc-4.2/trunk/gcc/gimplify.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/gimplify.c?rev=60059&r1=60058&r2=60059&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/gimplify.c (original) +++ llvm-gcc-4.2/trunk/gcc/gimplify.c Tue Nov 25 16:23:35 2008 @@ -180,7 +180,7 @@ #ifndef ENABLE_LLVM /* LLVM wants to know about gimple formal temps. */ for (t = c->temps; t ; t = TREE_CHAIN (t)) - DECL_GIMPLE_FORMAL_TEMP_P (t) = 0; + DECL_GIMPLE_FORMAL_TEMP_P (t) = 0; #else t = 0; #endif From isanbard at gmail.com Tue Nov 25 16:24:50 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:24:50 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60060 - /llvm-gcc-4.2/trunk/gcc/config/darwin.c Message-ID: <200811252224.mAPMOpi5026846@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:24:50 2008 New Revision: 60060 URL: http://llvm.org/viewvc/llvm-project?rev=60060&view=rev Log: Update to correct section type. Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.c Modified: llvm-gcc-4.2/trunk/gcc/config/darwin.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin.c?rev=60060&r1=60059&r2=60060&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin.c Tue Nov 25 16:24:50 2008 @@ -1533,7 +1533,8 @@ return darwin_sections[objc_v2_message_refs_section]; else if (!strncmp (name, "_OBJC_LABEL_CLASS_", 18)) return darwin_sections[objc_v2_classlist_section]; - else if (!strncmp (name, "_OBJC_LABEL_PROTOCOL_", 21)) + /* APPLE LOCAL radar 6351990 */ + else if (!strncmp (name, "l_OBJC_LABEL_PROTOCOL_", 22)) return darwin_sections[objc_v2_protocollist_section]; else if (!strncmp (name, "_OBJC_LABEL_CATEGORY_", 21)) return darwin_sections[objc_v2_categorylist_section]; @@ -1718,7 +1719,7 @@ else if (!strncmp (name, "LABEL_CLASS_", 12)) return "__DATA, __objc_classlist, regular, no_dead_strip"; else if (!strncmp (name, "LABEL_PROTOCOL_", 15)) - return "__DATA, __objc_protolist, regular, no_dead_strip"; + return "__DATA, __objc_protolist, coalesced, no_dead_strip"; else if (!strncmp (name, "LABEL_CATEGORY_", 15)) return "__DATA, __objc_catlist, regular, no_dead_strip"; else if (!strncmp (name, "LABEL_NONLAZY_CLASS_", 20)) @@ -1726,7 +1727,7 @@ else if (!strncmp (name, "LABEL_NONLAZY_CATEGORY_", 23)) return "__DATA, __objc_nlcatlist, regular, no_dead_strip"; else if (!strncmp (name, "PROTOCOL_REFERENCE_", 19)) - return "__DATA, __objc_protorefs, regular, no_dead_strip"; + return "__DATA, __objc_protorefs, coalesced, no_dead_strip"; else if (!strncmp (name, "SELECTOR_REFERENCES", 19)) return "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"; else if (!strncmp (name, "IMAGE_INFO", 10)) From isanbard at gmail.com Tue Nov 25 16:26:24 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 22:26:24 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60061 - in /llvm-gcc-4.2/trunk: gcc/ gcc/config/ gcc/config/arm/ gcc/config/i386/ gcc/cp/ gcc/objc/ gcc/testsuite/g++.apple/ gcc/testsuite/gcc.apple/ gcc/testsuite/gcc.target/i386/ gcc/testsuite/obj-c++.dg/ gcc/testsuite/objc.dg/ libcpp/ libcpp/include/ Message-ID: <200811252226.mAPMQTCW027010@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 16:26:23 2008 New Revision: 60061 URL: http://llvm.org/viewvc/llvm-project?rev=60061&view=rev Log: Update to latest GCC version. This includes a lot of "blocks" fixes. Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-67.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblock.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblockassign.C llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-67.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblock.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblockassign.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/i386/4299257.c llvm-gcc-4.2/trunk/gcc/testsuite/obj-c++.dg/objc2-objc2-protocol-3.mm llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/objc2-objc2-protocol-3.m llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/ok-unimplemented-anon-category.m Modified: llvm-gcc-4.2/trunk/gcc/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/c-common.c llvm-gcc-4.2/trunk/gcc/c-common.h llvm-gcc-4.2/trunk/gcc/c-decl.c llvm-gcc-4.2/trunk/gcc/c-lex.c llvm-gcc-4.2/trunk/gcc/c-objc-common.h llvm-gcc-4.2/trunk/gcc/c-parser.c llvm-gcc-4.2/trunk/gcc/c-pragma.h llvm-gcc-4.2/trunk/gcc/config.host llvm-gcc-4.2/trunk/gcc/config/arm/arm.c llvm-gcc-4.2/trunk/gcc/config/darwin-c.c llvm-gcc-4.2/trunk/gcc/config/darwin-sections.def llvm-gcc-4.2/trunk/gcc/config/i386/i386.c llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md llvm-gcc-4.2/trunk/gcc/cp/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/cp/cp-objcp-common.h llvm-gcc-4.2/trunk/gcc/cp/decl.c llvm-gcc-4.2/trunk/gcc/cp/parser.c llvm-gcc-4.2/trunk/gcc/langhooks-def.h llvm-gcc-4.2/trunk/gcc/langhooks.c llvm-gcc-4.2/trunk/gcc/langhooks.h llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/objc/objc-act.c llvm-gcc-4.2/trunk/gcc/stub-objc.c llvm-gcc-4.2/trunk/gcc/tree.c llvm-gcc-4.2/trunk/gcc/tree.h llvm-gcc-4.2/trunk/gcc/version.c llvm-gcc-4.2/trunk/libcpp/expr.c llvm-gcc-4.2/trunk/libcpp/include/cpplib.h Modified: llvm-gcc-4.2/trunk/gcc/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ChangeLog.apple?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/ChangeLog.apple Tue Nov 25 16:26:23 2008 @@ -1,3 +1,100 @@ +2008-11-18 Stuart Hastings + + Radar 6353006 + * tree.c (generic_block_literal_struct_type): Fix APPLE LOCAL. + * langhooks-def.h (lhd_build_generic_block_struct_type): Fix + APPLE LOCAL. + +2008-11-12 Caroline Tice + + * tree.c (generic_block_literal_struct_type): Move global variable + decl here from c-common.c. + (build_block_pointer_type): Change call to + build_generic_block_struct_type to go through lang_hooks. + * tree.h: Remove extern function dec, for + build_generic_block_struct_type. + * cp/cp-objcp-common.h: Define c++-specific version of + LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE. + * cp/parser.c (build_generic_block_struct_type): Rename function to + c_build_generic_block_struct_type. + * c-objc-common.h: Define c-specific version of + LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE. + * langhooks.c (lhd_build_generic_block_struct_type): New generic + function. + * langhooks.h (struct lang_hooks): Add new function field, + build_generic_block_struct_type. + * c-common.c (generic_block_literal_struct_type): Move global variable + decl from here to tree.c. + * c-common.h (c_build_generic_block_struct_type): New extern + function decl. + * c-parser.c (build_generic_block_struct_type): Rename function to + c_build_generic_block_struct_type. + * langhooks-def.h (lhd_build_generic_block_struct_type): New extern + function decl. + (LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE): New variable + definition. + (LANG_HOOKS_INITIALIZER): Initialize new field to + LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE + +2008-11-11 Fariborz Jahanian + + Radar 6351990 + * config/darwin.c (machopic_select_section): Accomodate change + for meta-data prefix name. + * config/darwin-sections.def (__objc_protorefs, __objc_protolist): + These sections are now coalesced. + +2008-11-11 Stuart Hastings + + Radar 4299257 + * config/i386/i386.c (bdesc_com): Move ucomXX instructions + from here... (bdesc_ucomi): ...to here. New. + (ix86_init_mmx_sse_builtins): Add a loop to walk + bdesc_ucomi[] and instantiate ucomiXX builtins. + (ix86_expand_sse_ucomi): New. (ix86_expand_builtin): Call + it. + +2008-11-07 Fariborz Jahanian + + Radar 5847976 + * c-decl.c (synth_block_byref_id_object_copy_func): Takes a new + 'flag' argument and generates the much simplified API. + (synth_block_byref_id_object_dispose_func): Ditto. + (new_block_byref_decl): Hack to prevent issuing bogus warning + on a field declared as __weak. + (init_byref_decl): Takes an additional 'flag' argument + and passes it down to synth_block_byref_id_object_copy_func and + synth_block_byref_id_object_dispose_func. + (finish_decl): Computes the flag for the block variable declaration. + * c-common.c (build_block_byref_release_decl, + build_block_byref_assign_copy_decl): Removed. + (build_block_byref_release_exp): Use the new API. + (build_block_object_assign_decl, build_block_object_assign_call_exp, + build_block_object_dispose_decl, build_block_object_dispose_call_exp): New. + (build_indirect_object_id_exp): Fixed a code gen bug which was exposed in + c/c++ mode, but not in ObjC/ObjC++ mode. + * c-common.h (build_block_object_assign_call_exp, + build_block_object_dispose_call_exp, + objc_is_gcable_type): New decls. + Declaration of several new flags. + (cast_to_pointer_to_id): Removed. + * stub-objc.c (objc_is_gcable_type): New + (copy_in_object, retain_block_component, release_block_component): Removed. + (cast_to_pointer_to_id): Removed. + * c-parser.c (build_block_struct_initlist): Remove call to copy_in_object. + (synth_copy_helper_block_func): Generates much simplified API. + (synth_destroy_helper_block_func): Ditto. + (block_object_dispose): Removed. + * config/darwin-c.c (darwin_cpp_builtins): Define __weak even when + -fobjc-gc is off. + +2008-11-4 Jim Grosbach + + Radar 6327222 + * config/arm/arm.c (legitimize_pic_address): Be more generous about + constants when the operand is of the form (const (plus (something) + (const)). + 2008-10-31 Stuart Hastings Radar 5813921 Modified: llvm-gcc-4.2/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.c Tue Nov 25 16:26:23 2008 @@ -6161,7 +6161,7 @@ /* APPLE LOCAL begin blocks 6040305 */ /* This routine builds: - *(id *)(EXP+20) expression which references the object id pointer. + *(void **)(EXP+20) expression which references the object pointer. */ tree build_indirect_object_id_exp (tree exp) @@ -6169,7 +6169,7 @@ tree dst_obj; int int_size = int_cst_value (TYPE_SIZE_UNIT (unsigned_type_node)); int offset; - /* dst->object = [src->object retail]; In thid case 'object' is the field + /* dst->object In thid case 'object' is the field of the object passed offset by: void * + void* + int + int + void* + void * This must match definition of Block_byref structs. */ /* APPLE LOCAL radar 6244520 */ @@ -6179,74 +6179,23 @@ dst_obj = build2 (PLUS_EXPR, ptr_type_node, exp, build_int_cst (NULL_TREE, offset)); /* APPLE LOCAL begin radar 6180456 */ - if (c_dialect_objc ()) - { - /* Type case to: 'id *' */ - dst_obj = cast_to_pointer_to_id (dst_obj); - dst_obj = build_indirect_ref (dst_obj, "unary *"); - } + /* Type case to: 'void **' */ + dst_obj = build_c_cast (build_pointer_type (ptr_type_node), dst_obj); + dst_obj = build_indirect_ref (dst_obj, "unary *"); /* APPLE LOCAL end radar 6180456 */ return dst_obj; } -/* APPLE LOCAL begin radar 6180456 */ -static tree block_byref_release_decl; - -/* Build a: void _Block_byref_release (void *) if not done - already. */ -tree -build_block_byref_release_decl (void) -{ - if (!block_byref_release_decl && - !(block_byref_release_decl = - lookup_name (get_identifier ("_Block_byref_release")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, void_list_node)); - - block_byref_release_decl = - builtin_function ("_Block_byref_release", func_type, 0, NOT_BUILT_IN, - 0, NULL_TREE); - - TREE_NOTHROW (block_byref_release_decl) = 0; - } - return block_byref_release_decl; -} -/* APPLE LOCAL end radar 6180456 */ - -static tree block_byref_assign_copy_decl; -tree -build_block_byref_assign_copy_decl (void) -{ - /* Build a: void _Block_byref_assign_copy (void *, void *) if not done already. */ - if (!block_byref_assign_copy_decl - && !(block_byref_assign_copy_decl - = lookup_name (get_identifier ("_Block_byref_assign_copy")))) - { - tree func_type - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, void_list_node))); - - block_byref_assign_copy_decl - = builtin_function ("_Block_byref_assign_copy", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_byref_assign_copy_decl) = 0; - } - return block_byref_assign_copy_decl; -} - /* This routine builds call to: - _Block_byref_release(VAR_DECL.__forwarding); + _Block_object_dispose(VAR_DECL.__forwarding, BLOCK_FIELD_IS_BYREF); and adds it to the statement list. */ tree build_block_byref_release_exp (tree var_decl) { - tree exp = var_decl, call_exp, func_params; + tree exp = var_decl, call_exp; tree type = TREE_TYPE (var_decl); - /* __block variables imported into Blocks are not _Block_byref_released() + /* __block variables imported into Blocks are not _Block_object_dispose() from within the Block statement itself; otherwise, each envokation of the block causes a release. Make sure to release __block variables declared and used locally in the block though. */ @@ -6261,10 +6210,9 @@ } TREE_USED (var_decl) = 1; - /* Declare: _Block_byref_release(void*) if not done already. */ + /* Declare: _Block_object_dispose(void*, BLOCK_FIELD_IS_BYREF) if not done already. */ exp = build_component_ref (exp, get_identifier ("__forwarding")); - func_params = tree_cons (NULL_TREE, exp, NULL_TREE); - call_exp = build_function_call (build_block_byref_release_decl (), func_params); + call_exp = build_block_object_dispose_call_exp (exp, BLOCK_FIELD_IS_BYREF); return call_exp; } /* APPLE LOCAL end blocks 6040305 */ @@ -9189,4 +9137,81 @@ } /* APPLE LOCAL end radar 6246527 */ +/* APPLE LOCAL begin radar 5847976 */ +static GTY(()) tree block_object_assign_decl; +static GTY(()) tree block_object_dispose_func_decl; +/* This routine declares: + void _Block_object_assign (void *, void *, int) or uses an + existing one. +*/ +static tree +build_block_object_assign_decl (void) +{ + tree func_type; + if (block_object_assign_decl) + return block_object_assign_decl; + block_object_assign_decl = lookup_name (get_identifier ("_Block_object_assign")); + if (block_object_assign_decl) + return block_object_assign_decl; + func_type = + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, integer_type_node, void_list_node)))); + + block_object_assign_decl = builtin_function ("_Block_object_assign", func_type, + 0, NOT_BUILT_IN, 0, NULL_TREE); + TREE_NOTHROW (block_object_assign_decl) = 0; + return block_object_assign_decl; +} + +/* This routine builds: + _Block_object_assign(dest, src, flag) +*/ +tree build_block_object_assign_call_exp (tree dst, tree src, int flag) +{ + tree func_params = tree_cons (NULL_TREE, dst, + tree_cons (NULL_TREE, src, + tree_cons (NULL_TREE, + build_int_cst (integer_type_node, flag), + NULL_TREE))); + return build_function_call (build_block_object_assign_decl (), func_params); +} + +/* This routine declares: + void _Block_object_dispose (void *, int) or uses an + existing one. +*/ +static tree +build_block_object_dispose_decl (void) +{ + tree func_type; + if (block_object_dispose_func_decl) + return block_object_dispose_func_decl; + block_object_dispose_func_decl = lookup_name (get_identifier ("_Block_object_dispose")); + if (block_object_dispose_func_decl) + return block_object_dispose_func_decl; + func_type = + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, integer_type_node, void_list_node))); + + block_object_dispose_func_decl = builtin_function ("_Block_object_dispose", func_type, + 0, NOT_BUILT_IN, 0, NULL_TREE); + TREE_NOTHROW (block_object_dispose_func_decl) = 0; + return block_object_dispose_func_decl; +} + +/* This routine builds the call tree: + _Block_object_dispose(src, flag) +*/ +tree build_block_object_dispose_call_exp (tree src, int flag) +{ + tree func_params = tree_cons (NULL_TREE, src, + tree_cons (NULL_TREE, + build_int_cst (integer_type_node, flag), + NULL_TREE)); + return build_function_call (build_block_object_dispose_decl (), func_params); +} +/* APPLE LOCAL end radar 5847976 */ #include "gt-c-common.h" Modified: llvm-gcc-4.2/trunk/gcc/c-common.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.h (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.h Tue Nov 25 16:26:23 2008 @@ -1022,6 +1022,11 @@ extern void objc_start_category_implementation (tree, tree); /* APPLE LOCAL radar 4592503 */ extern void objc_checkon_weak_attribute (tree); +/* APPLE LOCAL begin radar 5847976 */ +extern tree build_block_object_assign_call_exp (tree, tree, int); +extern tree build_block_object_dispose_call_exp (tree, int); +extern int objc_is_gcable_type (tree); +/* APPLE LOCAL end radar 5847976 */ extern void objc_continue_implementation (void); extern void objc_finish_implementation (void); extern void objc_set_visibility (int); @@ -1120,6 +1125,15 @@ extern tree vector_constructor_from_expr (tree, tree); /* APPLE LOCAL end AltiVec */ +/* APPLE LOCAL begin radar 5847976 */ +/* Runtime support functions used by compiler when generating copy/dispose helpers */ +enum { + BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ + BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ + BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ + BLOCK_FIELD_IS_WEAK = 16 /* declared __weak, only used in byref copy helpers */ +}; +/* APPLE LOCAL end radar 5847976 */ /* APPLE LOCAL begin radar 5732232 - blocks */ enum { BLOCK_NEEDS_FREE = (1 << 24), @@ -1183,10 +1197,7 @@ extern void start_block_helper_function (tree func_decl); extern void block_build_prologue (struct block_sema_info *block_impl); extern tree c_finish_return (tree); -extern tree copy_in_object (tree); extern bool block_requires_copying (tree); -extern tree retain_block_component (tree); -extern tree release_block_component (tree); /* APPLE LOCAL begin radar 5803600 */ extern void add_block_global_byref_list (tree); extern bool in_block_global_byref_list (tree); @@ -1195,7 +1206,6 @@ /* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ extern tree build_byref_local_var_access (tree, tree); extern tree do_digest_init (tree, tree); -extern tree cast_to_pointer_to_id (tree); /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ /* APPLE LOCAL begin radar 6237713 */ extern bool any_recognized_block_attribute (tree); @@ -1206,8 +1216,6 @@ /* APPLE LOCAL end radar 5847213 */ /* APPLE LOCAL begin radar 6083129 - byref escapes */ extern tree build_block_byref_release_exp (tree); -extern tree build_block_byref_release_decl (void); -extern tree build_block_byref_assign_copy_decl (void); /* APPLE LOCAL end radar 6083129 - byref escapes */ /* APPLE LOCAL radar 6040305 - blocks */ @@ -1220,6 +1228,9 @@ /* APPLE LOCAL radar 6160536 */ extern tree build_block_helper_name (int); +/* APPLE LOCAL radar 6353006 */ +extern tree c_build_generic_block_struct_type (void); + /* In c-omp.c */ extern tree c_finish_omp_master (tree); extern tree c_finish_omp_critical (tree, tree); Modified: llvm-gcc-4.2/trunk/gcc/c-decl.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-decl.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-decl.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-decl.c Tue Nov 25 16:26:23 2008 @@ -3582,17 +3582,17 @@ void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, struct Block_byref_id_object *src) { - dst->object = [src->object retain]; // objective-c only - _Block_byref_assign_copy(&_dest->object, _src->object) // or: c language + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // objects + _Block_object_assign(&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // blocks } */ static void -synth_block_byref_id_object_copy_func (void) +synth_block_byref_id_object_copy_func (int flag) { tree stmt, fnbody; tree dst_arg, src_arg; tree dst_obj, src_obj; struct c_arg_info * arg_info; - + tree call_exp; gcc_assert (block_byref_id_object_copy); /* Set up: (void* _dest, void*_src) parameters. */ dst_arg = build_decl (PARM_DECL, get_identifier ("_dst"), @@ -3625,23 +3625,10 @@ src_obj = build_indirect_object_id_exp (src_arg); /* APPLE LOCAL begin radar 6180456 */ - if (c_dialect_objc ()) - { - tree retain_exp = retain_block_component (src_obj); - - /* dst->object = [src->object retain]; */ - tree store = build_modify_expr (dst_obj, NOP_EXPR, retain_exp); - add_stmt (store); - } - else - { - /* _Block_byref_assign_copy(&_dest->object, _src->object) */ - tree func_params = tree_cons (NULL_TREE, build_fold_addr_expr (dst_obj), - tree_cons (NULL_TREE, src_obj, - NULL_TREE)); - tree call_exp = build_function_call (build_block_byref_assign_copy_decl (), func_params); - add_stmt (call_exp); - } + /* _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT) or : + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK) */ + call_exp = build_block_object_assign_call_exp (build_fold_addr_expr (dst_obj), src_obj, flag); + add_stmt (call_exp); /* APPLE LOCAL end radar 6180456 */ fnbody = c_end_compound_stmt (stmt, true); @@ -3655,16 +3642,15 @@ This routine builds: void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { - [_src->object release]; // objective-c or: - _Block_byref_release(_src->object) // c language + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // object + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // block } */ static void -synth_block_byref_id_object_dispose_func (void) +synth_block_byref_id_object_dispose_func (int flag) { tree stmt, fnbody; tree src_arg, src_obj, rel_exp; struct c_arg_info * arg_info; - gcc_assert (block_byref_id_object_dispose); /* Set up: (void *_src) parameter. */ src_arg = build_decl (PARM_DECL, get_identifier ("_src"), @@ -3685,15 +3671,9 @@ src_obj = build_indirect_object_id_exp (src_arg); /* APPLE LOCAL begin radar 6180456 */ - if (c_dialect_objc ()) - /* [_src->object release]; */ - rel_exp = release_block_component (src_obj); - else - { - /* _Block_byref_release(_src->object) */ - tree func_params = tree_cons (NULL_TREE, src_obj, NULL_TREE); - rel_exp = build_function_call (build_block_byref_release_decl (), func_params); - } + /* _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT) : or + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK) */ + rel_exp = build_block_object_dispose_call_exp (src_obj, flag); /* APPLE LOCAL end radar 6180456 */ add_stmt (rel_exp); @@ -3722,6 +3702,8 @@ new_block_byref_decl (tree decl) { static int unique_count; + /* APPLE LOCAL radar 5847976 */ + int save_flag_objc_gc; tree Block_byref_type; tree field_decl_chain, field_decl; const char *prefix = "__Block_byref_"; @@ -3774,7 +3756,13 @@ chainon (field_decl_chain, field_decl); pop_from_top_level (); + /* APPLE LOCAL begin radar 5847976 */ + /* Hack so we don't issue warning on a field_decl having __weak attribute */ + save_flag_objc_gc = flag_objc_gc; + flag_objc_gc = 0; finish_struct (Block_byref_type, field_decl_chain, NULL_TREE); + flag_objc_gc = save_flag_objc_gc; + /* APPLE LOCAL end radar 5847976 */ TREE_TYPE (decl) = Block_byref_type; /* Force layout_decl to recompute these fields. */ @@ -3798,7 +3786,8 @@ &initializer-expr}; */ static tree -init_byref_decl (tree decl, tree init) +/* APPLE LOCAL radar 5847976 */ +init_byref_decl (tree decl, tree init, int flag) { tree initlist; tree block_byref_type = TREE_TYPE (decl); @@ -3811,7 +3800,10 @@ fields = TYPE_FIELDS (block_byref_type); /* APPLE LOCAL begin radar 6244520 */ - initlist = tree_cons (fields, fold_convert (ptr_type_node, integer_zero_node), 0); + /* APPLE LOCAL begin radar 5847976 */ + initlist = tree_cons (fields, fold_convert (ptr_type_node, ((flag & BLOCK_FIELD_IS_WEAK) != 0) ? integer_one_node + : integer_zero_node), 0); + /* APPLE LOCAL end radar 5847976 */ fields = TREE_CHAIN (fields); initlist = tree_cons (fields, @@ -3843,7 +3835,7 @@ block_byref_id_object_copy = build_helper_func_decl (get_identifier (name), func_type); /* Synthesize function definition. */ - synth_block_byref_id_object_copy_func (); + synth_block_byref_id_object_copy_func (flag); } initlist = tree_cons (fields, build_fold_addr_expr (block_byref_id_object_copy), @@ -3861,7 +3853,7 @@ block_byref_id_object_dispose = build_helper_func_decl (get_identifier (name), func_type); /* Synthesize function definition. */ - synth_block_byref_id_object_dispose_func (); + synth_block_byref_id_object_dispose_func (flag); } initlist = tree_cons (fields, build_fold_addr_expr (block_byref_id_object_dispose), @@ -3919,6 +3911,16 @@ } else { + int flag = 0; + if (objc_is_gcable_type (TREE_TYPE (decl)) == -1) + flag = BLOCK_FIELD_IS_WEAK; + if (block_requires_copying (decl)) + { + if (TREE_CODE (TREE_TYPE (decl)) == BLOCK_POINTER_TYPE) + flag |= BLOCK_FIELD_IS_BLOCK; + else + flag |= BLOCK_FIELD_IS_OBJECT; + } decl = new_block_byref_decl (decl); /* APPLE LOCAL begin radar 6289031 */ if (! flag_objc_gc_only) @@ -3926,8 +3928,10 @@ push_cleanup (decl, build_block_byref_release_exp (decl), false); } /* APPLE LOCAL end radar 6289031 */ - - init = init_byref_decl (decl, init); + /* APPLE LOCAL begin radar 5847976 */ + COPYABLE_WEAK_BLOCK (decl) = ((flag & BLOCK_FIELD_IS_WEAK) != 0); + init = init_byref_decl (decl, init, flag); + /* APPLE LOCAL end radar 5847976 */ } } /* APPLE LOCAL end radar 5932809 - copyable byref blocks (C++ cq) */ @@ -7907,6 +7911,8 @@ { COPYABLE_BYREF_LOCAL_VAR (byref_decl) = 1; COPYABLE_BYREF_LOCAL_NONPOD (byref_decl) = COPYABLE_BYREF_LOCAL_NONPOD (decl); + /* APPLE LOCAL radar 5847976 */ + COPYABLE_WEAK_BLOCK (byref_decl) = COPYABLE_WEAK_BLOCK (decl); } /* APPLE LOCAL end radar 5932809 - copyable byref blocks (C++ ch) */ Modified: llvm-gcc-4.2/trunk/gcc/c-lex.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-lex.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-lex.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-lex.c Tue Nov 25 16:26:23 2008 @@ -372,7 +372,8 @@ non-NULL. */ enum cpp_ttype -c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags) +/* APPLE LOCAL CW asm blocks C++ comments 6338079 */ +c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, int defer) { static bool no_more_pch; const cpp_token *tok; @@ -474,18 +475,24 @@ case CPP_NUMBER: { - unsigned int flags = cpp_classify_number (parse_in, tok); + /* APPLE LOCAL CW asm blocks C++ comments 6338079 */ + unsigned int flags = cpp_classify_number (parse_in, tok, defer); switch (flags & CPP_N_CATEGORY) { case CPP_N_INVALID: + /* APPLE LOCAL begin CW asm blocks C++ comments 6338079 */ + if (flags & CPP_N_DEFER) + { + add_flags = ERROR_DEFERRED; + *value = error_mark_node; + break; + } + /* APPLE LOCAL end CW asm blocks C++ comments 6338079 */ + /* cpplib has issued an error. */ *value = error_mark_node; - /* APPLE LOCAL begin CW asm blocks 6276214 */ - /* If errors are deferred, they don't count as errors yet. */ - if (!flag_ms_asms) - errorcount++; - /* APPLE LOCAL end CW asm blocks 6276214 */ + errorcount++; break; case CPP_N_INTEGER: @@ -611,7 +618,7 @@ /* Because we don't recognize inline asm commments during lexing, we have to pass this back to the parser to error out with or eat as a comment as appropriate. */ - if (flag_iasm_blocks_local) + if (defer && flag_iasm_blocks_local) { *value = build_int_cst_wide (char_type_node, c, 0); break; Modified: llvm-gcc-4.2/trunk/gcc/c-objc-common.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-objc-common.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-objc-common.h (original) +++ llvm-gcc-4.2/trunk/gcc/c-objc-common.h Tue Nov 25 16:26:23 2008 @@ -140,4 +140,10 @@ #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p +/* APPLE LOCAL begin radar 6353006 */ +#undef LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE +#define LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE \ + c_build_generic_block_struct_type +/* APPLE LOCAL end radar 6353006 */ + #endif /* GCC_C_OBJC_COMMON */ Modified: llvm-gcc-4.2/trunk/gcc/c-parser.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-parser.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-parser.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-parser.c Tue Nov 25 16:26:23 2008 @@ -389,7 +389,7 @@ timevar_push (TV_LEX); /* APPLE LOCAL CW asm blocks */ - token->type = c_lex_with_flags (&token->value, &token->location, &token->flags); + token->type = c_lex_with_flags (&token->value, &token->location, &token->flags, 0); token->id_kind = C_ID_NONE; token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; @@ -5499,15 +5499,6 @@ switch (c_parser_peek_token (parser)->type) { case CPP_NUMBER: - /* APPLE LOCAL begin CW asm blocks (in 4.2 ak) */ - if (cpp_get_options (parse_in)->h_suffix - && c_parser_peek_token (parser)->value == error_mark_node) - { - /* This was previously deferred. */ - cpp_error (parse_in, CPP_DL_ERROR, "invalid suffix on integer constant"); - c_parser_consume_token (parser); - } - /* APPLE LOCAL end CW asm blocks (in 4.2 ak) */ case CPP_CHAR: case CPP_WCHAR: expr.value = c_parser_peek_token (parser)->value; @@ -9326,7 +9317,9 @@ { /* (in 4.2 an) */ aname = c_parser_iasm_identifier (parser); - if (c_parser_next_token_is (parser, CPP_COLON)) + if (aname == error_mark_node) + c_parser_consume_token (parser); + else if (c_parser_next_token_is (parser, CPP_COLON)) { c_parser_consume_token (parser); iasm_label (aname, false); @@ -9366,12 +9359,6 @@ } /* APPLE LOCAL end CW asm blocks */ /* APPLE LOCAL begin radar 5732232 - blocks (C++ ce) */ -/* APPLE LOCAL begin radar 6175959 */ -static GTY(()) tree block_copy_assign_decl; -static GTY(()) tree block_object_assign_decl; -static GTY(()) tree block_destroy_decl; -static GTY(()) tree block_object_dispose_func_decl; -/* APPLE LOCAL end radar 6175959 */ /* APPLE LOCAL begin radar 6300081 */ @@ -9406,7 +9393,8 @@ */ tree -build_generic_block_struct_type (void) +/* APPLE LOCAL radar 6353006 */ +c_build_generic_block_struct_type (void) { tree field_decl_chain; tree field_decl; @@ -9728,7 +9716,7 @@ tree y = TREE_VALUE (chain); TREE_USED (y) = 1; fields = TREE_CHAIN (fields); - initlist = tree_cons (fields, copy_in_object (y), initlist); + initlist = tree_cons (fields, y, initlist); } for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) @@ -9898,8 +9886,8 @@ if (block_requires_copying (TREE_VALUE (chain))) { /* APPLE LOCAL begin radar 6175959 */ - tree which_function_decl; - tree func_params, call_exp; + int flag; + tree call_exp; tree p = TREE_VALUE (chain); tree dst_block_component, src_block_component; dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), @@ -9908,66 +9896,26 @@ DECL_NAME (p)); if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) - { - /* _Block_copy_assign(&_dest->myImportedBlock, _src->myImportedClosure, 0) */ - /* Build a: void _Block_copy_assign (void *, void *, int) if not done - already. */ - /* APPLE LOCAL begin radar 6310599 */ - if (!block_copy_assign_decl && - !(block_copy_assign_decl = lookup_name (get_identifier ("_Block_copy_assign")))) - /* APPLE LOCAL end radar 6310599 */ - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node)))); - - block_copy_assign_decl = builtin_function ("_Block_copy_assign", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_copy_assign_decl) = 0; - } - which_function_decl = block_copy_assign_decl; - } + /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_BLOCK) */ + flag = BLOCK_FIELD_IS_BLOCK; else - { - /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, 0) */ - /* Build a: void _Block_object_assign (void *, void *, int) if not done - already. */ - if (!block_object_assign_decl && - !(block_object_assign_decl = lookup_name (get_identifier ("_Block_object_assign")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node)))); - - block_object_assign_decl = builtin_function ("_Block_object_assign", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_object_assign_decl) = 0; - } - which_function_decl = block_object_assign_decl; - } + /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_OBJECT) */ + flag = BLOCK_FIELD_IS_OBJECT; dst_block_component = build_fold_addr_expr (dst_block_component); - func_params = tree_cons (NULL_TREE, dst_block_component, - tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), - NULL_TREE))); - call_exp = build_function_call (which_function_decl, func_params); + call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); add_stmt (call_exp); /* APPLE LOCAL end radar 6175959 */ } /* For each __block declared variable must generate call to: - _Block_byref_assign_copy(&_dest->myImportedBlock, _src->myImportedBlock) + _Block_object_assign(&_dest->myImportedBlock, _src->myImportedBlock, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */ for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) { - tree func_params, call_exp; + int flag = BLOCK_FIELD_IS_BYREF; + tree call_exp; tree p = TREE_VALUE (chain); tree dst_block_component, src_block_component; dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), @@ -9975,12 +9923,12 @@ src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); - /* _Block_byref_assign_copy(&_dest->myImportedClosure, _src->myImportedClosure) */ + /* _Block_object_assign(&_dest->myImportedClosure, _src->myImportedClosure, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */ + if (COPYABLE_WEAK_BLOCK (p)) + flag |= BLOCK_FIELD_IS_WEAK; + dst_block_component = build_fold_addr_expr (dst_block_component); - func_params = tree_cons (NULL_TREE, dst_block_component, - tree_cons (NULL_TREE, src_block_component, - NULL_TREE)); - call_exp = build_function_call (build_block_byref_assign_copy_decl (), func_params); + call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); add_stmt (call_exp); } @@ -9991,30 +9939,6 @@ free (arg_info); } -/* APPLE LOCAL begin radar 6175959 */ -static tree -block_object_dispose (tree src_block_component) -{ - tree func_params; - if (!block_object_dispose_func_decl && - !(block_object_dispose_func_decl = lookup_name (get_identifier ("_Block_object_dispose")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node))); - - block_object_dispose_func_decl = builtin_function ("_Block_object_dispose", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_object_dispose_func_decl) = 0; - } - func_params = tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), NULL_TREE)); - return build_function_call (block_object_dispose_func_decl, func_params); -} -/* APPLE LOCAL end radar 6175959 */ - static void synth_destroy_helper_block_func (struct block_sema_info * block_impl) { @@ -10042,64 +9966,41 @@ chain = TREE_CHAIN (chain)) if (block_requires_copying (TREE_VALUE (chain))) { - /* APPLE LOCAL begin radar 6175959 */ + int flag; + tree rel_exp; tree p = TREE_VALUE (chain); tree src_block_component; src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) - { - tree func_params, call_exp; - /* _Block_destroy(_src->myImportedClosure); */ - /* _Block_destroy (void *); */ - /* Build a: void _Block_destroy (void *) if not done already. */ - if (!block_destroy_decl && - !(block_destroy_decl = lookup_name (get_identifier ("_Block_destroy")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node))); - - block_destroy_decl = builtin_function ("_Block_destroy", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_destroy_decl) = 0; - } - func_params = tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), NULL_TREE)); - call_exp = build_function_call (block_destroy_decl, func_params); - add_stmt (call_exp); - } + /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_BLOCK); */ + flag = BLOCK_FIELD_IS_BLOCK; else - { - tree rel_exp; - /* _Block_object_dispose(_src->imported_object_0, 0); */ - rel_exp = block_object_dispose (src_block_component); - add_stmt (rel_exp); - } - /* APPLE LOCAL end radar 6175959 */ + /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_OBJECT); */ + flag = BLOCK_FIELD_IS_OBJECT; + rel_exp = build_block_object_dispose_call_exp (src_block_component, flag); + add_stmt (rel_exp); } /* For each __block declared variable must generate call to: - _Block_byref_release(_src->myImportedClosure) + _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */ for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) { - tree func_params, call_exp; + tree call_exp; + int flag = BLOCK_FIELD_IS_BYREF; tree p = TREE_VALUE (chain); tree src_block_component; src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); - /* _Block_byref_release(_src->myImportedClosure) */ - /* Build a: void _Block_byref_release (void *) if not done - already. */ - func_params = tree_cons (NULL_TREE, src_block_component, NULL_TREE); - call_exp = build_function_call (build_block_byref_release_decl (), func_params); + if (COPYABLE_WEAK_BLOCK (p)) + flag |= BLOCK_FIELD_IS_WEAK; + /* _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */ + call_exp = build_block_object_dispose_call_exp (src_block_component, flag); add_stmt (call_exp); } Modified: llvm-gcc-4.2/trunk/gcc/c-pragma.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-pragma.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-pragma.h (original) +++ llvm-gcc-4.2/trunk/gcc/c-pragma.h Tue Nov 25 16:26:23 2008 @@ -101,7 +101,8 @@ extern const struct cpp_token *c_lex_peek (int); extern void c_lex_prepend (const struct cpp_token *, int); /* APPLE LOCAL end AltiVec */ -extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *); +/* APPLE LOCAL CW asm blocks C++ comments 6338079 */ +extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *, int); /* If 1, then lex strings into the execution character set. If 0, lex strings into the host character set. Modified: llvm-gcc-4.2/trunk/gcc/config.host URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config.host?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config.host (original) +++ llvm-gcc-4.2/trunk/gcc/config.host Tue Nov 25 16:26:23 2008 @@ -91,10 +91,10 @@ # Generic darwin host support. out_host_hook_obj=host-darwin.o host_xmake_file="${host_xmake_file} x-darwin" - /* APPLE LOCAL begin ARM native compiler support */ - /* Default size of memory to set aside for precompiled headers */ + # APPLE LOCAL begin ARM native compiler support + # Default size of memory to set aside for precompiled headers host_xm_defines='DARWIN_PCH_ADDR_SPACE_SIZE=1024*1024*1024' - /* APPLE LOCAL end ARM native compiler support */ + # APPLE LOCAL end ARM native compiler support ;; esac Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/arm/arm.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Tue Nov 25 16:26:23 2008 @@ -84,6 +84,7 @@ static const char *fp_const_from_val (REAL_VALUE_TYPE *); static arm_cc get_arm_condition_code (rtx); static HOST_WIDE_INT int_log2 (HOST_WIDE_INT); +static rtx is_jump_table (rtx); static const char *output_multi_immediate (rtx *, const char *, const char *, int, HOST_WIDE_INT); static const char *shift_op (rtx, HOST_WIDE_INT *); @@ -3859,6 +3860,10 @@ offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, base == reg ? 0 : reg); + /* APPLE LOCAL begin 6327222 */ + /* #if 0 for now so it's here for reference since this is a tricky + bit. */ +#if 0 if (GET_CODE (offset) == CONST_INT) { /* The base register doesn't really matter, we only want to @@ -3872,7 +3877,8 @@ if (GET_CODE (offset) == CONST_INT) return plus_constant (base, INTVAL (offset)); } - +#endif + /* APPLE LOCAL end 6327222 */ if (GET_MODE_SIZE (mode) > 4 && (GET_MODE_CLASS (mode) == MODE_INT || TARGET_SOFT_FLOAT)) Modified: llvm-gcc-4.2/trunk/gcc/config/darwin-c.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin-c.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin-c.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin-c.c Tue Nov 25 16:26:23 2008 @@ -1081,7 +1081,8 @@ else { builtin_define ("__strong="); - builtin_define ("__weak="); + /* APPLE LOCAL radar 5847976 */ + builtin_define ("__weak=__attribute__((objc_gc(weak)))"); } /* APPLE LOCAL end ObjC GC */ /* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ Modified: llvm-gcc-4.2/trunk/gcc/config/darwin-sections.def URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/darwin-sections.def?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/darwin-sections.def (original) +++ llvm-gcc-4.2/trunk/gcc/config/darwin-sections.def Tue Nov 25 16:26:23 2008 @@ -117,10 +117,12 @@ ".section __DATA, __objc_nlclslist, regular, no_dead_strip", 1) DEF_SECTION (objc_v2_nonlazy_category_section, 0, ".section __DATA, __objc_nlcatlist, regular, no_dead_strip", 1) +/* APPLE LOCAL begin radar 6351990 */ DEF_SECTION (objc_v2_protocollist_section, 0, - ".section __DATA, __objc_protolist, regular, no_dead_strip", 1) + ".section __DATA, __objc_protolist, coalesced, no_dead_strip", 1) DEF_SECTION (objc_v2_protocolrefs_section, 0, - ".section __DATA, __objc_protorefs, regular, no_dead_strip", 1) + ".section __DATA, __objc_protorefs, coalesced, no_dead_strip", 1) +/* APPLE LOCAL end radar 6351990 */ DEF_SECTION (objc_v2_super_classrefs_section, 0, ".section __DATA, __objc_superrefs, regular, no_dead_strip", 1) DEF_SECTION (objc_v2_image_info_section, 0, Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Tue Nov 25 16:26:23 2008 @@ -2020,15 +2020,13 @@ error ("-mstackrealign not supported in the 64bit mode"); /* APPLE LOCAL end radar 4877693 */ - target_flags |= TARGET_SUBTARGET64_DEFAULT & ~target_flags_explicit; - /* Enable by default the SSE and MMX builtins. Do allow the user to explicitly disable any of these. In particular, disabling SSE and MMX for kernel code is extremely useful. */ if (!ix86_arch_specified) target_flags - |= ((MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE) - & ~target_flags_explicit); + |= ((MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE + | TARGET_SUBTARGET64_DEFAULT) & ~target_flags_explicit); /* APPLE LOCAL begin mainline candidate */ /* Disable the red zone for kernel compilation. ??? Why aren't we using -mcmodel=kernel? */ @@ -6882,12 +6880,9 @@ /* TLS references should always be enclosed in UNSPEC. */ if (SYMBOL_REF_TLS_MODEL (op0)) return false; - /* APPLE LOCAL begin 6227434 */ + /* APPLE LOCAL begin fix-and-continue 6227434 */ #if TARGET_MACHO - /* ObjC machinery always has a legitimate PIC - address. */ - if (objc_anonymous_local_objc_name (XSTR (op0, 0)) - || SYMBOL_REF_LOCAL_P (op0)) + if (machopic_data_defined_p (op0)) return true; /* Under -mfix-and-continue, even local storage is addressed via the GOT, so that the value of local @@ -6895,7 +6890,7 @@ if (TARGET_FIX_AND_CONTINUE) return false; #endif - /* APPLE LOCAL end 6227434 */ + /* APPLE LOCAL end fix-and-continue 6227434 */ if (!SYMBOL_REF_FAR_ADDR_P (op0) && SYMBOL_REF_LOCAL_P (op0)) return true; break; @@ -7452,6 +7447,10 @@ new = XEXP (new, 1); } new = gen_rtx_PLUS (Pmode, base, new); + /* APPLE LOCAL begin fix-and-continue 6358507 */ + if (!legitimate_address_p (Pmode, new, FALSE)) + new = force_reg (Pmode, new); + /* APPLE LOCAL end fix-and-continue 6358507 */ } } } @@ -15537,6 +15536,7 @@ const unsigned int flag; }; +/* APPLE LOCAL begin 4299257 */ static const struct builtin_description bdesc_comi[] = { { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, UNEQ, 0 }, @@ -15545,25 +15545,29 @@ { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, GT, 0 }, { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, GE, 0 }, { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, LTGT, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, UNEQ, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, UNLT, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, UNLE, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, GT, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, GE, 0 }, - { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, LTGT, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdeq", IX86_BUILTIN_COMIEQSD, UNEQ, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdlt", IX86_BUILTIN_COMILTSD, UNLT, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdle", IX86_BUILTIN_COMILESD, UNLE, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdgt", IX86_BUILTIN_COMIGTSD, GT, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdge", IX86_BUILTIN_COMIGESD, GE, 0 }, { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdneq", IX86_BUILTIN_COMINEQSD, LTGT, 0 }, - { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, UNEQ, 0 }, - { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, UNLT, 0 }, - { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, UNLE, 0 }, +}; +static const struct builtin_description bdesc_ucomi[] = +{ + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, EQ, 0 }, + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, LT, 0 }, + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, LE, 0 }, + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, GT, 0 }, + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, GE, 0 }, + { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, LTGT, 0 }, + { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, EQ, 0 }, + { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, LT, 0 }, + { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, LE, 0 }, { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdgt", IX86_BUILTIN_UCOMIGTSD, GT, 0 }, { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdge", IX86_BUILTIN_UCOMIGESD, GE, 0 }, { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, LTGT, 0 }, }; +/* APPLE LOCAL end 4299257 */ /* APPLE LOCAL begin 5612787 mainline sse4 */ static const struct builtin_description bdesc_ptest[] = @@ -16709,13 +16713,23 @@ def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pshufw", v4hi_ftype_v4hi_int, IX86_BUILTIN_PSHUFW); def_builtin (MASK_MMX, "__builtin_ia32_pmaddwd", v2si_ftype_v4hi_v4hi, IX86_BUILTIN_PMADDWD); - /* comi/ucomi insns. */ + /* APPLE LOCAL 4299257 */ + /* comi insns. */ for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++) if (d->mask == MASK_SSE2) def_builtin (d->mask, d->name, int_ftype_v2df_v2df, d->code); else def_builtin (d->mask, d->name, int_ftype_v4sf_v4sf, d->code); + /* APPLE LOCAL begin 4299257 */ + /* ucomi insns. */ + for (i = 0, d = bdesc_ucomi; i < ARRAY_SIZE (bdesc_ucomi); i++, d++) + if (d->mask == MASK_SSE2) + def_builtin (d->mask, d->name, int_ftype_v2df_v2df, d->code); + else + def_builtin (d->mask, d->name, int_ftype_v4sf_v4sf, d->code); + /* APPLE LOCAL end 4299257 */ + /* APPLE LOCAL begin 5612787 mainline sse4 */ /* ptest insns. */ for (i = 0, d = bdesc_ptest; i < ARRAY_SIZE (bdesc_ptest); i++, d++) @@ -17482,6 +17496,56 @@ return SUBREG_REG (target); } +/* APPLE LOCAL begin 4299257 */ +/* Subroutine of ix86_expand_builtin to take care of ucomi insns. */ + +static rtx +ix86_expand_sse_ucomi (const struct builtin_description *d, tree arglist, + rtx target) +{ + tree arg0 = TREE_VALUE (arglist); + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + rtx op0 = expand_normal (arg0); + rtx op1 = expand_normal (arg1); + enum machine_mode mode0 = insn_data[d->icode].operand[0].mode; + enum machine_mode mode1 = insn_data[d->icode].operand[1].mode; + enum machine_mode scalar_mode; + enum rtx_code comparison = d->comparison; + + if (VECTOR_MODE_P (mode0)) + op0 = safe_vector_operand (op0, mode0); + if (VECTOR_MODE_P (mode1)) + op1 = safe_vector_operand (op1, mode1); + + /* Swap operands if we have a comparison that isn't available in + hardware. */ + if (d->flag & BUILTIN_DESC_SWAP_OPERANDS) + { + rtx tmp = op1; + op1 = op0; + op0 = tmp; + } + + target = gen_reg_rtx (SImode); + emit_move_insn (target, const0_rtx); + target = gen_rtx_SUBREG (QImode, target, 0); + + gcc_assert (mode0 == V4SFmode || mode0 == V2DFmode); + gcc_assert (mode1 == V4SFmode || mode1 == V2DFmode); + + scalar_mode = (mode0 == V4SFmode) ? SFmode : DFmode; + op0 = gen_rtx_SUBREG (scalar_mode, copy_to_mode_reg (mode0, op0), 0); + op1 = gen_rtx_SUBREG (scalar_mode, copy_to_mode_reg (mode1, op1), 0); + + ix86_compare_op0 = op0; + ix86_compare_op1 = op1; + if (ix86_expand_setcc (comparison, target)) + return SUBREG_REG (target); + + return NULL_RTX; +} +/* APPLE LOCAL end 4299257 */ + /* APPLE LOCAL begin 5612787 mainline sse4 */ /* Subroutine of ix86_expand_builtin to take care of ptest insns. */ @@ -18632,6 +18696,12 @@ if (d->code == fcode) return ix86_expand_sse_comi (d, arglist, target); + /* APPLE LOCAL begin 4299257 */ + for (i = 0, d = bdesc_ucomi; i < ARRAY_SIZE (bdesc_ucomi); i++, d++) + if (d->code == fcode) + return ix86_expand_sse_ucomi (d, arglist, target); + /* APPLE LOCAL end 4299257 */ + /* APPLE LOCAL begin 5612787 mainline sse4 */ for (i = 0, d = bdesc_ptest; i < ARRAY_SIZE (bdesc_ptest); i++, d++) if (d->code == fcode) Modified: llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md Tue Nov 25 16:26:23 2008 @@ -464,8 +464,14 @@ if (SYMBOL_REF_TLS_MODEL (op) != 0) return 0; +/* APPLE LOCAL begin fix-and-continue 6358507 */ if (SYMBOL_REF_LOCAL_P (op)) - return 1; + { + if (!TARGET_FIX_AND_CONTINUE + || machopic_data_defined_p (op)) + return 1; + } +/* APPLE LOCAL end fix-and-continue 6358507 */ /* There is, however, a not insubstantial body of code in the rest of the compiler that assumes it can just stick the results of Modified: llvm-gcc-4.2/trunk/gcc/cp/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/ChangeLog.apple?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/cp/ChangeLog.apple Tue Nov 25 16:26:23 2008 @@ -1,3 +1,23 @@ +008-11-07 Fariborz Jahanian + + Radar 5847976 + * decl.c (synth_block_byref_id_object_copy_func): Takes new 'flag' argument + and produces the new much simplified API. + (synth_block_byref_id_object_dispose_func): Ditto. + (new_block_byref_decl): Turn off -fobjc-gc so we don't get + bogus warning on field declared as __weak. + (init_byref_decl): Takes a new 'flag' argument and passes + it down to synth_block_byref_id_object_copy_func and + synth_block_byref_id_object_dispose_func. + (cp_finish_decl): Calculates the flag for the block + variable declaration and passes it down to init_byref_decl. + * parser.c (build_block_struct_initlist): Removes call to + copy_in_object (not needed). + (synth_copy_helper_block_func): Produce the new, simplified + API. + (synth_destroy_helper_block_func): Ditto. + (build_block_byref_decl): Copy over COPYABLE_WEAK_BLOCK flag. + 2008-10-31 Fariborz Jahanian Radar 6175959 Modified: llvm-gcc-4.2/trunk/gcc/cp/cp-objcp-common.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/cp-objcp-common.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/cp-objcp-common.h (original) +++ llvm-gcc-4.2/trunk/gcc/cp/cp-objcp-common.h Tue Nov 25 16:26:23 2008 @@ -171,4 +171,10 @@ #define LANG_HOOKS_VTABLE_P cp_vtable_p /* APPLE LOCAL end kext identify vtables */ +/* APPLE LOCAL begin radar 6353006 */ +#undef LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE +#define LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE \ + c_build_generic_block_struct_type +/* APPLE LOCAL end radar 6353006 */ + #endif /* GCC_CP_OBJCP_COMMON */ Modified: llvm-gcc-4.2/trunk/gcc/cp/decl.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/decl.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/decl.c (original) +++ llvm-gcc-4.2/trunk/gcc/cp/decl.c Tue Nov 25 16:26:23 2008 @@ -5298,14 +5298,16 @@ void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, struct Block_byref_id_object *src) { - dst->object = [src->object retain]; + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // objects + _Block_object_assign(&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // blocks } */ static void -synth_block_byref_id_object_copy_func (void) +synth_block_byref_id_object_copy_func (int flag) { tree stmt; tree dst_arg, src_arg; tree dst_obj, src_obj; + tree call_exp; gcc_assert (block_byref_id_object_copy); /* Set up: (void* _dest, void*_src) parameters. */ @@ -5342,23 +5344,10 @@ /* src_obj is: _src->object. */ src_obj = build_indirect_object_id_exp (src_arg); /* APPLE LOCAL begin radar 6180456 */ - if (c_dialect_objc ()) - { - tree retain_exp = retain_block_component (src_obj); - - /* dst->object = [src->object retain]; */ - tree store = build_modify_expr (dst_obj, NOP_EXPR, retain_exp); - add_stmt (store); - } - else - { - /* _Block_byref_assign_copy(&_dest->object, _src->object) */ - tree func_params = tree_cons (NULL_TREE, build_fold_addr_expr (dst_obj), - tree_cons (NULL_TREE, src_obj, - NULL_TREE)); - tree call_exp = build_function_call (build_block_byref_assign_copy_decl (), func_params); - add_stmt (call_exp); - } + /* _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_OBJECT) or: + _Block_object_assign (&_dest->object, _src->object, BLOCK_FIELD_IS_BLOCK) */ + call_exp = build_block_object_assign_call_exp (build_fold_addr_expr (dst_obj), src_obj, flag); + add_stmt (call_exp); /* APPLE LOCAL end radar 6180456 */ finish_compound_stmt (stmt); @@ -5371,10 +5360,10 @@ This routine builds: void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { - [_src->object release]; // objective-c++ or: - _Block_byref_release(_src->object) // c++ language + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT[|BLOCK_FIELD_IS_WEAK]) // objects + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK[|BLOCK_FIELD_IS_WEAK]) // blocks } */ -static void synth_block_byref_id_object_dispose_func (void) +static void synth_block_byref_id_object_dispose_func (int flag) { tree stmt; tree src_arg, src_obj, rel_exp; @@ -5403,15 +5392,9 @@ src_obj = build_indirect_object_id_exp (src_arg); /* APPLE LOCAL begin radar 6180456 */ - if (c_dialect_objc ()) - /* [_src->object release]; */ - rel_exp = release_block_component (src_obj); - else - { - /* _Block_byref_release(_src->object) */ - tree func_params = tree_cons (NULL_TREE, src_obj, NULL_TREE); - rel_exp = build_function_call (build_block_byref_release_decl (), func_params); - } + /* _Block_object_dispose(_src->object, BLOCK_FIELD_IS_OBJECT) or: + _Block_object_dispose(_src->object, BLOCK_FIELD_IS_BLOCK) */ + rel_exp = build_block_object_dispose_call_exp (src_obj, flag); /* APPLE LOCAL end radar 6180456 */ add_stmt (rel_exp); @@ -5471,6 +5454,8 @@ new_block_byref_decl (tree decl) { static int unique_count; + /* APPLE LOCAL radar 5847976 */ + int save_flag_objc_gc; tree Block_byref_type; tree fields = NULL_TREE, field; const char *prefix = "__Block_byref_"; @@ -5524,8 +5509,14 @@ field = build_decl (FIELD_DECL, DECL_NAME (decl), TREE_TYPE (decl)); chainon (fields, field); + /* APPLE LOCAL begin radar 5847976 */ + /* Hack so we don't issue warning on a field_decl having __weak attribute */ + save_flag_objc_gc = flag_objc_gc; + flag_objc_gc = 0; /* finish_struct (Block_byref_type, field_decl_chain, NULL_TREE); */ block_finish_struct (Block_byref_type, fields); + flag_objc_gc = save_flag_objc_gc; + /* APPLE LOCAL end radar 5847976 */ pop_from_top_level (); TREE_TYPE (decl) = Block_byref_type; @@ -5550,7 +5541,7 @@ &initializer-expr}; */ static tree -init_byref_decl (tree decl, tree init) +init_byref_decl (tree decl, tree init, int flag) { tree initlist; tree block_byref_type = TREE_TYPE (decl); @@ -5563,7 +5554,8 @@ fields = TYPE_FIELDS (block_byref_type); /* APPLE LOCAL begin radar 6244520 */ - initlist = tree_cons (fields, fold_convert (ptr_type_node, integer_zero_node), + initlist = tree_cons (fields, fold_convert (ptr_type_node, ((flag & BLOCK_FIELD_IS_WEAK) != 0) ? integer_one_node + : integer_zero_node), 0); fields = TREE_CHAIN (fields); @@ -5599,7 +5591,7 @@ func_type); DECL_CONTEXT (block_byref_id_object_copy) = current_function_decl; /* Synthesize function definition. */ - synth_block_byref_id_object_copy_func (); + synth_block_byref_id_object_copy_func (flag); pop_lang_context (); } initlist = tree_cons (fields, @@ -5621,7 +5613,7 @@ func_type); DECL_CONTEXT (block_byref_id_object_dispose) = current_function_decl; /* Synthesize function definition. */ - synth_block_byref_id_object_dispose_func (); + synth_block_byref_id_object_dispose_func (flag); pop_lang_context (); } initlist = tree_cons (fields, @@ -5786,10 +5778,23 @@ } else { + /* APPLE LOCAL begin radar 5847976 */ + int flag = 0; + if (objc_is_gcable_type (TREE_TYPE (decl)) == -1) + flag = BLOCK_FIELD_IS_WEAK; + if (block_requires_copying (decl)) + { + if (TREE_CODE (TREE_TYPE (decl)) == BLOCK_POINTER_TYPE) + flag |= BLOCK_FIELD_IS_BLOCK; + else + flag |= BLOCK_FIELD_IS_OBJECT; + } decl = new_block_byref_decl (decl); if (! flag_objc_gc_only) push_cleanup (decl, build_block_byref_release_exp (decl), false); - init = init_byref_decl (decl, init); + COPYABLE_WEAK_BLOCK (decl) = ((flag & BLOCK_FIELD_IS_WEAK) != 0); + init = init_byref_decl (decl, init, flag); + /* APPLE LOCAL end radar 5847976 */ } } /* APPLE LOCAL end blocks 6040305 (cq) */ Modified: llvm-gcc-4.2/trunk/gcc/cp/parser.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/parser.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/cp/parser.c (original) +++ llvm-gcc-4.2/trunk/gcc/cp/parser.c Tue Nov 25 16:26:23 2008 @@ -442,7 +442,8 @@ /* Get a new token from the preprocessor. */ token->type - = c_lex_with_flags (&token->u.value, &token->location, &token->flags); + /* APPLE LOCAL CW asm blocks C++ comments 6338079 */ + = c_lex_with_flags (&token->u.value, &token->location, &token->flags, 1); token->input_file_stack_index = input_file_stack_tick; token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; @@ -542,12 +543,15 @@ /* APPLE LOCAL begin CW asm blocks */ top: if (flag_ms_asms) - while (lexer->next_token->type == CPP_NUMBER - && lexer->next_token->u.value == error_mark_node) + if (lexer->next_token->type == CPP_NUMBER + && lexer->next_token->u.value == error_mark_node + && (lexer->next_token->flags & ERROR_DEFERRED)) { + cp_lexer_set_source_position_from_token (lexer->next_token); + /* This was previously deferred. */ + lexer->next_token->flags ^= ERROR_DEFERRED; error ("invalid suffix on integer constant"); - cp_lexer_consume_token (lexer); } if (!inside_iasm_block) { @@ -20538,13 +20542,6 @@ } /* APPLE LOCAL end radar 6214617 */ -/* APPLE LOCAL begin radar 6175959 */ -static GTY(()) tree block_copy_assign_decl; -static GTY(()) tree block_object_assign_decl; -static GTY(()) tree block_destroy_decl; -static GTY(()) tree block_object_dispose_func_decl; -/* APPLE LOCAL end radar 6175959 */ - /* APPLE LOCAL begin radar 5847213 - radar 6329245 */ /** build_descriptor_block_decl - This routine builds a static block_descriptior variable of type: @@ -20635,7 +20632,8 @@ */ tree -build_generic_block_struct_type (void) +/* APPLE LOCAL radar 6353006 */ +c_build_generic_block_struct_type (void) { tree fields = NULL_TREE; tree field; @@ -20919,7 +20917,7 @@ { tree y = TREE_VALUE (chain); TREE_USED (y) = 1; - CONSTRUCTOR_APPEND_ELT(impl_v, NULL_TREE, copy_in_object (y)); + CONSTRUCTOR_APPEND_ELT(impl_v, NULL_TREE, y); } for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) @@ -21093,7 +21091,7 @@ if (cp_block_requires_copying (TREE_VALUE (chain))) { /* APPLE LOCAL begin radar 6175959 */ - tree which_function_decl = NULL_TREE; + int flag = 0; tree p = TREE_VALUE (chain); tree dst_block_component, src_block_component; dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), @@ -21102,27 +21100,8 @@ DECL_NAME (p)); if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) - { - /* _Block_copy_assign(&_dest->myImportedBlock, _src->myImportedClosure, 0) */ - /* Build a: void _Block_copy_assign (void *, void *, int) if not done - already. */ - /* APPLE LOCAL begin radar 6310599 */ - if (!block_copy_assign_decl && - !(block_copy_assign_decl = lookup_name (get_identifier ("_Block_copy_assign")))) - /* APPLE LOCAL end radar 6310599 */ - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node)))); - - block_copy_assign_decl = builtin_function ("_Block_copy_assign", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_copy_assign_decl) = 0; - } - which_function_decl = block_copy_assign_decl; - } + /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_BLOCK) */ + flag = BLOCK_FIELD_IS_BLOCK; /* APPLE LOCAL begin radar 6214617 */ else if (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (p)) || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p))) @@ -21133,48 +21112,27 @@ } /* APPLE LOCAL end radar 6214617 */ else - { - /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, 0) */ - /* Build a: void _Block_object_assign (void *, void *, int) if not done - already. */ - if (!block_object_assign_decl && - !(block_object_assign_decl = lookup_name (get_identifier ("_Block_object_assign")))) + /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_OBJECT) */ + flag = BLOCK_FIELD_IS_OBJECT; + if (flag) { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node)))); - - block_object_assign_decl = builtin_function ("_Block_object_assign", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_object_assign_decl) = 0; - } - which_function_decl = block_object_assign_decl; - } - if (which_function_decl) - { - tree func_params, call_exp; - dst_block_component = build_fold_addr_expr (dst_block_component); - func_params = tree_cons (NULL_TREE, dst_block_component, - tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), - NULL_TREE))); - call_exp = build_function_call (which_function_decl, func_params); - add_stmt (call_exp); + tree call_exp; + dst_block_component = build_fold_addr_expr (dst_block_component); + call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); + add_stmt (call_exp); + } + /* APPLE LOCAL end radar 6175959 */ } - /* APPLE LOCAL end radar 6175959 */ - } /* For each __block declared variable used in |...| Must generate call to: - _Block_byref_assign_copy(&_dest->myImportedBlock, _src->myImportedBlock) + _Block_object_assign(&_dest->myImportedBlock, _src->myImportedBlock, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */ for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) { - tree func_params, call_exp; + int flag = BLOCK_FIELD_IS_BYREF; + tree call_exp; tree p = TREE_VALUE (chain); tree dst_block_component, src_block_component; dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), @@ -21182,12 +21140,12 @@ src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); - /* _Block_byref_assign_copy(&_dest->myImportedClosure, _src->myImportedClosure) */ - dst_block_component = build_fold_addr_expr (dst_block_component); - func_params = tree_cons (NULL_TREE, dst_block_component, - tree_cons (NULL_TREE, src_block_component, - NULL_TREE)); - call_exp = build_function_call (build_block_byref_assign_copy_decl (), func_params); + /* _Block_object_assign(&_dest->myImportedClosure, _src->myImportedClosure, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */ + if (COPYABLE_WEAK_BLOCK (p)) + flag |= BLOCK_FIELD_IS_WEAK; + + dst_block_component = build_fold_addr_expr (dst_block_component); + call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); add_stmt (call_exp); } @@ -21201,30 +21159,6 @@ /* free (arg_info); */ } -/* APPLE LOCAL begin radar 6175959 */ -static tree -block_object_dispose (tree src_block_component) -{ - tree func_params; - if (!block_object_dispose_func_decl && - !(block_object_dispose_func_decl = lookup_name (get_identifier ("_Block_object_dispose")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node))); - - block_object_dispose_func_decl = builtin_function ("_Block_object_dispose", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_object_dispose_func_decl) = 0; - } - func_params = tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), NULL_TREE)); - return build_function_call (block_object_dispose_func_decl, func_params); -} -/* APPLE LOCAL end radar 6175959 */ - static void synth_destroy_helper_block_func (struct block_sema_info * block_impl) { @@ -21263,37 +21197,16 @@ && CLASSTYPE_DESTRUCTORS (TREE_TYPE (TREE_VALUE (chain))))) /* APPLE LOCAL end radar 6214617 */ { + int flag = 0; + tree rel_exp; tree p = TREE_VALUE (chain); tree src_block_component; src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) - { - tree func_params, call_exp; - /* APPLE LOCAL begin radar 6175959 */ - /* _Block_destroy(_src->myImportedClosure); */ - /* _Block_destroy (void *); */ - /* Build a: void _Block_destroy (void *) if not done already. */ - if (!block_destroy_decl && - !(block_destroy_decl = lookup_name (get_identifier ("_Block_destroy")))) - { - tree func_type = - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, void_list_node))); - - block_destroy_decl = builtin_function ("_Block_destroy", func_type, - 0, NOT_BUILT_IN, 0, NULL_TREE); - TREE_NOTHROW (block_destroy_decl) = 0; - } - func_params = tree_cons (NULL_TREE, src_block_component, - tree_cons (NULL_TREE, - build_int_cst (integer_type_node, 0), NULL_TREE)); - call_exp = build_function_call (block_destroy_decl, func_params); - /* APPLE LOCAL end radar 6175959 */ - add_stmt (call_exp); - } + /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_BLOCK); */ + flag = BLOCK_FIELD_IS_BLOCK; /* APPLE LOCAL begin radar 6214617 */ else if (TREE_CODE (TREE_TYPE (p)) == RECORD_TYPE && CLASSTYPE_DESTRUCTORS (TREE_TYPE (p))) @@ -21304,35 +21217,34 @@ } /* APPLE LOCAL end radar 6214617 */ else - { - tree rel_exp; - /* APPLE LOCAL begin radar 6175959 */ - /* _Block_object_dispose(_src->imported_object_0, 0); */ - rel_exp = block_object_dispose (src_block_component); - /* APPLE LOCAL end radar 6175959 */ - add_stmt (rel_exp); - } + /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_OBJECT); */ + flag = BLOCK_FIELD_IS_OBJECT; + if (flag) + { + rel_exp = build_block_object_dispose_call_exp (src_block_component, flag); + add_stmt (rel_exp); + } } /* For each __block declared variable used in |...| Must generate call to: - _Block_byref_release(_src->myImportedClosure) + _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */ for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) { - tree func_params, call_exp; + tree call_exp; + int flag = BLOCK_FIELD_IS_BYREF; tree p = TREE_VALUE (chain); tree src_block_component; src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), DECL_NAME (p)); - /* _Block_byref_release(_src->myImportedClosure) */ - /* Build a: void _Block_byref_release (void *) if not done - already. */ - func_params = tree_cons (NULL_TREE, src_block_component, NULL_TREE); - call_exp = build_function_call (build_block_byref_release_decl (), func_params); - add_stmt (call_exp); + if (COPYABLE_WEAK_BLOCK (p)) + flag |= BLOCK_FIELD_IS_WEAK; + /* _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */ + call_exp = build_block_object_dispose_call_exp (src_block_component, flag); + add_stmt (call_exp); } finish_compound_stmt (stmt); @@ -21490,8 +21402,6 @@ /* APPLE LOCAL radar 6160536 */ block_helper_function_decl = build_helper_func_decl (build_block_helper_name (unique_count), ftype); - if (current_function_decl) - DECL_NO_STATIC_CHAIN (current_function_decl) = 0; DECL_CONTEXT (block_helper_function_decl) = current_function_decl; cur_block->helper_func_decl = block_helper_function_decl; @@ -21713,6 +21623,8 @@ { COPYABLE_BYREF_LOCAL_VAR (byref_decl) = 1; COPYABLE_BYREF_LOCAL_NONPOD (byref_decl) = COPYABLE_BYREF_LOCAL_NONPOD (decl); + /* APPLE LOCAL radar 5847976 */ + COPYABLE_WEAK_BLOCK (byref_decl) = COPYABLE_WEAK_BLOCK (decl); } /* Current scope must be that of the main function body. */ @@ -21983,6 +21895,8 @@ /* APPLE LOCAL radar 6172148 */ BLOCK_SYNTHESIZED_FUNC (func_decl) = 1; retrofit_lang_decl (func_decl); + if (current_function_decl) + DECL_NO_STATIC_CHAIN (current_function_decl) = 0; return func_decl; } Modified: llvm-gcc-4.2/trunk/gcc/langhooks-def.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/langhooks-def.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/langhooks-def.h (original) +++ llvm-gcc-4.2/trunk/gcc/langhooks-def.h Tue Nov 25 16:26:23 2008 @@ -97,6 +97,10 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, tree); +/* APPLE LOCAL begin 6353006 */ +extern tree lhd_build_generic_block_struct_type (void); +/* APPLE LOCAL end 6353006 */ + #define LANG_HOOKS_NAME "GNU unknown" #define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier) #define LANG_HOOKS_INIT hook_bool_void_false @@ -145,6 +149,11 @@ #define LANG_HOOKS_FUNCTION_LEAVE_NESTED lhd_do_nothing_f #define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P hook_bool_tree_true +/* APPLE LOCAL begin radar 6353006 */ +#define LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE \ + lhd_build_generic_block_struct_type +/* APPLE LOCAL end radar 6353006 */ + /* Attribute hooks. */ #define LANG_HOOKS_ATTRIBUTE_TABLE NULL #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE NULL @@ -337,6 +346,8 @@ LANG_HOOKS_BUILTIN_FUNCTION, \ LANG_HOOKS_INIT_TS, \ LANG_HOOKS_EXPR_TO_DECL, \ +/* APPLE LOCAL radar 6353006 */ \ + LANG_HOOKS_BUILD_GENERIC_BLOCK_STRUCT_TYPE, \ } #endif /* GCC_LANG_HOOKS_DEF_H */ Modified: llvm-gcc-4.2/trunk/gcc/langhooks.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/langhooks.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/langhooks.c (original) +++ llvm-gcc-4.2/trunk/gcc/langhooks.c Tue Nov 25 16:26:23 2008 @@ -613,3 +613,11 @@ tree t ATTRIBUTE_UNUSED) { } + +/* APPLE LOCAL begin radar 6353006 */ +tree +lhd_build_generic_block_struct_type (void) +{ + return NULL_TREE; +} +/* APPLE LOCAL end radar 6353006 */ Modified: llvm-gcc-4.2/trunk/gcc/langhooks.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/langhooks.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/langhooks.h (original) +++ llvm-gcc-4.2/trunk/gcc/langhooks.h Tue Nov 25 16:26:23 2008 @@ -468,6 +468,13 @@ TREE_SIDE_EFFECTS need updating. */ tree (*expr_to_decl) (tree expr, bool *tc, bool *ti, bool *se); + + /* APPLE LOCAL begin radar 6353006 */ + /* For c-based languages, builds a generic type for Blocks pointers (for + emitting debug information. For other languages, returns NULL. */ + tree (*build_generic_block_struct_type) (void); + /* APPLE LOCAL end radar 6353006 */ + /* Whenever you add entries here, make sure you adjust langhooks-def.h and langhooks.c accordingly. */ }; Modified: llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/objc/ChangeLog.apple Tue Nov 25 16:26:23 2008 @@ -1,3 +1,39 @@ +2008-11-14 Fariborz Jahanian + + Radar 6370136 + * objc-act.c (objc_merge_protocol_methods): Merge copied + list of protocol's methods into class. + +2008-11-13 Fariborz Jahanian + + Radar 6351990 (minor tweak). + * objc-act.c (build_protocol_list_address_table): Move couple + of variables out of the loop. + +2008-11-11 Fariborz Jahanian + + Radar 6351990 + * objc-act.c (build_protocollist_reference_decl): Builds + a weak visibility hidder symbol for protocol reference + meta-data symbols. + (objc_add_to_protocol_list_chain): Takes addition argument + and builds a tree using this argument. + (build_protocol_list_address_table): Now builds a list + of protocol label and address of generated protocol symbol. + +2008-11-07 Fariborz Jahanian + + Radar 5847976 + * objc-act.c (objc_is_gcable_type): Made global. + (objc_build_weak_reference_tree): Quick return if + -fobjc-gc unspecified. + (objc_checkon_weak_attribute): Ditto. + (objc_generate_write_barrier): Generate write-barrier for + a __block variable declared as __weak. + (retain_block_component, release_block_component, + copy_in_object): Removed. + (cast_to_pointer_to_id): Removed. + 2008-10-27 Fariborz Jahanian Radar 6231433 Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Tue Nov 25 16:26:23 2008 @@ -224,7 +224,6 @@ /* APPLE LOCAL begin objc new property */ static bool objc_lookup_protocol (tree, tree, tree, bool); -static int objc_is_gcable_type (tree); /* APPLE LOCAL radar 5277239 */ static tree lookup_method_static (tree, tree, int, bool, bool); /* APPLE LOCAL radar 4817072 */ @@ -272,8 +271,8 @@ static void init_UOBJC2_EHTYPE_decls (void); static void create_ivar_offset_name (char *, tree, tree); static void build_v2_category_template (void); -/* APPLE LOCAL radar 4533974 - ObjC new protocol */ -static tree build_protocollist_reference_decl (void); +/* APPLE LOCAL radar 4533974 - ObjC new protocol - radar 6351990 */ +static tree build_protocollist_reference_decl (tree); static void objc_add_to_category_list_chain (tree); static void objc_add_to_nonlazy_category_list_chain (tree); /* APPLE LOCAL begin radar 4441049 */ @@ -1081,7 +1080,6 @@ void objc_continue_implementation (void) - { objc_ivar_chain = continue_class (objc_implementation_context); @@ -4531,6 +4529,8 @@ tree type; enum debug_info_type save_write_symbols = write_symbols; const struct gcc_debug_hooks *const save_hooks = debug_hooks; + /* APPLE LOCAL 6348516 */ + int save_warn_padded; /* Suppress outputting debug symbols, because dbxout_init hasn'r been called yet. */ @@ -4871,12 +4871,18 @@ } /* APPLE LOCAL end ObjC new abi */ build_protocol_template (); + /* APPLE LOCAL begin 6348516 */ + save_warn_padded = warn_padded; + warn_padded = 0; + /* APPLE LOCAL end 6348516 */ build_category_template (); build_objc_exception_stuff (); if (flag_next_runtime) build_next_objc_exception_stuff (); + /* APPLE LOCAL 6348516 */ + warn_padded = save_warn_padded; /* static SEL _OBJC_SELECTOR_TABLE[]; */ if (! flag_next_runtime) @@ -6775,7 +6781,8 @@ they are pointers to types that are themselves GC-able. */ /* APPLE LOCAL end ObjC GC */ -static int +/* APPLE LOCAL radar 5847976 */ +int /* APPLE LOCAL ObjC GC */ objc_is_gcable_type (tree type) { @@ -7049,6 +7056,10 @@ tree objc_build_weak_reference_tree (tree expr) { + /* APPLE LOCAL begin radar 5847976 */ + if (!flag_objc_gc) + return expr; + /* APPLE LOCAL end radar 5847976 */ return objc_tree_is_weak_expr (expr) ? build1 (OBJC_WEAK_REFERENCE_EXPR, TREE_TYPE (expr), expr) : expr; } @@ -7087,6 +7098,10 @@ void objc_checkon_weak_attribute (tree decl) { + /* APPLE LOCAL begin radar 5747976 */ + if (!flag_objc_gc) + return; + /* APPLE LOCAL end radar 5747976 */ if (decl && DECL_P (decl)) { if (objc_collecting_ivars @@ -7094,7 +7109,8 @@ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))) return; - if ((TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL) + /* APPLE LOCAL radar 5847976 */ + if ((TREE_CODE (decl) == FIELD_DECL || (TREE_CODE (decl) == VAR_DECL && !COPYABLE_BYREF_LOCAL_VAR (decl))) && objc_is_gcable_type (TREE_TYPE (decl)) == -1) { location_t saved_location = input_location; @@ -7448,7 +7464,20 @@ } /* APPLE LOCAL begin radar 4426814 */ if (strong == -1) - return NULL_TREE; + { + /* APPLE LOCAL begin radar 5847976 */ + /* Must generate write barrier for __block objects which are __weak + and used in an assignment. */ + if (TREE_CODE (outer) == COMPONENT_REF && TREE_OPERAND (outer, 0) + && TREE_CODE (TREE_OPERAND (outer, 0)) == VAR_DECL) + { + tree var_decl = TREE_OPERAND (outer, 0); + if (COPYABLE_WEAK_BLOCK (var_decl)) + return objc_build_global_assignment (lhs, rhs, -1); + } + /* APPLE LOCAL end radar 5847976 */ + return NULL_TREE; + } /* APPLE LOCAL end radar 4426814 */ /* LLVM LOCAL - begin 5541393 */ @@ -12364,12 +12393,13 @@ in the __protocol_list section. */ static void -objc_add_to_protocol_list_chain (tree protocol_decl) +/* APPLE LOCAL begin radar 6351990 */ +objc_add_to_protocol_list_chain (tree protocol_interface_decl, tree protocol_decl) { tree *chain; for (chain = &protocol_list_chain; *chain; chain = &TREE_CHAIN (*chain)) ; - *chain = tree_cons (NULL_TREE, protocol_decl, NULL_TREE); + *chain = tree_cons (protocol_interface_decl, protocol_decl, NULL_TREE); } /* Build the __protocol_list section table containing address of all generate protocol_t @@ -12379,34 +12409,34 @@ build_protocol_list_address_table (void) { tree chain; - int count=0; - tree type; - tree initlist = NULL_TREE; - tree decl; - tree expr; tree list_chain = protocol_list_chain; - const char *label_name = "_OBJC_LABEL_PROTOCOL_$"; + char *string = NULL; + unsigned int buf_size = 0; for (chain = list_chain; chain; chain = TREE_CHAIN (chain)) { - tree purpose = NULL_TREE; - expr = TREE_VALUE (chain); + tree decl = TREE_PURPOSE (chain); + tree expr = TREE_VALUE (chain); + gcc_assert (decl && TREE_CODE (decl) == PROTOCOL_INTERFACE_TYPE); + if ((strlen ("l_OBJC_LABEL_PROTOCOL_$_") + strlen (IDENTIFIER_POINTER (PROTOCOL_NAME (decl))) + 1) > buf_size) + { + if (!buf_size) + buf_size = BUFSIZE; + else + buf_size = strlen ("l_OBJC_LABEL_PROTOCOL_$_") + strlen (IDENTIFIER_POINTER (PROTOCOL_NAME (decl))) + 1; + string = (char *)alloca (buf_size); + } + sprintf (string, "l_OBJC_LABEL_PROTOCOL_$_%s", IDENTIFIER_POINTER (PROTOCOL_NAME (decl))); + decl = create_hidden_decl (objc_protocol_type, string); + DECL_WEAK (decl) = 1; + set_user_assembler_name (decl, string); expr = convert (objc_protocol_type, build_fold_addr_expr (expr)); -#ifndef OBJCPLUS - purpose = build_int_cst (NULL_TREE, count); -#endif - ++count; - initlist = tree_cons (purpose, expr, initlist); + /* APPLE LOCAL radar 4561192 */ + objc_set_alignment_attribute (decl, objc_protocol_type); + finish_var_decl (decl, expr); } - gcc_assert (count > 0); - type = build_array_type (objc_protocol_type, - build_index_type (build_int_cst (NULL_TREE, count - 1))); - decl = start_var_decl (type, label_name); - expr = objc_build_constructor (type, nreverse (initlist)); - /* APPLE LOCAL radar 4561192 */ - objc_set_alignment_attribute (decl, objc_protocol_type); - finish_var_decl (decl, expr); } +/* APPLE LOCAL end radar 6351990 */ /* Build decl = initializer; for each protocol referenced in @protocol(MyProtole) expression. */ @@ -12480,33 +12510,39 @@ if (TREE_VALUE (*chain) == ident) { if (! TREE_PURPOSE (*chain)) - TREE_PURPOSE (*chain) = build_protocollist_reference_decl (); + /* APPLE LOCAL radar 6351990 */ + TREE_PURPOSE (*chain) = build_protocollist_reference_decl (ident); return TREE_PURPOSE (*chain); } - decl = build_protocollist_reference_decl (); + /* APPLE LOCAL radar 6351990 */ + decl = build_protocollist_reference_decl (ident); *chain = tree_cons (decl, ident, NULL_TREE); return decl; } -static GTY(()) int protocollist_reference_idx; - /* This routine creates a static variable used to implement @protocol(MyProtocol) expression. This variable will be initialized to global protocol_t meta-data pointer. */ +/* APPLE LOCAL begin radar 6351990 */ static tree -build_protocollist_reference_decl (void) +build_protocollist_reference_decl (tree protocol) { tree decl; - char buf[BUFSIZE]; + tree protocol_ident = PROTOCOL_NAME (protocol); + char *buf = (char *)alloca (strlen ("l_OBJC_PROTOCOL_REFERENCE_$_") + + IDENTIFIER_LENGTH (protocol_ident) + 1); - sprintf (buf, "_OBJC_PROTOCOL_REFERENCE_$_%d", protocollist_reference_idx++); - decl = start_var_decl (objc_protocol_type, buf); + sprintf (buf, "l_OBJC_PROTOCOL_REFERENCE_$_%s", IDENTIFIER_POINTER (protocol_ident)); + decl = create_hidden_decl (objc_protocol_type, buf); + DECL_WEAK (decl) = 1; + set_user_assembler_name (decl, buf); return decl; } +/* APPLE LOCAL end radar 6351990 */ /* APPLE LOCAL end radar 4533974 - ObjC new protocol */ /* Add the global class meta-data declaration to the list which later on ends up @@ -14214,8 +14250,8 @@ reset_initializer_llvm(decl); #endif /* LLVM LOCAL end */ - /* APPLE LOCAL radar 4533974 - ObjC new protocol */ - objc_add_to_protocol_list_chain (decl); + /* APPLE LOCAL radar 4533974 - ObjC new protocol - radar 6351990 */ + objc_add_to_protocol_list_chain (p, decl); } } @@ -16878,8 +16914,13 @@ tree p = TREE_VALUE (rproto); if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) { - objc_merge_methods (class, PROTOCOL_CLS_METHODS (p), '+'); - objc_merge_methods (class, PROTOCOL_NST_METHODS (p), '-'); + /* APPLE LOCAL begin radar 6370136 */ + /* Call objc_merge_methods on copied list of methods, as insertion + of methods in class's method list has side-effect of modifying + protocol's method list which must not change. */ + objc_merge_methods (class, copy_list (PROTOCOL_CLS_METHODS (p)), '+'); + objc_merge_methods (class, copy_list (PROTOCOL_NST_METHODS (p)), '-'); + /* APPLE LOCAL end radar 6370136 */ /* Search in nested protocols also. */ objc_merge_proto_properties_in_class (class, PROTOCOL_LIST (p)); } @@ -19324,7 +19365,7 @@ DECL_CONTEXT (decl) = 0; DECL_ARTIFICIAL (decl) = 1; DECL_INITIAL (decl) = initlist; - /* APPLE LOCAL begin LLVM */ + /* APPLE LOCAL begin LLVM */ #ifdef ENABLE_LLVM /* Let optimizer know that this decl is not removable. */ set_user_assembler_name(decl, IDENTIFIER_POINTER (DECL_NAME(decl))); @@ -20356,63 +20397,10 @@ } /* APPLE LOCAL end radar 5376125 */ /* APPLE LOCAL begin radar 5782740 - blocks */ -tree retain_block_component (tree exp) -{ - /* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ - /* We do not want to warn on [id retain] message because we know what we - are doing. */ - tree ret_exp; - donot_warn_missing_methods = 1; - ret_exp = objc_finish_message_expr (exp, get_identifier ("retain"), NULL_TREE); - donot_warn_missing_methods = 0; - return ret_exp; - /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ -} - -tree release_block_component (tree exp) -{ - /* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ - /* We do not want to warn on [id release] message because we know what we - are doing. */ - tree ret_exp; - donot_warn_missing_methods = 1; - ret_exp = objc_finish_message_expr (exp, get_identifier ("release"), NULL_TREE); - donot_warn_missing_methods = 0; - return ret_exp; - /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ -} - -/** copy_in_object - This routine for objective-c object pointers, returns - [ [EXP retain] autorelease ] expression which is used in initialization - of copied in variable used to set up a block literal struct. -*/ -tree copy_in_object (tree exp) -{ -/* APPLE LOCAL begin radar 5808305 */ - return exp; -#if 0 - tree msg_exp; - tree type = TREE_TYPE (exp); - if (!objc_is_object_ptr (type)) - return exp; - msg_exp = retain_block_component (exp); - msg_exp = objc_finish_message_expr (msg_exp, get_identifier ("autorelease"), NULL_TREE); - return msg_exp; -#endif -/* APPLE LOCAL end radar 5808305 */ -} - bool block_requires_copying (tree exp) { return TREE_CODE (TREE_TYPE (exp)) == BLOCK_POINTER_TYPE || objc_is_object_ptr (TREE_TYPE (exp)); } /* APPLE LOCAL end radar 5782740 - blocks */ -/* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ -tree cast_to_pointer_to_id (tree exp) -{ - tree type = build_pointer_type (objc_object_type); - return build_c_cast (type, exp); -} -/* APPLE LOCAL end radar 5932809 - copyable byref blocks */ #include "gt-objc-objc-act.h" Modified: llvm-gcc-4.2/trunk/gcc/stub-objc.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/stub-objc.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/stub-objc.c (original) +++ llvm-gcc-4.2/trunk/gcc/stub-objc.c Tue Nov 25 16:26:23 2008 @@ -510,6 +510,13 @@ return; } /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ +/* APPLE LOCAL begin radar 5847976 */ +int +objc_is_gcable_type (tree ARG_UNUSED (type)) +{ + return 0; +} +/* APPLE LOCAL end radar 5847976 */ /* APPLE LOCAL begin radar 4592503 */ void objc_checkon_weak_attribute (tree ARG_UNUSED (decl)) @@ -582,18 +589,6 @@ /* APPLE LOCAL end radar 5202926 */ /* APPLE LOCAL begin radar 5782740 - blocks */ -tree copy_in_object (tree exp) -{ - return exp; -} -tree retain_block_component (tree ARG_UNUSED (exp)) -{ - return NULL_TREE; -} -tree release_block_component (tree ARG_UNUSED (exp)) -{ - return NULL_TREE; -} bool block_requires_copying (tree exp) { /* APPLE LOCAL begin radar 6175959 */ @@ -611,9 +606,3 @@ return object; } /* APPLE LOCAL end radar 5802025 */ -/* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ -tree cast_to_pointer_to_id (tree exp) -{ - return exp; -} -/* APPLE LOCAL end radar 5932809 - copyable byref blocks */ Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-67.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/asm-block-67.C?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-67.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-67.C Tue Nov 25 16:26:23 2008 @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-fasm-blocks" } */ + +int i = 1st; /* { dg-error "invalid suffix on integer constant" } */ Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblock.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-weakblock.C?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblock.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblock.C Tue Nov 25 16:26:23 2008 @@ -0,0 +1,54 @@ +/* APPLE LOCAL radar 5847976 */ +/* Test __weak attribute on __block objects. */ +/* { dg-options "-mmacosx-version-min=10.6 -ObjC++ -fobjc-gc -framework Foundation" { target *-*-darwin* } } */ +/* { dg-do run } */ +#import + +// provide our own version for testing + +int GotCalled = 0; + +void _Block_object_assign(void *destAddr, const void *object, const int flags) { + printf("_Block_object_assign(dest %p, value %p, flags %x)\n", destAddr, object, flags); + ++GotCalled; +} + +int recovered = 0; + + at interface TestObject : NSObject { +} + at end + + at implementation TestObject +- (id)retain { + printf("Whoops, retain called!\n"); + exit(1); +} +- (void)finalize { + ++recovered; + [super finalize]; +} +- (void)dealloc { + ++recovered; + [super dealloc]; +} + at end + + +void testRR() { + // create test object + TestObject *to = [[TestObject alloc] init]; + __block TestObject *__weak testObject = to; // iniitialization does NOT require support function +} + +int main(int argc, char *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GotCalled = 0; + testRR(); + if (GotCalled == 1) { + printf("called out to support function on initialization\n"); + return 1; + } + printf("%s: Success\n", argv[0]); + return 0; +} Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblockassign.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-weakblockassign.C?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblockassign.C (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-weakblockassign.C Tue Nov 25 16:26:23 2008 @@ -0,0 +1,61 @@ +/* APPLE LOCAL radar 5847976 */ +/* Test __weak attribute on __block objects. */ +/* { dg-options "-mmacosx-version-min=10.6 -ObjC++ -fobjc-gc -framework Foundation" { target *-*-darwin* } } */ +/* { dg-do run } */ + +#import + +// provide our own version for testing + +int GotCalled = 0; + +void objc_assign_weak(id value, id * location) { + ++GotCalled; + *location = value; +} + +int recovered = 0; + + at interface TestObject : NSObject { +} + at end + + at implementation TestObject +- (id)retain { + printf("Whoops, retain called!\n"); + exit(1); +} +- (void)finalize { + ++recovered; + [super finalize]; +} +- (void)dealloc { + ++recovered; + [super dealloc]; +} + at end + + +void testRR() { + // create test object + TestObject *to = [[TestObject alloc] init]; + __block TestObject *__weak testObject = to; // initialization does NOT require support function + + // there could be a Block that references "testObject" and that block could have been copied to the + // heap and the Block_byref forwarding pointer aims at the heap object. + // Assigning to it should trigger, under GC, the objc_assign_weak call + testObject = [NSObject new]; // won't last long :-) +} + +int main(int argc, char *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GotCalled = 0; + testRR(); + if (GotCalled == 0) { + printf("didn't call out to support function on assignment\n"); + return 1; + } + printf("%s: Success\n", argv[0]); + return 0; +} + Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-67.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-67.c?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-67.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-67.c Tue Nov 25 16:26:23 2008 @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-fasm-blocks" } */ + +int i = 1st; /* { dg-error "invalid suffix \"st\" on integer constant" } */ Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblock.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblock.c?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblock.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblock.c Tue Nov 25 16:26:23 2008 @@ -0,0 +1,54 @@ +/* APPLE LOCAL radar 5847976 */ +/* Test __weak attribute on __block objects. */ +/* { dg-options "-mmacosx-version-min=10.6 -ObjC -fobjc-gc -framework Foundation" { target *-*-darwin* } } */ +/* { dg-do run } */ +#import + +// provide our own version for testing + +int GotCalled = 0; + +void _Block_object_assign(void *destAddr, const void *object, const int flags) { + printf("_Block_object_assign(dest %p, value %p, flags %x)\n", destAddr, object, flags); + ++GotCalled; +} + +int recovered = 0; + + at interface TestObject : NSObject { +} + at end + + at implementation TestObject +- (id)retain { + printf("Whoops, retain called!\n"); + exit(1); +} +- (void)finalize { + ++recovered; + [super finalize]; +} +- (void)dealloc { + ++recovered; + [super dealloc]; +} + at end + + +void testRR() { + // create test object + TestObject *to = [[TestObject alloc] init]; + __block TestObject *__weak testObject = to; // iniitialization does NOT require support function +} + +int main(int argc, char *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GotCalled = 0; + testRR(); + if (GotCalled == 1) { + printf("called out to support function on initialization\n"); + return 1; + } + printf("%s: Success\n", argv[0]); + return 0; +} Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblockassign.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblockassign.c?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblockassign.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-weakblockassign.c Tue Nov 25 16:26:23 2008 @@ -0,0 +1,61 @@ +/* APPLE LOCAL radar 5847976 */ +/* Test __weak attribute on __block objects. */ +/* { dg-options "-mmacosx-version-min=10.6 -ObjC -fobjc-gc -framework Foundation" { target *-*-darwin* } } */ +/* { dg-do run } */ + +#import + +// provide our own version for testing + +int GotCalled = 0; + +void objc_assign_weak(id value, id * location) { + ++GotCalled; + *location = value; +} + +int recovered = 0; + + at interface TestObject : NSObject { +} + at end + + at implementation TestObject +- (id)retain { + printf("Whoops, retain called!\n"); + exit(1); +} +- (void)finalize { + ++recovered; + [super finalize]; +} +- (void)dealloc { + ++recovered; + [super dealloc]; +} + at end + + +void testRR() { + // create test object + TestObject *to = [[TestObject alloc] init]; + __block TestObject *__weak testObject = to; // initialization does NOT require support function + + // there could be a Block that references "testObject" and that block could have been copied to the + // heap and the Block_byref forwarding pointer aims at the heap object. + // Assigning to it should trigger, under GC, the objc_assign_weak call + testObject = [NSObject new]; // won't last long :-) +} + +int main(int argc, char *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GotCalled = 0; + testRR(); + if (GotCalled == 0) { + printf("didn't call out to support function on assignment\n"); + return 1; + } + printf("%s: Success\n", argv[0]); + return 0; +} + Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/i386/4299257.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/i386/4299257.c?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/i386/4299257.c (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/i386/4299257.c Tue Nov 25 16:26:23 2008 @@ -0,0 +1,10 @@ +/* APPLE LOCAL file 4299257 */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target sse4 } */ +/* Require a test of the parity flag. */ +/* { dg-final { scan-assembler "\t\(j|set\)n?p\t" } } */ +typedef float vFloat __attribute__((vector_size(16))); +char *t(vFloat a, vFloat b) +{ + return __builtin_ia32_ucomieq(a, b) ? "y" : "n"; +} Added: llvm-gcc-4.2/trunk/gcc/testsuite/obj-c++.dg/objc2-objc2-protocol-3.mm URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/obj-c%2B%2B.dg/objc2-objc2-protocol-3.mm?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/obj-c++.dg/objc2-objc2-protocol-3.mm (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/obj-c++.dg/objc2-objc2-protocol-3.mm Tue Nov 25 16:26:23 2008 @@ -0,0 +1,21 @@ +/* APPLE LOCAL file radar 6351990 */ +/* { dg-options "-mmacosx-version-min=10.6 -m32 -fobjc-abi-version=2" { target *-*-darwin* } } */ +/* { dg-do compile { target *-*-darwin* } } */ + + at protocol PROTO + at end + at protocol PROTO1 + at end + at protocol PROTO2 + at end + + at interface INTF @end + + at implementation INTF @end + +int main() +{ + return (long) @protocol(PROTO); + (long) @protocol(PROTO1); +} +/* { dg-final { scan-assembler "l_OBJC_LABEL_PROTOCOL_\\\$_PROTO:\n\t.long\tl_OBJC_PROTOCOL_\\\$_PROTO" } } */ +/* { dg-final { scan-assembler "l_OBJC_PROTOCOL_REFERENCE_\\\$_PROTO:\n\t.long\tl_OBJC_PROTOCOL_\\\$_PROTO" } } */ Added: llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/objc2-objc2-protocol-3.m URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/objc2-objc2-protocol-3.m?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/objc2-objc2-protocol-3.m (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/objc2-objc2-protocol-3.m Tue Nov 25 16:26:23 2008 @@ -0,0 +1,21 @@ +/* APPLE LOCAL file radar 6351990 */ +/* { dg-options "-mmacosx-version-min=10.6 -m32 -fobjc-abi-version=2" { target *-*-darwin* } } */ +/* { dg-do compile { target *-*-darwin* } } */ + + at protocol PROTO + at end + at protocol PROTO1 + at end + at protocol PROTO2 + at end + + at interface INTF @end + + at implementation INTF @end + +int main() +{ + return (long) @protocol(PROTO); + (long) @protocol(PROTO1); +} +/* { dg-final { scan-assembler "l_OBJC_LABEL_PROTOCOL_\\\$_PROTO:\n\t.long\tl_OBJC_PROTOCOL_\\\$_PROTO" } } */ +/* { dg-final { scan-assembler "l_OBJC_PROTOCOL_REFERENCE_\\\$_PROTO:\n\t.long\tl_OBJC_PROTOCOL_\\\$_PROTO" } } */ Added: llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/ok-unimplemented-anon-category.m URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/ok-unimplemented-anon-category.m?rev=60061&view=auto ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/ok-unimplemented-anon-category.m (added) +++ llvm-gcc-4.2/trunk/gcc/testsuite/objc.dg/ok-unimplemented-anon-category.m Tue Nov 25 16:26:23 2008 @@ -0,0 +1,51 @@ +/* APPLE LOCAL file radar 6370136 */ +/* Fix regression caused by fix to radar 6017984 - Test must clean compile. */ +/* { dg-options "-Werror" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +#import + + at interface Foo : NSView {} + at end + + at interface FooTextView : NSTextView {} + at end + + at protocol FooTextViewDelegate +- (void)bar:(FooTextView *)textView; +- (void)bas:(FooTextView *)textView; +- (void)bat:(FooTextView *)textView; + at end + + at interface FooTextView() +- (void)setDelegate:(id )delegate; +- (id )delegate; + at end + + at interface Foo() + at end + + at implementation Foo +- (void)bar:(FooTextView *)textView {} + +- (void)bas:(FooTextView *)textView {} + +- (void)bat:(FooTextView *)textView {} + at end + + at implementation FooTextView +- (void)setDelegate:(id )delegate { + [super setDelegate:delegate]; +} + +- (id )delegate { + return (id )[super delegate]; +} + +- (void)jellyBean:(id)sender { + [[self delegate] bas:self]; + [[self delegate] bat:self]; + [[self delegate] bar:self]; +} + + at end Modified: llvm-gcc-4.2/trunk/gcc/tree.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree.c Tue Nov 25 16:26:23 2008 @@ -69,10 +69,12 @@ "expression", }; +/* APPLE LOCAL begin 6353006 */ +tree generic_block_literal_struct_type; +/* APPLE LOCAL end 6353006 */ + /* obstack.[ch] explicitly declined to prototype this. */ extern int _obstack_allocated_p (struct obstack *h, void *obj); -/* APPLE LOCAL radar 6300081 */ -tree generic_block_literal_struct_type = NULL; #ifdef GATHER_STATISTICS /* Statistics-gathering stuff. */ @@ -5110,10 +5112,11 @@ { tree t; - /* APPLE LOCAL begin radar 6300081 */ + /* APPLE LOCAL begin radar 6300081 & 6353006 */ if (!generic_block_literal_struct_type) - generic_block_literal_struct_type = build_generic_block_struct_type (); - /* APPLE LOCAL end radar 6300081 */ + generic_block_literal_struct_type = + lang_hooks.build_generic_block_struct_type (); + /* APPLE LOCAL end radar 6300081 & 6353006 */ t = make_node (BLOCK_POINTER_TYPE); Modified: llvm-gcc-4.2/trunk/gcc/tree.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.h (original) +++ llvm-gcc-4.2/trunk/gcc/tree.h Tue Nov 25 16:26:23 2008 @@ -3070,7 +3070,9 @@ unsigned copyable_byref_local_nonpod : 1; /* APPLE LOCAL radar 6172148 */ unsigned block_synthesized_function : 1; - /* 6 unused bits. */ + /* APPLE LOCAL radar 5847976 */ + unsigned block_weak : 1; + /* 5 unused bits. */ /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ /* APPLE LOCAL end radar 5732232 - blocks */ }; @@ -3127,6 +3129,8 @@ /* APPLE LOCAL begin radar 5932809 - copyable byref blocks */ #define COPYABLE_BYREF_LOCAL_VAR(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.copyable_byref_local_var) #define COPYABLE_BYREF_LOCAL_NONPOD(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.copyable_byref_local_nonpod) +/* APPLE LOCAL radar 5847976 */ +#define COPYABLE_WEAK_BLOCK(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.block_weak) /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ /* In a VAR_DECL, nonzero if the data should be allocated from @@ -4853,7 +4857,6 @@ /* APPLE LOCAL begin radar 6300081 */ extern GTY(()) tree generic_block_literal_struct_type; -extern tree build_generic_block_struct_type (void); /* APPLE LOCAL end radar 6300081 */ #endif /* GCC_TREE_H */ Modified: llvm-gcc-4.2/trunk/gcc/version.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/version.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/version.c (original) +++ llvm-gcc-4.2/trunk/gcc/version.c Tue Nov 25 16:26:23 2008 @@ -11,12 +11,12 @@ /* APPLE LOCAL begin Apple version */ #ifdef ENABLE_LLVM #ifdef LLVM_VERSION_INFO -#define VERSUFFIX " (Based on Apple Inc. build 5627) (LLVM build " LLVM_VERSION_INFO ")" +#define VERSUFFIX " (Based on Apple Inc. build 5628) (LLVM build " LLVM_VERSION_INFO ")" #else -#define VERSUFFIX " (Based on Apple Inc. build 5627) (LLVM build)" +#define VERSUFFIX " (Based on Apple Inc. build 5628) (LLVM build)" #endif #else -#define VERSUFFIX " (Based on Apple Inc. build 5627)" +#define VERSUFFIX " (Based on Apple Inc. build 5628)" #endif /* APPLE LOCAL end Apple version */ Modified: llvm-gcc-4.2/trunk/libcpp/expr.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libcpp/expr.c?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/libcpp/expr.c (original) +++ llvm-gcc-4.2/trunk/libcpp/expr.c Tue Nov 25 16:26:23 2008 @@ -160,7 +160,8 @@ floating point, or invalid), radix (decimal, octal, hexadecimal), and type suffixes. */ unsigned int -cpp_classify_number (cpp_reader *pfile, const cpp_token *token) +/* APPLE LOCAL CW asm blocks C++ comments 6338079 */ +cpp_classify_number (cpp_reader *pfile, const cpp_token *token, int defer) { const uchar *str = token->val.str.text; const uchar *limit; @@ -293,8 +294,8 @@ /* APPLE LOCAL begin CW asm blocks C++ comments 4248139 */ /* Because we don't regonize inline asm comments during lexing, we have to avoid erroring out now. */ - if (cpp_get_options (pfile)->h_suffix) - return CPP_N_INVALID; + if (defer && cpp_get_options (pfile)->h_suffix) + return CPP_N_INVALID | CPP_N_DEFER; /* APPLE LOCAL end CW asm blocks C++ comments 4248139 */ cpp_error (pfile, CPP_DL_ERROR, @@ -569,7 +570,8 @@ switch (token->type) { case CPP_NUMBER: - temp = cpp_classify_number (pfile, token); + /* APPLE LOCAL CW asm blocks C++ comments 6338079 */ + temp = cpp_classify_number (pfile, token, 0); switch (temp & CPP_N_CATEGORY) { case CPP_N_FLOATING: Modified: llvm-gcc-4.2/trunk/libcpp/include/cpplib.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libcpp/include/cpplib.h?rev=60061&r1=60060&r2=60061&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/libcpp/include/cpplib.h (original) +++ llvm-gcc-4.2/trunk/libcpp/include/cpplib.h Tue Nov 25 16:26:23 2008 @@ -184,6 +184,10 @@ #define BOL (1 << 6) /* Token at beginning of line. */ #define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, set in c-lex.c. */ +/* APPLE LOCAL begin CW asm blocks C++ comments 6338079 */ +#define ERROR_DEFERRED PURE_ZERO/* Set when an invalid suffix error is + deferred out of cpp. */ +/* APPLE LOCAL end CW asm blocks C++ comments 6338079 */ /* Specify which field, if any, of the cpp_token union is used. */ @@ -859,10 +863,13 @@ #define CPP_N_UNSIGNED 0x1000 /* Properties. */ #define CPP_N_IMAGINARY 0x2000 #define CPP_N_DFLOAT 0x4000 +/* APPLE LOCAL CW asm blocks C++ comments 6338079 */ +#define CPP_N_DEFER 0x8000 /* Classify a CPP_NUMBER token. The return value is a combination of the flags from the above sets. */ -extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *); +/* APPLE LOCAL CW asm blocks C++ comments 6338079 */ +extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *, int); /* Evaluate a token classified as category CPP_N_INTEGER. */ extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, From isanbard at gmail.com Tue Nov 25 17:00:57 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 23:00:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60062 - in /llvm-gcc-4.2/trunk/gcc/testsuite: ./ bugs/powerpc/ g++.apple/ gcc.apple/ gcc.dg/ gcc.dg/cpp/ gcc.dg/pch/ Message-ID: <200811252301.mAPN10oQ028150@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 17:00:54 2008 New Revision: 60062 URL: http://llvm.org/viewvc/llvm-project?rev=60062&view=rev Log: Update test suite to Apple GCC's versions. Modified: llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple llvm-gcc-4.2/trunk/gcc/testsuite/bugs/powerpc/gcc.xfail llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-23.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-61.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-dynamic-array.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-do.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for1.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-nested-while.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return1.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-switch.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-while.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-no-trampoline.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-1.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-2.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-3.C llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper.C llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6025404.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6308664.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-23.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-61.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-dynamic-array.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-do.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-nested-while.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-switch.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-while.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-no-trampoline.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-2.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-3.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/i386-bitmask1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/uninit-test-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2s.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-2.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-version-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-3.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/dollar.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.hs llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-1.c llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-2.c Modified: llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/ChangeLog.apple Tue Nov 25 17:00:54 2008 @@ -1,3 +1,62 @@ +2008-11-18 Stuart Hastings + + Radar 6385223 + * gcc.apple/6025404.c: Check for SSSE3 support. + +2008-11-14 Fariborz Jahanian + + Radar 6370136 + * objc.dg/ok-unimplemented-anon-category.m: Add + +2008-11-11 Fariborz Jahanian + + Radar 6351990 + * objc.dg/objc2-objc2-protocol-3.m: New + * obj-c++.dg/objc2-objc2-protocol-3.mm: New + +2008-11-11 Stuart Hastings + + Radar 4299257 + * gcc.target/i386/4299257.c: New. + +2008-11-07 Fariborz Jahanian + + Radar 5847976 + * gcc.apple/block-weakblockassign.c: New + * gcc.apple/block-blocks-test-8.c: Removed + * gcc.apple/block-noescape-helper-3.c: Modified + * gcc.apple/block-escape-do.c: Modified + * gcc.apple/block-escape-switch.c: Modified + * gcc.apple/block-escape-return.c: Modified + * gcc.apple/block-escape-while.c: Modified + * gcc.apple/block-noescape-helper.c: Modified + * gcc.apple/block-escape-for.c: Modified + * gcc.apple/block-escape-nested-while.c: Modified + * gcc.apple/block-escape-for1.c: Modified + * gcc.apple/block-weakblock.c: Modified + * gcc.apple/block-noescape-helper-1.c: Modified + * gcc.apple/block-escape-return1.c: Modified + * gcc.apple/block-noescape-helper-2.c: Modified + * g++.apple/block-weakblockassign.C: New + * g++.apple/block-blocks-test-8.C: Removed + * g++.apple/block-noescape-helper-3.C: Modified + * g++.apple/block-escape-do.C: Modified + * g++.apple/block-escape-switch.C: Modified + * g++.apple/block-escape-return.C: Modified + * g++.apple/block-escape-while.C: Modified + * g++.apple/block-noescape-helper.C: Modified + * g++.apple/block-escape-for.C: Modified + * g++.apple/block-escape-nested-while.C: Modified + * g++.apple/block-escape-for1.C: Modified + * g++.apple/block-weakblock.C: Modified + * g++.apple/block-noescape-helper-1.C: Modified + * g++.apple/block-escape-return1.C: Modified + * g++.apple/block-noescape-helper-2.C: Modified + +2008-11-05 Stuart Hastings + + * gcc.apple/6308664.c: Tweak to tolerate -fstack-protector-all. + 2008-10-31 Stuart Hastings Radar 5813291 Modified: llvm-gcc-4.2/trunk/gcc/testsuite/bugs/powerpc/gcc.xfail URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/bugs/powerpc/gcc.xfail?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/bugs/powerpc/gcc.xfail (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/bugs/powerpc/gcc.xfail Tue Nov 25 17:00:54 2008 @@ -126,6 +126,12 @@ 3904235: gcc.dg/wtr-unary-plus-1.c unary plus operator (test for warnings, line 13) 5275911: gcc.dg/invalid-call-1.c non-compatible type (test for warnings, line 18) 0000000: compiler driver --coverage option(s) (compiler options) +6348516: gcc.dg/20050607-1.c (test for excess errors) +6348516: gcc.dg/Wpadded.c (test for excess errors) +6348517: gcc.dg/darwin-weakimport-1.c scan-assembler-not weak_[a-z \t]*_b +6348517: gcc.dg/darwin-weakimport-3.c scan-assembler-not coalesced +6348519: gcc.dg/pch/valid-2.c -O... -g (test for errors, line 3) [ 7 tests ] +6348519: gcc.dg/pch/valid-2.c -O0 -g (test for errors, line 3) #1 [ 7 duplicate tests ] # # -fasm-blocks only 5087183: gcc.dg/cpp/19951227-1.c (test for errors, line 2) Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-23.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/asm-block-23.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-23.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-23.C Tue Nov 25 17:00:54 2008 @@ -13,5 +13,5 @@ nop ; ## of cols nop ;  of cols } - int i = 1st 0; /* { dg-error "invalid suffix" } */ + int i = 1st; /* { dg-error "invalid suffix" } */ } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-61.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/asm-block-61.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-61.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/asm-block-61.C Tue Nov 25 17:00:54 2008 @@ -4,11 +4,11 @@ /* Radar 4739936 */ int i = 9h; -int j = 1st 0; /* { dg-error "invalid suffix on integer constant" } */ +int j = 1st; /* { dg-error "invalid suffix on integer constant" } */ void foo() { asm { - mov eax, 1st 0 /* { dg-error "invalid suffix on integer constant" } */ + mov eax, 1st /* { dg-error "invalid suffix on integer constant" } */ mov eax, 1h ; foo 1st ; bye bye Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-dynamic-array.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-dynamic-array.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-dynamic-array.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-dynamic-array.C Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file radar 6212722 */ /* Test for use of array (dynamic or static) as copied in object in a block. */ /* { dg-options "-mmacosx-version-min=10.6 -ObjC++ -framework Foundation" { target *-*-darwin* } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */ /* { dg-do run } */ #import Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-do.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-do.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-do.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-do.C Tue Nov 25 17:00:54 2008 @@ -7,7 +7,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-for.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for.C Tue Nov 25 17:00:54 2008 @@ -6,7 +6,7 @@ extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for1.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-for1.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for1.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-for1.C Tue Nov 25 17:00:54 2008 @@ -8,7 +8,7 @@ extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-nested-while.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-nested-while.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-nested-while.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-nested-while.C Tue Nov 25 17:00:54 2008 @@ -8,7 +8,7 @@ extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-return.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return.C Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern "C" void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return1.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-return1.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return1.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-return1.C Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern "C" void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-switch.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-switch.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-switch.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-switch.C Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern "C" void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-while.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-escape-while.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-while.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-escape-while.C Tue Nov 25 17:00:54 2008 @@ -6,7 +6,7 @@ extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-no-trampoline.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-no-trampoline.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-no-trampoline.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-no-trampoline.C Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file radar 6230701 */ /* Test that no trampoline is generated for this test case. */ /* { dg-options "-mmacosx-version-min=10.6 -ObjC++ -framework Foundation -O0" { target *-*-darwin* } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */ /* { dg-do run } */ #import Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-1.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-noescape-helper-1.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-1.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-1.C Tue Nov 25 17:00:54 2008 @@ -7,12 +7,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-2.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-noescape-helper-2.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-2.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-2.C Tue Nov 25 17:00:54 2008 @@ -7,12 +7,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-3.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-noescape-helper-3.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-3.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper-3.C Tue Nov 25 17:00:54 2008 @@ -1,5 +1,5 @@ /* APPLE LOCAL file radar 6083129 byref escapes */ -/* Test for generation of escape _Block_byref_release call when a __block +/* Test for generation of escape _Block_object_dispose call when a __block variable inside a block is declared and used. */ /* { dg-options "-fblocks" } */ /* { dg-do run } */ @@ -7,13 +7,13 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { - ++count; +static void _Block_object_dispose(void * arg, int flag) { + ++count; } void junk(void (^block)(void)) { @@ -21,15 +21,15 @@ } int test() { - { - void (^dummy)(void) = ^{ int __block i = 10; printf("i = %d\n", i); }; - junk(dummy); - } + void (^dummy)(void) = ^{ int __block i = 10; printf("i = %d\n", i); }; + junk(dummy); return count; } -int main() { - if (test() != 1) - abort(); - return 0; +int main() +{ + if ( test() != 1) + abort(); + return 0; } + Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper.C URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-noescape-helper.C?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper.C (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-noescape-helper.C Tue Nov 25 17:00:54 2008 @@ -5,12 +5,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern "C" void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6025404.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6025404.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6025404.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6025404.c Tue Nov 25 17:00:54 2008 @@ -3,6 +3,7 @@ /* { dg-options "-O3 -mssse3" } */ #include #include +#include "../gcc.dg/i386-cpuid.h" void foo(__m128i *a, __m128i *b, __m128i c, __m128i d, __m128i e) { *a = _mm_maddubs_epi16(c, d); @@ -10,9 +11,16 @@ } int main(void) { + unsigned long cpu_facilities; union { char c[16]; __m128i v; } c = { -1 }, d = { 1 }, e = { 1 }; union { short s[8]; __m128i v; } a, b; + cpu_facilities = i386_cpuid_ecx (); + + if ((cpu_facilities & (bit_SSSE3)) != (bit_SSSE3)) + /* If host has no SSSE3 support, pass. */ + return 0; + foo(&a.v, &b.v, c.v, d.v, e.v); if (0) Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6308664.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6308664.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6308664.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/6308664.c Tue Nov 25 17:00:54 2008 @@ -1,7 +1,7 @@ /* APPLE LOCAL file 6308664 */ /* { dg-do compile { target i?86-*-darwin* x86_64-*-darwin* } } */ -/* { dg-options { -m64 } } */ -/* { dg-final { scan-assembler-not "GOTPCREL" } } */ +/* { dg-options { -m64 -mfix-and-continue } } */ +/* { dg-final { scan-assembler-not " L.*@GOTPCREL" } } */ extern void doit(double x); void test() Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-23.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-23.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-23.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-23.c Tue Nov 25 17:00:54 2008 @@ -13,5 +13,5 @@ nop ; ## of cols nop ;  of cols } - int i = 1st 0; /* { dg-error "invalid suffix" } */ + int i = 1st; /* { dg-error "invalid suffix" } */ } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-61.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-61.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-61.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/asm-block-61.c Tue Nov 25 17:00:54 2008 @@ -4,11 +4,11 @@ /* Radar 4739936 */ int i = 9h; -int j = 1st 0; /* { dg-error "invalid suffix on integer constant" } */ +int j = 1st; /* { dg-error "invalid suffix \"st\" on integer constant" } */ void foo() { asm { - mov eax, 1st 0 /* { dg-error "invalid suffix on integer constant" } */ + mov eax, 1st /* { dg-error "invalid suffix \"st\" on integer constant" } */ mov eax, 1h ; foo 1st ; bye bye Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-dynamic-array.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-dynamic-array.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-dynamic-array.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-dynamic-array.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file radar 6212722 */ /* Test for use of array (dynamic or static) as copied in object in a block. */ /* { dg-options "-mmacosx-version-min=10.6 -ObjC -framework Foundation" { target *-*-darwin* } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */ /* { dg-do run } */ #import Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-do.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-do.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-do.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-do.c Tue Nov 25 17:00:54 2008 @@ -7,7 +7,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for.c Tue Nov 25 17:00:54 2008 @@ -6,7 +6,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-for1.c Tue Nov 25 17:00:54 2008 @@ -8,7 +8,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-nested-while.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-nested-while.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-nested-while.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-nested-while.c Tue Nov 25 17:00:54 2008 @@ -8,7 +8,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return.c Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-return1.c Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-switch.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-switch.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-switch.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-switch.c Tue Nov 25 17:00:54 2008 @@ -6,10 +6,10 @@ #include extern void abort(void); -void _Block_byref_assign_copy(void *a, void *b){}; +void _Block_object_assign(void *a, void *b, int flag){}; static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { printf ("%p\n", arg); ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-while.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-while.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-while.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-escape-while.c Tue Nov 25 17:00:54 2008 @@ -6,7 +6,7 @@ extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-no-trampoline.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-no-trampoline.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-no-trampoline.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-no-trampoline.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file radar 6230701 */ /* Test that no trampoline is generated for this test case. */ /* { dg-options "-mmacosx-version-min=10.6 -ObjC -framework Foundation -O0" { target *-*-darwin* } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */ /* { dg-do run } */ #import Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-1.c Tue Nov 25 17:00:54 2008 @@ -1,5 +1,5 @@ /* APPLE LOCAL file radar 6083129 byref escapes */ -/* Test for generation of escape _Block_byref_release call when a local +/* Test for generation of escape _Block_object_dispose call when a local __block variable is copied in. */ /* { dg-options "-fblocks" } */ /* { dg-do run } */ @@ -7,12 +7,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-2.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-2.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-2.c Tue Nov 25 17:00:54 2008 @@ -1,5 +1,5 @@ /* APPLE LOCAL file radar 6083129 byref escapes */ -/* Test for generation of escape _Block_byref_release call when a local +/* Test for generation of escape _Block_object_dispose call when a local __block variable is copied in and block has a return statement. */ /* { dg-options "-fblocks" } */ /* { dg-do run } */ @@ -7,12 +7,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-3.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-3.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-3.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper-3.c Tue Nov 25 17:00:54 2008 @@ -1,5 +1,5 @@ /* APPLE LOCAL file radar 6083129 byref escapes */ -/* Test for generation of escape _Block_byref_release call when a __block +/* Test for generation of escape _Block_object_dispose call when a __block variable inside a block is declared and used. */ /* { dg-options "-fblocks" } */ /* { dg-do run } */ @@ -7,12 +7,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-noescape-helper.c Tue Nov 25 17:00:54 2008 @@ -5,12 +5,12 @@ #include void *_NSConcreteStackBlock; -void _Block_byref_assign_copy(void * dst, void *src){} +void _Block_object_assign(void * dst, void *src, int flag){} extern void abort(void); static int count; -static void _Block_byref_release(void * arg) { +static void _Block_object_dispose(void * arg, int flag) { ++count; } Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/i386-bitmask1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/i386-bitmask1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/i386-bitmask1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/i386-bitmask1.c Tue Nov 25 17:00:54 2008 @@ -5,15 +5,12 @@ /* LLVM LOCAL */ /* { dg-final { scan-assembler "and.*(0xffffff00|4294967040)" } } */ unsigned char lut[256]; -/* LLVM LOCAL make these global */ -unsigned int *srcptr, *dstptr; void foo( int count ) { int j; - /* LLVM LOCAL begin remove uninitialized srcptr, dstptr */ - /* LLVM LOCAL end */ + unsigned int *srcptr, *dstptr; for (j = 0; j < count; j++) { unsigned int tmp = *srcptr; unsigned int alpha = (tmp&255); Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/uninit-test-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/uninit-test-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/uninit-test-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/uninit-test-1.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,6 @@ /* Radar 4964532 */ /* { dg-do compile } */ -/* { dg-options "-O2 -gdwarf-2 -dA -mmacosx-version-min=10.4" { target powerpc*-*-darwin* i?86*-*-darwin* } } */ +/* { dg-options "-O2 -gdwarf-2 -dA -mmacosx-version-min=10.4 -m32" { target powerpc*-*-darwin* i?86*-*-darwin* } } */ /* { dg-options "-O2 -gdwarf-2 -dA" { target arm*-*-darwin* } } */ /* { dg-final { scan-assembler "DW_OP_APPLE_uninit" } } */ #include Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2.c Tue Nov 25 17:00:54 2008 @@ -4,8 +4,8 @@ /* Test of prohibition on directives which result from macro expansion. See also direct2s.c */ -/* { dg-do compile } */ - +/* { dg-do compile } */ /* APPLE LOCAL CW asm blocks 6338079 */ +/* { dg-options "-ansi -pedantic-errors -fno-asm-blocks" } */ #define HASH # #define HASHDEFINE #define #define HASHINCLUDE #include Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2s.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2s.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2s.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/cpp/direct2s.c Tue Nov 25 17:00:54 2008 @@ -5,8 +5,8 @@ expansion. Same as direct2.c, with -save-temps applied; results should be identical. */ -/* { dg-do compile } */ -/* { dg-options "-save-temps -ansi -pedantic-errors" } */ +/* { dg-do compile } */ /* APPLE LOCAL CW asm blocks 6338079 */ +/* { dg-options "-save-temps -ansi -pedantic-errors -fno-asm-blocks" } */ #define HASH # #define HASHDEFINE #define Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-1.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file mainline 2007-02-20 5005743 */ /* Basic test for -mmacosx-version-min switch on Darwin. */ -/* { dg-options "-mmacosx-version-min=10.1" } */ +/* APPLE LOCAL 64-bit default */ +/* { dg-options "-mmacosx-version-min=10.1 -m32" } */ /* { dg-do run { target powerpc*-*-darwin* i?86*-*-darwin* } } */ int main(void) Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-2.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-2.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-minversion-2.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* APPLE LOCAL file mainline 2007-02-20 5005743 */ /* Basic test for -mmacosx-version-min switch on Darwin. */ -/* { dg-options "-mmacosx-version-min=10.1 -mmacosx-version-min=10.3" } */ +/* APPLE LOCAL 64-bit default */ +/* { dg-options "-mmacosx-version-min=10.1 -mmacosx-version-min=10.3 -m32" } */ /* { dg-do run { target powerpc*-*-darwin* i?86*-*-darwin* } } */ int main(void) Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-version-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-version-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-version-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-version-1.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,7 @@ /* Basic test of the -mmacosx-version-min option. */ -/* { dg-options "-mmacosx-version-min=10.1" } */ +/* APPLE LOCAL 64-bit default */ +/* { dg-options "-mmacosx-version-min=10.1 -m32" } */ /* APPLE LOCAL ARM */ /* { dg-do link { target powerpc*-*-darwin* i?86*-*-darwin* } } */ Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-1.c Tue Nov 25 17:00:54 2008 @@ -1,6 +1,8 @@ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-require-weak "" } */ /* { dg-options "-fno-common -fno-asynchronous-unwind-tables" } */ +/* APPLE LOCAL 64-bit default objective-c 6348517 */ +/* { dg-options "-fno-common -fno-asynchronous-unwind-tables -m32" { target { i?86-*-darwin* x86_64-*-darwin* } } } */ /* { dg-final { scan-assembler "weak_reference _a" } } */ /* { dg-final { scan-assembler-not "weak_\[a-z \t\]*_b" } } */ Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-3.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-3.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-3.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/darwin-weakimport-3.c Tue Nov 25 17:00:54 2008 @@ -1,5 +1,7 @@ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-options "-fno-asynchronous-unwind-tables" } */ +/* APPLE LOCAL 64-bit default objective-c 6348517 */ +/* { dg-options "-fno-common -fno-asynchronous-unwind-tables -m32" { target { i?86-*-darwin* x86_64-*-darwin* } } } */ /* { dg-require-weak "" } */ /* { dg-final { scan-assembler-not "coalesced" } } */ Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/dollar.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/dollar.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/dollar.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/dollar.c Tue Nov 25 17:00:54 2008 @@ -2,6 +2,8 @@ /* { dg-do compile } */ /* { dg-options -fno-dollars-in-identifiers } */ +/* APPLE LOCAL CW asm blocks 6338079 */ +/* { dg-options "-fno-dollars-in-identifiers -fno-asm-blocks" } */ /* Test that -fno-dollars-in-identifiers is honoured. Neil Booth, 17 May 2003. */ Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.c Tue Nov 25 17:00:54 2008 @@ -1,5 +1,7 @@ /* { dg-options "-I. -Winvalid-pch -fexceptions" } */ +/* APPLE LOCAL 64-bit default for objc 6348519 */ +/* { dg-options "-I. -Winvalid-pch -fexceptions -m32" { target { i?86-*-darwin* x86_64-*-darwin* } } } */ #include "valid-2.h"/* { dg-error "settings for -fexceptions do not match|No such file|they were invalid" } */ int x; Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.hs URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.hs?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.hs (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/pch/valid-2.hs Tue Nov 25 17:00:54 2008 @@ -1 +1,3 @@ +/* APPLE LOCAL 64-bit default for objc 6348519 */ +/* { dg-options "-m32" { target { i?86-*-darwin* x86_64-*-darwin* } } } */ extern int x; Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-1.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-1.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-1.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-1.c Tue Nov 25 17:00:54 2008 @@ -5,7 +5,7 @@ Contributed by Hans-Peter Nilsson */ /* { dg-do run } */ -/* APPLE LOCAL 5886557 explicitly disable inlining. */ +/* LLVM LOCAL 5886557 explicitly disable inlining. */ /* { dg-options "-O2 -foptimize-sibling-calls -fno-inline-functions" } */ /* The option -foptimize-sibling-calls is the default, but serves as Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-2.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-2.c?rev=60062&r1=60061&r2=60062&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-2.c (original) +++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.dg/sibcall-2.c Tue Nov 25 17:00:54 2008 @@ -5,7 +5,7 @@ Contributed by Hans-Peter Nilsson */ /* { dg-do run } */ -/* APPLE LOCAL 5886557 explicitly disable inlining. */ +/* LLVM LOCAL 5886557 explicitly disable inlining. */ /* { dg-options "-O2 -foptimize-sibling-calls -fno-inline-functions" } */ /* The option -foptimize-sibling-calls is the default, but serves as From nunoplopes at sapo.pt Tue Nov 25 18:00:45 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Wed, 26 Nov 2008 00:00:45 -0000 Subject: [llvm-commits] [llvm] r60064 - in /llvm/trunk: include/llvm/Support/Annotation.h lib/Support/Annotation.cpp Message-ID: <200811260000.mAQ00jlW030279@zion.cs.uiuc.edu> Author: nlopes Date: Tue Nov 25 18:00:44 2008 New Revision: 60064 URL: http://llvm.org/viewvc/llvm-project?rev=60064&view=rev Log: change AnnotationManager to use 'const char*' instead of std::string. this fixes the leakage of those strings and avoids the creation of such strings in static cosntructors (should result in a little improvement of startup time) Modified: llvm/trunk/include/llvm/Support/Annotation.h llvm/trunk/lib/Support/Annotation.cpp Modified: llvm/trunk/include/llvm/Support/Annotation.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Annotation.h?rev=60064&r1=60063&r2=60064&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Annotation.h (original) +++ llvm/trunk/include/llvm/Support/Annotation.h Tue Nov 25 18:00:44 2008 @@ -172,13 +172,12 @@ //===--------------------------------------------------------------------===// // Basic ID <-> Name map functionality - static AnnotationID getID(const std::string &Name); // Name -> ID - static const std::string &getName(AnnotationID ID); // ID -> Name + static AnnotationID getID(const char *Name); // Name -> ID + static const char *getName(AnnotationID ID); // ID -> Name // getID - Name -> ID + registration of a factory function for demand driven // annotation support. - static AnnotationID getID(const std::string &Name, Factory Fact, - void *Data = 0); + static AnnotationID getID(const char *Name, Factory Fact, void *Data = 0); //===--------------------------------------------------------------------===// // Annotation creation on demand support... Modified: llvm/trunk/lib/Support/Annotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Annotation.cpp?rev=60064&r1=60063&r2=60064&view=diff ============================================================================== --- llvm/trunk/lib/Support/Annotation.cpp (original) +++ llvm/trunk/lib/Support/Annotation.cpp Tue Nov 25 18:00:44 2008 @@ -27,7 +27,7 @@ } } -typedef std::map IDMapType; +typedef std::map IDMapType; static unsigned IDCounter = 0; // Unique ID counter // Static member to ensure initialiation on demand. @@ -53,7 +53,7 @@ } } -AnnotationID AnnotationManager::getID(const std::string &Name) { // Name -> ID +AnnotationID AnnotationManager::getID(const char *Name) { // Name -> ID IDMapType::iterator I = IDMap->find(Name); if (I == IDMap->end()) { (*IDMap)[Name] = IDCounter++; // Add a new element @@ -64,7 +64,7 @@ // getID - Name -> ID + registration of a factory function for demand driven // annotation support. -AnnotationID AnnotationManager::getID(const std::string &Name, Factory Fact, +AnnotationID AnnotationManager::getID(const char *Name, Factory Fact, void *Data) { AnnotationID Result(getID(Name)); registerAnnotationFactory(Result, Fact, Data); @@ -74,7 +74,7 @@ // getName - This function is especially slow, but that's okay because it should // only be used for debugging. // -const std::string &AnnotationManager::getName(AnnotationID ID) { // ID -> Name +const char *AnnotationManager::getName(AnnotationID ID) { // ID -> Name IDMapType &TheMap = *IDMap; for (IDMapType::iterator I = TheMap.begin(); ; ++I) { assert(I != TheMap.end() && "Annotation ID is unknown!"); From nunoplopes at sapo.pt Tue Nov 25 18:02:09 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Wed, 26 Nov 2008 00:02:09 -0000 Subject: [llvm-commits] [llvm] r60065 - /llvm/trunk/test/Transforms/CodeGenPrepare/ Message-ID: <200811260002.mAQ029b0030335@zion.cs.uiuc.edu> Author: nlopes Date: Tue Nov 25 18:02:09 2008 New Revision: 60065 URL: http://llvm.org/viewvc/llvm-project?rev=60065&view=rev Log: ignore tests output Modified: llvm/trunk/test/Transforms/CodeGenPrepare/ (props changed) Propchange: llvm/trunk/test/Transforms/CodeGenPrepare/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Tue Nov 25 18:02:09 2008 @@ -0,0 +1,3 @@ +Output +*.log +*.sum From sabre at nondot.org Tue Nov 25 18:03:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 00:03:26 -0000 Subject: [llvm-commits] [llvm] r60066 - /llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Message-ID: <200811260003.mAQ03Q1b030380@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 18:03:26 2008 New Revision: 60066 URL: http://llvm.org/viewvc/llvm-project?rev=60066&view=rev Log: this doesn't need EH Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll?rev=60066&r1=60065&r2=60066&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Tue Nov 25 18:03:26 2008 @@ -5,7 +5,7 @@ @A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2] -define void @test(i32 %row, i32 %N.in) { +define void @test(i32 %row, i32 %N.in) nounwind { entry: %N = bitcast i32 %N.in to i32 ; [#uses=1] %tmp5 = icmp sgt i32 %N.in, 0 ; [#uses=1] From sabre at nondot.org Tue Nov 25 18:12:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 00:12:08 -0000 Subject: [llvm-commits] [llvm] r60067 - /llvm/trunk/test/CodeGen/X86/remat-mov0.ll Message-ID: <200811260012.mAQ0C84o030625@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 18:12:08 2008 New Revision: 60067 URL: http://llvm.org/viewvc/llvm-project?rev=60067&view=rev Log: fix an over-reduced test. Modified: llvm/trunk/test/CodeGen/X86/remat-mov0.ll Modified: llvm/trunk/test/CodeGen/X86/remat-mov0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/remat-mov0.ll?rev=60067&r1=60066&r2=60067&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/remat-mov0.ll (original) +++ llvm/trunk/test/CodeGen/X86/remat-mov0.ll Tue Nov 25 18:12:08 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 3 +; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 2 %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } %struct.ImgT = type { i8, i8*, i8*, %struct.FILE*, i32, i32, i32, i32, i8*, double*, float*, float*, float*, i32*, double, double, i32*, double*, i32*, i32* } @@ -17,12 +17,7 @@ br i1 false, label %bb197, label %bb149 bb149: ; preds = %bb105 - %tmp151 = getelementptr %struct._CompT* null, i32 0, i32 0 ; [#uses=1] - br i1 false, label %bb184, label %bb193 - -bb184: ; preds = %bb149 - tail call fastcc void @MergeComponents( %struct._CompT* %comp, %struct._CompT* null, %struct._CompT* null, %struct._CompT** %head, %struct.ImgT* %img ) nounwind - tail call fastcc void @MergeToLeft( %struct._CompT* %comp, %struct._CompT** %head, %struct.ImgT* %img ) nounwind + %tmp151 = getelementptr %struct._CompT* %comp, i32 0, i32 0 ; [#uses=1] br label %bb193 bb193: ; preds = %bb184, %bb149 From sabre at nondot.org Tue Nov 25 18:26:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 00:26:17 -0000 Subject: [llvm-commits] [llvm] r60068 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/X86/2008-10-16-SpillerBug.ll test/CodeGen/X86/isel-sink2.ll Message-ID: <200811260026.mAQ0QHKY031081@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 18:26:16 2008 New Revision: 60068 URL: http://llvm.org/viewvc/llvm-project?rev=60068&view=rev Log: Teach CodeGenPrepare to look through Bitcast instructions when attempting to optimize addressing modes. This allows us to optimize things like isel-sink2.ll into: movl 4(%esp), %eax cmpb $0, 4(%eax) jne LBB1_2 ## F LBB1_1: ## TB movl $4, %eax ret LBB1_2: ## F movzbl 7(%eax), %eax ret instead of: _test: movl 4(%esp), %eax cmpb $0, 4(%eax) leal 4(%eax), %eax jne LBB1_2 ## F LBB1_1: ## TB movl $4, %eax ret LBB1_2: ## F movzbl 3(%eax), %eax ret This shrinks (e.g.) 403.gcc from 1133510 to 1128345 lines of .s. Note that the 2008-10-16-SpillerBug.ll testcase is dubious at best, I doubt it is really testing what it thinks it is. Added: llvm/trunk/test/CodeGen/X86/isel-sink2.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp llvm/trunk/test/CodeGen/X86/2008-10-16-SpillerBug.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60068&r1=60067&r2=60068&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 18:26:16 2008 @@ -636,6 +636,17 @@ TLI.getPointerTy()) return MatchAddr(AddrInst->getOperand(0), Depth); return false; + case Instruction::BitCast: + // BitCast is always a noop, and we can handle it as long as it is + // int->int or pointer->pointer (we don't want int<->fp or something). + if ((isa(AddrInst->getOperand(0)->getType()) || + isa(AddrInst->getOperand(0)->getType())) && + // Don't touch identity bitcasts. These were probably put here by LSR, + // and we don't want to mess around with them. Assume it knows what it + // is doing. + AddrInst->getOperand(0)->getType() != AddrInst->getType()) + return MatchAddr(AddrInst->getOperand(0), Depth); + return false; case Instruction::Add: { // Check to see if we can merge in the RHS then the LHS. If so, we win. ExtAddrMode BackupAddrMode = AddrMode; Modified: llvm/trunk/test/CodeGen/X86/2008-10-16-SpillerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-10-16-SpillerBug.ll?rev=60068&r1=60067&r2=60068&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-10-16-SpillerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-10-16-SpillerBug.ll Tue Nov 25 18:26:16 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -relocation-model=pic -disable-fp-elim -mtriple=i386-apple-darwin | grep and | grep 7 | grep ebp +; RUN: llvm-as < %s | llc -relocation-model=pic -disable-fp-elim -mtriple=i386-apple-darwin | grep {andl.*7.*ecx} %struct.XXDActiveTextureTargets = type { i64, i64, i64, i64, i64, i64 } %struct.XXDAlphaTest = type { float, i16, i8, i8 } Added: llvm/trunk/test/CodeGen/X86/isel-sink2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/isel-sink2.ll?rev=60068&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/isel-sink2.ll (added) +++ llvm/trunk/test/CodeGen/X86/isel-sink2.ll Tue Nov 25 18:26:16 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {movzbl.7(%...)} +; RUN: llvm-as < %s | llc -march=x86 | not grep leal + +define i8 @test(i32 *%P) nounwind { + %Q = getelementptr i32* %P, i32 1 + %R = bitcast i32* %Q to i8* + %S = load i8* %R + %T = icmp eq i8 %S, 0 + br i1 %T, label %TB, label %F +TB: + ret i8 4 +F: + %U = getelementptr i8* %R, i32 3 + %V = load i8* %U + ret i8 %V +} From evan.cheng at apple.com Tue Nov 25 18:55:09 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Nov 2008 16:55:09 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> Message-ID: <9F29411B-595D-445D-904D-0A4062568365@apple.com> On Nov 25, 2008, at 11:14 AM, Chris Lattner wrote: > > On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: > >> Author: evancheng >> Date: Tue Nov 25 13:00:29 2008 >> New Revision: 60042 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev >> Log: >> convertToSignExtendedInteger should return opInvalidOp instead of >> asserting if sematics of float does not allow arithmetics. > > Are you sure? This behavior was consistent with all the other > methods. Usually the client has to check to see if it is hacking on > ppc long double and not do the optimization in question. The client is calling convertToInteger(). How would it know it's not possible to convert ppc long double? Seems like only APFloat has this information. Evan > > > -Chris > >> >> >> Added: >> llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >> APFloatAssert.ll >> Modified: >> llvm/trunk/lib/Support/APFloat.cpp >> >> Modified: llvm/trunk/lib/Support/APFloat.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Support/APFloat.cpp (original) >> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 >> @@ -117,6 +117,11 @@ >> && "Compile-time arithmetic does not support these >> semantics"); >> } >> >> + static inline bool >> + isArithmeticOk(const llvm::fltSemantics &semantics) { >> + return semantics.arithmeticOK; >> + } >> + >> /* Return the value of a decimal exponent of the form >> [+-]ddddddd. >> >> @@ -1787,7 +1792,8 @@ >> const integerPart *src; >> unsigned int dstPartsCount, truncatedBits; >> >> - assertArithmeticOK(*semantics); >> + if (!isArithmeticOk(*semantics)) >> + return opInvalidOp; >> >> *isExact = false; >> >> >> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >> APFloatAssert.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >> APFloatAssert.ll (added) >> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >> APFloatAssert.ll Tue Nov 25 13:00:29 2008 >> @@ -0,0 +1,11 @@ >> +; RUN: llvm-as < %s | opt -indvars >> + >> +define void @t() nounwind { >> +entry: >> + br label %bb23.i91 >> + >> +bb23.i91: ; preds = %bb23.i91, %entry >> + %result.0.i89 = phi ppc_fp128 >> [ 0xM00000000000000000000000000000000, %entry ], [ %0, >> %bb23.i91 ] ; [#uses=2] >> + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; >> [#uses=1] >> + br label %bb23.i91 >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Nov 25 19:03:13 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Nov 2008 17:03:13 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <9F29411B-595D-445D-904D-0A4062568365@apple.com> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> <9F29411B-595D-445D-904D-0A4062568365@apple.com> Message-ID: <81E52E52-52D1-42B7-A7EA-9EF7C2050B5C@apple.com> On Nov 25, 2008, at 4:55 PM, Evan Cheng wrote: > > On Nov 25, 2008, at 11:14 AM, Chris Lattner wrote: > >> >> On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Tue Nov 25 13:00:29 2008 >>> New Revision: 60042 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev >>> Log: >>> convertToSignExtendedInteger should return opInvalidOp instead of >>> asserting if sematics of float does not allow arithmetics. >> >> Are you sure? This behavior was consistent with all the other >> methods. Usually the client has to check to see if it is hacking on >> ppc long double and not do the optimization in question. > > The client is calling convertToInteger(). How would it know it's not > possible to convert ppc long double? Seems like only APFloat has this > information. Ok, I see checks for PPCDoubleDouble elsewhere. I'll fix. Evan > > > Evan > >> >> >> -Chris >> >>> >>> >>> Added: >>> llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll >>> Modified: >>> llvm/trunk/lib/Support/APFloat.cpp >>> >>> Modified: llvm/trunk/lib/Support/APFloat.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Support/APFloat.cpp (original) >>> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 >>> @@ -117,6 +117,11 @@ >>> && "Compile-time arithmetic does not support these >>> semantics"); >>> } >>> >>> + static inline bool >>> + isArithmeticOk(const llvm::fltSemantics &semantics) { >>> + return semantics.arithmeticOK; >>> + } >>> + >>> /* Return the value of a decimal exponent of the form >>> [+-]ddddddd. >>> >>> @@ -1787,7 +1792,8 @@ >>> const integerPart *src; >>> unsigned int dstPartsCount, truncatedBits; >>> >>> - assertArithmeticOK(*semantics); >>> + if (!isArithmeticOk(*semantics)) >>> + return opInvalidOp; >>> >>> *isExact = false; >>> >>> >>> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll (added) >>> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll Tue Nov 25 13:00:29 2008 >>> @@ -0,0 +1,11 @@ >>> +; RUN: llvm-as < %s | opt -indvars >>> + >>> +define void @t() nounwind { >>> +entry: >>> + br label %bb23.i91 >>> + >>> +bb23.i91: ; preds = %bb23.i91, %entry >>> + %result.0.i89 = phi ppc_fp128 >>> [ 0xM00000000000000000000000000000000, %entry ], [ %0, >>> %bb23.i91 ] ; [#uses=2] >>> + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; >>> [#uses=1] >>> + br label %bb23.i91 >>> +} >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Tue Nov 25 19:08:16 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Nov 2008 17:08:16 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <9F29411B-595D-445D-904D-0A4062568365@apple.com> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> <9F29411B-595D-445D-904D-0A4062568365@apple.com> Message-ID: <93EDE7DA-398D-47A4-A1B4-588CAC646842@apple.com> On Nov 25, 2008, at 4:55 PMPST, Evan Cheng wrote: > On Nov 25, 2008, at 11:14 AM, Chris Lattner wrote: >> On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Tue Nov 25 13:00:29 2008 >>> New Revision: 60042 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev >>> Log: >>> convertToSignExtendedInteger should return opInvalidOp instead of >>> asserting if sematics of float does not allow arithmetics. >> >> Are you sure? This behavior was consistent with all the other >> methods. Usually the client has to check to see if it is hacking on >> ppc long double and not do the optimization in question. > > The client is calling convertToInteger(). How would it know it's not > possible to convert ppc long double? Seems like only APFloat has this > information. Chris is right, it's currently caller's responsibility to check this. Search for PPCDoubleDouble, you'll see examples. isArithmeticOK is a good idea though, that's better than what it does now. But many places you've only got an MVT to look at. > Evan > >> >> >> -Chris >> >>> >>> >>> Added: >>> llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll >>> Modified: >>> llvm/trunk/lib/Support/APFloat.cpp >>> >>> Modified: llvm/trunk/lib/Support/APFloat.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Support/APFloat.cpp (original) >>> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 >>> @@ -117,6 +117,11 @@ >>> && "Compile-time arithmetic does not support these >>> semantics"); >>> } >>> >>> + static inline bool >>> + isArithmeticOk(const llvm::fltSemantics &semantics) { >>> + return semantics.arithmeticOK; >>> + } >>> + >>> /* Return the value of a decimal exponent of the form >>> [+-]ddddddd. >>> >>> @@ -1787,7 +1792,8 @@ >>> const integerPart *src; >>> unsigned int dstPartsCount, truncatedBits; >>> >>> - assertArithmeticOK(*semantics); >>> + if (!isArithmeticOk(*semantics)) >>> + return opInvalidOp; >>> >>> *isExact = false; >>> >>> >>> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll (added) >>> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>> APFloatAssert.ll Tue Nov 25 13:00:29 2008 >>> @@ -0,0 +1,11 @@ >>> +; RUN: llvm-as < %s | opt -indvars >>> + >>> +define void @t() nounwind { >>> +entry: >>> + br label %bb23.i91 >>> + >>> +bb23.i91: ; preds = %bb23.i91, %entry >>> + %result.0.i89 = phi ppc_fp128 >>> [ 0xM00000000000000000000000000000000, %entry ], [ %0, >>> %bb23.i91 ] ; [#uses=2] >>> + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; >>> [#uses=1] >>> + br label %bb23.i91 >>> +} >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Nov 25 19:11:57 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Nov 2008 01:11:57 -0000 Subject: [llvm-commits] [llvm] r60072 - in /llvm/trunk/lib: Support/APFloat.cpp Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200811260111.mAQ1BvwX032581@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 25 19:11:57 2008 New Revision: 60072 URL: http://llvm.org/viewvc/llvm-project?rev=60072&view=rev Log: Revert r60042. IndVarSimplify should check if APFloat is PPCDoubleDouble first before trying to convert it to an integer. Modified: llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60072&r1=60071&r2=60072&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 19:11:57 2008 @@ -117,11 +117,6 @@ && "Compile-time arithmetic does not support these semantics"); } - static inline bool - isArithmeticOk(const llvm::fltSemantics &semantics) { - return semantics.arithmeticOK; - } - /* Return the value of a decimal exponent of the form [+-]ddddddd. @@ -1792,8 +1787,7 @@ const integerPart *src; unsigned int dstPartsCount, truncatedBits; - if (!isArithmeticOk(*semantics)) - return opInvalidOp; + assertArithmeticOK(*semantics); *isExact = false; Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=60072&r1=60071&r2=60072&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Nov 25 19:11:57 2008 @@ -742,6 +742,8 @@ static bool convertToInt(const APFloat &APF, uint64_t *intVal) { bool isExact = false; + if (&APF.getSemantics() == &APFloat::PPCDoubleDouble) + return false; if (APF.convertToInteger(intVal, 32, APF.isNegative(), APFloat::rmTowardZero, &isExact) != APFloat::opOK) From evan.cheng at apple.com Tue Nov 25 19:14:17 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 Nov 2008 17:14:17 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <93EDE7DA-398D-47A4-A1B4-588CAC646842@apple.com> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> <9F29411B-595D-445D-904D-0A4062568365@apple.com> <93EDE7DA-398D-47A4-A1B4-588CAC646842@apple.com> Message-ID: On Nov 25, 2008, at 5:08 PM, Dale Johannesen wrote: > On Nov 25, 2008, at 4:55 PMPST, Evan Cheng wrote: >> On Nov 25, 2008, at 11:14 AM, Chris Lattner wrote: >>> On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: >>> >>>> Author: evancheng >>>> Date: Tue Nov 25 13:00:29 2008 >>>> New Revision: 60042 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev >>>> Log: >>>> convertToSignExtendedInteger should return opInvalidOp instead of >>>> asserting if sematics of float does not allow arithmetics. >>> >>> Are you sure? This behavior was consistent with all the other >>> methods. Usually the client has to check to see if it is hacking on >>> ppc long double and not do the optimization in question. >> >> The client is calling convertToInteger(). How would it know it's not >> possible to convert ppc long double? Seems like only APFloat has this >> information. > > Chris is right, it's currently caller's responsibility to check this. > Search for PPCDoubleDouble, you'll see examples. > isArithmeticOK is a good idea though, that's better than what it does > now. But many places you've only got an MVT to look at. I've reverted this and added code to check for PPCDoubleDouble. It's important to keep all methods consistent. However, since these methods return a APFloat::opStatus, I think we should rely on that instead of the explicit semantics check. Evan > > >> Evan >> >>> >>> >>> -Chris >>> >>>> >>>> >>>> Added: >>>> llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>> APFloatAssert.ll >>>> Modified: >>>> llvm/trunk/lib/Support/APFloat.cpp >>>> >>>> Modified: llvm/trunk/lib/Support/APFloat.cpp >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> =================================================================== >>>> --- llvm/trunk/lib/Support/APFloat.cpp (original) >>>> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 >>>> @@ -117,6 +117,11 @@ >>>> && "Compile-time arithmetic does not support these >>>> semantics"); >>>> } >>>> >>>> + static inline bool >>>> + isArithmeticOk(const llvm::fltSemantics &semantics) { >>>> + return semantics.arithmeticOK; >>>> + } >>>> + >>>> /* Return the value of a decimal exponent of the form >>>> [+-]ddddddd. >>>> >>>> @@ -1787,7 +1792,8 @@ >>>> const integerPart *src; >>>> unsigned int dstPartsCount, truncatedBits; >>>> >>>> - assertArithmeticOK(*semantics); >>>> + if (!isArithmeticOk(*semantics)) >>>> + return opInvalidOp; >>>> >>>> *isExact = false; >>>> >>>> >>>> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>> APFloatAssert.ll >>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto >>>> >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> = >>>> =================================================================== >>>> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>> APFloatAssert.ll (added) >>>> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>> APFloatAssert.ll Tue Nov 25 13:00:29 2008 >>>> @@ -0,0 +1,11 @@ >>>> +; RUN: llvm-as < %s | opt -indvars >>>> + >>>> +define void @t() nounwind { >>>> +entry: >>>> + br label %bb23.i91 >>>> + >>>> +bb23.i91: ; preds = %bb23.i91, %entry >>>> + %result.0.i89 = phi ppc_fp128 >>>> [ 0xM00000000000000000000000000000000, %entry ], [ %0, >>>> %bb23.i91 ] ; [#uses=2] >>>> + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; >>>> [#uses=1] >>>> + br label %bb23.i91 >>>> +} >>>> >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Tue Nov 25 19:18:07 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 Nov 2008 17:18:07 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> <9F29411B-595D-445D-904D-0A4062568365@apple.com> <93EDE7DA-398D-47A4-A1B4-588CAC646842@apple.com> Message-ID: <0C8DAB63-4282-41E0-B6C9-3D8478701BA5@apple.com> On Nov 25, 2008, at 5:14 PM, Evan Cheng wrote: >>> >>> The client is calling convertToInteger(). How would it know it's not >>> possible to convert ppc long double? Seems like only APFloat has >>> this >>> information. >> >> Chris is right, it's currently caller's responsibility to check this. >> Search for PPCDoubleDouble, you'll see examples. >> isArithmeticOK is a good idea though, that's better than what it does >> now. But many places you've only got an MVT to look at. > > I've reverted this and added code to check for PPCDoubleDouble. It's > important to keep all methods consistent. However, since these methods > return a APFloat::opStatus, I think we should rely on that instead of > the explicit semantics check. Sure, how about adding a new opUnsupportedOp flag? opInvalidOp means something to IEEE, opUnsupportedOp could mean "we don't know how to fold this" which is different. -Chris From evan.cheng at apple.com Tue Nov 25 19:18:51 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Nov 2008 01:18:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60073 - /llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Message-ID: <200811260118.mAQ1IpVS000317@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 25 19:18:51 2008 New Revision: 60073 URL: http://llvm.org/viewvc/llvm-project?rev=60073&view=rev Log: Do not declare is_jump_table with ENABLE_LLVM. This gets added everytime we do a gcc4.2 merge. Hopefully this commit fix it once for all. Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.c?rev=60073&r1=60072&r2=60073&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/arm/arm.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Tue Nov 25 19:18:51 2008 @@ -84,7 +84,9 @@ static const char *fp_const_from_val (REAL_VALUE_TYPE *); static arm_cc get_arm_condition_code (rtx); static HOST_WIDE_INT int_log2 (HOST_WIDE_INT); +#ifndef ENABLE_LLVM static rtx is_jump_table (rtx); +#endif static const char *output_multi_immediate (rtx *, const char *, const char *, int, HOST_WIDE_INT); static const char *shift_op (rtx, HOST_WIDE_INT *); @@ -97,7 +99,6 @@ /* APPLE LOCAL end compact switch tables */ /* LLVM LOCAL */ #ifndef ENABLE_LLVM -static rtx is_jump_table (rtx); static HOST_WIDE_INT get_jump_table_size (rtx); static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT); static Mnode *add_minipool_forward_ref (Mfix *); From dalej at apple.com Tue Nov 25 19:22:05 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Nov 2008 17:22:05 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <42254F84-7D36-41F9-8872-22271F1AD00B@apple.com> <9F29411B-595D-445D-904D-0A4062568365@apple.com> <93EDE7DA-398D-47A4-A1B4-588CAC646842@apple.com> Message-ID: <5DDF7889-905F-4500-A00B-58AFBAF317B6@apple.com> On Nov 25, 2008, at 5:14 PMPST, Evan Cheng wrote: > > On Nov 25, 2008, at 5:08 PM, Dale Johannesen wrote: > >> On Nov 25, 2008, at 4:55 PMPST, Evan Cheng wrote: >>> On Nov 25, 2008, at 11:14 AM, Chris Lattner wrote: >>>> On Nov 25, 2008, at 11:00 AM, Evan Cheng wrote: >>>> >>>>> Author: evancheng >>>>> Date: Tue Nov 25 13:00:29 2008 >>>>> New Revision: 60042 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=60042&view=rev >>>>> Log: >>>>> convertToSignExtendedInteger should return opInvalidOp instead of >>>>> asserting if sematics of float does not allow arithmetics. >>>> >>>> Are you sure? This behavior was consistent with all the other >>>> methods. Usually the client has to check to see if it is hacking >>>> on >>>> ppc long double and not do the optimization in question. >>> >>> The client is calling convertToInteger(). How would it know it's not >>> possible to convert ppc long double? Seems like only APFloat has >>> this >>> information. >> >> Chris is right, it's currently caller's responsibility to check this. >> Search for PPCDoubleDouble, you'll see examples. >> isArithmeticOK is a good idea though, that's better than what it does >> now. But many places you've only got an MVT to look at. > > I've reverted this and added code to check for PPCDoubleDouble. It's > important to keep all methods consistent. However, since these methods > return a APFloat::opStatus, I think we should rely on that instead of > the explicit semantics check. opStatus is intended to mimic IEEE754 exception codes. We could add an auxiliary return value like losesInfo in convert. However, even I recognize that what you suggest is much more appealing aesthetically, and ISTR I tried to do this and it was not as easy as you would expect, although I've forgotten why. > Evan > >> >> >>> Evan >>> >>>> >>>> >>>> -Chris >>>> >>>>> >>>>> >>>>> Added: >>>>> llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>>> APFloatAssert.ll >>>>> Modified: >>>>> llvm/trunk/lib/Support/APFloat.cpp >>>>> >>>>> Modified: llvm/trunk/lib/Support/APFloat.cpp >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60042&r1=60041&r2=60042&view=diff >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/lib/Support/APFloat.cpp (original) >>>>> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Nov 25 13:00:29 2008 >>>>> @@ -117,6 +117,11 @@ >>>>> && "Compile-time arithmetic does not support these >>>>> semantics"); >>>>> } >>>>> >>>>> + static inline bool >>>>> + isArithmeticOk(const llvm::fltSemantics &semantics) { >>>>> + return semantics.arithmeticOK; >>>>> + } >>>>> + >>>>> /* Return the value of a decimal exponent of the form >>>>> [+-]ddddddd. >>>>> >>>>> @@ -1787,7 +1792,8 @@ >>>>> const integerPart *src; >>>>> unsigned int dstPartsCount, truncatedBits; >>>>> >>>>> - assertArithmeticOK(*semantics); >>>>> + if (!isArithmeticOk(*semantics)) >>>>> + return opInvalidOp; >>>>> >>>>> *isExact = false; >>>>> >>>>> >>>>> Added: llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>>> APFloatAssert.ll >>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll?rev=60042&view=auto >>>>> >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> = >>>>> ================================================================== >>>>> --- llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>>> APFloatAssert.ll (added) >>>>> +++ llvm/trunk/test/Transforms/IndVarsSimplify/2008-11-25- >>>>> APFloatAssert.ll Tue Nov 25 13:00:29 2008 >>>>> @@ -0,0 +1,11 @@ >>>>> +; RUN: llvm-as < %s | opt -indvars >>>>> + >>>>> +define void @t() nounwind { >>>>> +entry: >>>>> + br label %bb23.i91 >>>>> + >>>>> +bb23.i91: ; preds = %bb23.i91, %entry >>>>> + %result.0.i89 = phi ppc_fp128 >>>>> [ 0xM00000000000000000000000000000000, %entry ], [ %0, >>>>> %bb23.i91 ] ; [#uses=2] >>>>> + %0 = mul ppc_fp128 %result.0.i89, %result.0.i89 ; >>>>> [#uses=1] >>>>> + br label %bb23.i91 >>>>> +} >>>>> >>>>> >>>>> _______________________________________________ >>>>> llvm-commits mailing list >>>>> llvm-commits at cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Tue Nov 25 19:25:17 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 Nov 2008 17:25:17 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r60073 - /llvm-gcc-4.2/trunk/gcc/config/arm/arm.c In-Reply-To: <200811260118.mAQ1IpVS000317@zion.cs.uiuc.edu> References: <200811260118.mAQ1IpVS000317@zion.cs.uiuc.edu> Message-ID: <0016172D-F235-48D3-A4C3-E59C99CA9094@apple.com> On Nov 25, 2008, at 5:18 PMPST, Evan Cheng wrote: > Author: evancheng > Date: Tue Nov 25 19:18:51 2008 > New Revision: 60073 > > URL: http://llvm.org/viewvc/llvm-project?rev=60073&view=rev > Log: > Do not declare is_jump_table with ENABLE_LLVM. This gets added > everytime we do a gcc4.2 merge. Hopefully this commit fix it once > for all. It probably won't unless you put LOCAL comments in the right places. > Modified: > llvm-gcc-4.2/trunk/gcc/config/arm/arm.c > > Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.c?rev=60073&r1=60072&r2=60073&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/config/arm/arm.c (original) > +++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Tue Nov 25 19:18:51 2008 > @@ -84,7 +84,9 @@ > static const char *fp_const_from_val (REAL_VALUE_TYPE *); > static arm_cc get_arm_condition_code (rtx); > static HOST_WIDE_INT int_log2 (HOST_WIDE_INT); > +#ifndef ENABLE_LLVM > static rtx is_jump_table (rtx); > +#endif > static const char *output_multi_immediate (rtx *, const char *, > const char *, > int, HOST_WIDE_INT); > static const char *shift_op (rtx, HOST_WIDE_INT *); > @@ -97,7 +99,6 @@ > /* APPLE LOCAL end compact switch tables */ > /* LLVM LOCAL */ > #ifndef ENABLE_LLVM > -static rtx is_jump_table (rtx); > static HOST_WIDE_INT get_jump_table_size (rtx); > static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, > HOST_WIDE_INT); > static Mnode *add_minipool_forward_ref (Mfix *); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Nov 25 19:37:32 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 Nov 2008 17:37:32 -0800 Subject: [llvm-commits] [llvm-gcc-4.2] r60073 - /llvm-gcc-4.2/trunk/gcc/config/arm/arm.c In-Reply-To: <0016172D-F235-48D3-A4C3-E59C99CA9094@apple.com> References: <200811260118.mAQ1IpVS000317@zion.cs.uiuc.edu> <0016172D-F235-48D3-A4C3-E59C99CA9094@apple.com> Message-ID: <16e5fdf90811251737s1ca0f04cl75ef5bc386105fef@mail.gmail.com> On Tue, Nov 25, 2008 at 5:25 PM, Dale Johannesen wrote: > > On Nov 25, 2008, at 5:18 PMPST, Evan Cheng wrote: > >> Author: evancheng >> Date: Tue Nov 25 19:18:51 2008 >> New Revision: 60073 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60073&view=rev >> Log: >> Do not declare is_jump_table with ENABLE_LLVM. This gets added >> everytime we do a gcc4.2 merge. Hopefully this commit fix it once >> for all. > > It probably won't unless you put LOCAL comments in the right places. > Yes. Please put the local tags there. Otherwise, I have no idea. -bw From sabre at nondot.org Tue Nov 25 20:00:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 02:00:14 -0000 Subject: [llvm-commits] [llvm] r60074 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/X86/isel-sink3.ll Message-ID: <200811260200.mAQ20Ebr001723@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 20:00:14 2008 New Revision: 60074 URL: http://llvm.org/viewvc/llvm-project?rev=60074&view=rev Log: This adds in some code (currently disabled unless you pass -enable-smarter-addr-folding to llc) that gives CGP a better cost model for when to sink computations into addressing modes. The basic observation is that sinking increases register pressure when part of the addr computation has to be available for other reasons, such as having a use that is a non-memory operation. In cases where it works, it can substantially reduce register pressure. This code is currently an overall win on 403.gcc and 255.vortex (the two things I've been looking at), but there are several things I want to do before enabling it by default: 1. This isn't doing any caching of results, so it is much slower than it could be. It currently slows down release-asserts llc by 1.7% on 176.gcc: 27.12s -> 27.60s. 2. This doesn't think about inline asm memory operands yet. 3. The cost model botches the case when the needed value is live across the computation for other reasons. I'll continue poking at this, and eventually turn it on as llcbeta. Added: llvm/trunk/test/CodeGen/X86/isel-sink3.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60074&r1=60073&r2=60074&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 20:00:14 2008 @@ -504,7 +504,7 @@ }; } // end anonymous namespace -static OStream &operator<<(OStream &OS, const ExtAddrMode &AM) { +static inline OStream &operator<<(OStream &OS, const ExtAddrMode &AM) { AM.print(OS); return OS; } @@ -541,11 +541,22 @@ const TargetLowering &TLI; const Type *AccessTy; ExtAddrMode &AddrMode; + + /// IgnoreProfitability - This is set to true when we should not do + /// profitability checks. When true, IsProfitableToFoldIntoAddressingMode + /// always returns true. + bool IgnoreProfitability; + AddressingModeMatcher(SmallVectorImpl &AMI, const TargetLowering &T, const Type *AT,ExtAddrMode &AM) - : AddrModeInsts(AMI), TLI(T), AccessTy(AT), AddrMode(AM) {} + : AddrModeInsts(AMI), TLI(T), AccessTy(AT), AddrMode(AM) { + IgnoreProfitability = false; + } public: + /// Match - Find the maximal addressing mode that a load/store of V can fold, + /// give an access type of AccessTy. This returns a list of involved + /// instructions in AddrModeInsts. static ExtAddrMode Match(Value *V, const Type *AccessTy, SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI) { @@ -560,6 +571,7 @@ bool MatchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth); bool MatchAddr(Value *V, unsigned Depth); bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth); + bool IsProfitableToFoldIntoAddressingMode(Instruction *I); }; } // end anonymous namespace @@ -617,6 +629,36 @@ return true; } +/// MightBeFoldableInst - This is a little filter, which returns true if an +/// addressing computation involving I might be folded into a load/store +/// accessing it. This doesn't need to be perfect, but needs to accept at least +/// the set of instructions that MatchOperationAddr can. +static bool MightBeFoldableInst(Instruction *I) { + switch (I->getOpcode()) { + case Instruction::BitCast: + // Don't touch identity bitcasts. + if (I->getType() == I->getOperand(0)->getType()) + return false; + return isa(I->getType()) || isa(I->getType()); + case Instruction::PtrToInt: + // PtrToInt is always a noop, as we know that the int type is pointer sized. + return true; + case Instruction::IntToPtr: + // We know the input is intptr_t, so this is foldable. + return true; + case Instruction::Add: + return true; + case Instruction::Mul: + case Instruction::Shl: + // Can only handle X*C and X << C. + return isa(I->getOperand(1)); + case Instruction::GetElementPtr: + return true; + default: + return false; + } +} + /// MatchOperationAddr - Given an instruction or constant expr, see if we can /// fold the operation into the addressing mode. If so, update the addressing @@ -669,12 +711,9 @@ AddrModeInsts.resize(OldSize); break; } - case Instruction::Or: { - //ConstantInt *RHS = dyn_cast(AddrInst->getOperand(1)); - //if (!RHS) break; - // TODO: We can handle "Or Val, Imm" iff this OR is equivalent to an ADD. - break; - } + //case Instruction::Or: + // TODO: We can handle "Or Val, Imm" iff this OR is equivalent to an ADD. + //break; case Instruction::Mul: case Instruction::Shl: { // Can only handle X*C and X << C. @@ -796,9 +835,23 @@ AddrMode.BaseGV = 0; } } else if (Instruction *I = dyn_cast(Addr)) { + ExtAddrMode BackupAddrMode = AddrMode; + unsigned OldSize = AddrModeInsts.size(); + + // Check to see if it is possible to fold this operation. if (MatchOperationAddr(I, I->getOpcode(), Depth)) { - AddrModeInsts.push_back(I); - return true; + // Okay, it's possible to fold this. Check to see if it is actually + // *profitable* to do so. We use a simple cost model to avoid increasing + // register pressure too much. + if (I->hasOneUse() || IsProfitableToFoldIntoAddressingMode(I)) { + AddrModeInsts.push_back(I); + return true; + } + + // It isn't profitable to do this, roll back. + //cerr << "NOT FOLDING: " << *I; + AddrMode = BackupAddrMode; + AddrModeInsts.resize(OldSize); } } else if (ConstantExpr *CE = dyn_cast(Addr)) { if (MatchOperationAddr(CE, CE->getOpcode(), Depth)) @@ -832,6 +885,136 @@ return false; } +/// FindAllMemoryUses - Recursively walk all the uses of I until we find a +/// memory use. If we find an obviously non-foldable instruction, return true. +/// Add the ultimately found memory instructions to MemoryUses. +static bool FindAllMemoryUses(Instruction *I, + SmallVectorImpl > &MemoryUses, + SmallPtrSet &ConsideredInsts) { + // If we already considered this instruction, we're done. + if (!ConsideredInsts.insert(I)) + return false; + + // If this is an obviously unfoldable instruction, bail out. + if (!MightBeFoldableInst(I)) + return true; + + // Loop over all the uses, recursively processing them. + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + if (LoadInst *LI = dyn_cast(*UI)) { + MemoryUses.push_back(std::make_pair(LI, UI.getOperandNo())); + continue; + } + + if (StoreInst *SI = dyn_cast(*UI)) { + if (UI.getOperandNo() == 0) return true; // Storing addr, not into addr. + MemoryUses.push_back(std::make_pair(SI, UI.getOperandNo())); + continue; + } + + if (CallInst *CI = dyn_cast(*UI)) { + InlineAsm *IA = dyn_cast(CI->getCalledValue()); + if (IA == 0) return true; + + + // FIXME: HANDLE MEM OPS + //MemoryUses.push_back(std::make_pair(CI, UI.getOperandNo())); + return true; + } + + if (FindAllMemoryUses(cast(*UI), MemoryUses, ConsideredInsts)) + return true; + } + + return false; +} + +#include "llvm/Support/CommandLine.h" +cl::opt ENABLECRAZYHACK("enable-smarter-addr-folding", cl::Hidden); + + +/// IsProfitableToFoldIntoAddressingMode - It is possible for the addressing +/// mode of the machine to fold the specified instruction into a load or store +/// that ultimately uses it. However, the specified instruction has multiple +/// uses. Given this, it may actually increase register pressure to fold it +/// into the load. For example, consider this code: +/// +/// X = ... +/// Y = X+1 +/// use(Y) -> nonload/store +/// Z = Y+1 +/// load Z +/// +/// In this case, Y has multiple uses, and can be folded into the load of Z +/// (yielding load [X+2]). However, doing this will cause both "X" and "X+1" to +/// be live at the use(Y) line. If we don't fold Y into load Z, we use one +/// fewer register. Since Y can't be folded into "use(Y)" we don't increase the +/// number of computations either. +/// +/// Note that this (like most of CodeGenPrepare) is just a rough heuristic. If +/// X was live across 'load Z' for other reasons, we actually *would* want to +/// fold the addressing mode in the Z case. +bool AddressingModeMatcher:: +IsProfitableToFoldIntoAddressingMode(Instruction *I) { + if (IgnoreProfitability || !ENABLECRAZYHACK) return true; + + // If 'I' is a constant GEP from an alloca, always fold it. This allows us + // to get an offset from the stack pointer. If a non-memory use uses this GEP + // it will just get an add of a constant to the stack pointer. This increases + // the lifetime of the stack pointer, which is always live anyway. + if (GetElementPtrInst *GEPI = dyn_cast(I)) + // FIXME: This is just a special purpose form of availability hacking. + if (isa(GEPI->getOperand(0)) && GEPI->hasAllConstantIndices()) + return true; + + // If all uses of this instruction are ultimately load/store/inlineasm's, + // check to see if their addressing modes will include this instruction. If + // so, we can fold it into all uses, so it doesn't matter if it has multiple + // uses. + SmallVector, 16> MemoryUses; + SmallPtrSet ConsideredInsts; + if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts)) + return false; // Has a non-memory, non-foldable use! + + // Now that we know that all uses of this instruction are part of a chain of + // computation involving only operations that could theoretically be folded + // into a memory use, loop over each of these uses and see if they could + // *actually* fold the instruction. + SmallVector MatchedAddrModeInsts; + for (unsigned i = 0, e = MemoryUses.size(); i != e; ++i) { + Instruction *User = MemoryUses[i].first; + unsigned OpNo = MemoryUses[i].second; + + // Get the access type of this use. If the use isn't a pointer, we don't + // know what it accesses. + Value *Address = User->getOperand(OpNo); + if (!isa(Address->getType())) + return false; + const Type *AddressAccessTy = + cast(Address->getType())->getElementType(); + + // Do a match against the root of this address, ignoring profitability. This + // will tell us if the addressing mode for the memory operation will + // *actually* cover the shared instruction. + ExtAddrMode Result; + AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI, AddressAccessTy, + Result); + Matcher.IgnoreProfitability = true; + bool Success = Matcher.MatchAddr(Address, 0); + Success = Success; assert(Success && "Couldn't select *anything*?"); + + // If the match didn't cover I, then it won't be shared by it. + if (std::find(MatchedAddrModeInsts.begin(), MatchedAddrModeInsts.end(), + I) == MatchedAddrModeInsts.end()) + return false; + + MatchedAddrModeInsts.clear(); + } + + return true; +} + //===----------------------------------------------------------------------===// // Memory Optimization Added: llvm/trunk/test/CodeGen/X86/isel-sink3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/isel-sink3.ll?rev=60074&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/isel-sink3.ll (added) +++ llvm/trunk/test/CodeGen/X86/isel-sink3.ll Tue Nov 25 20:00:14 2008 @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s | llc -enable-smarter-addr-folding | grep {addl.(%eax), %ecx} +; RUN: llvm-as < %s | llc -enable-smarter-addr-folding | not grep leal +; this should not sink %1 into bb1, that would increase reg pressure. + +; rdar://6399178 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i32 @bar(i32** %P) nounwind { +entry: + %0 = load i32** %P, align 4 ; [#uses=2] + %1 = getelementptr i32* %0, i32 1 ; [#uses=1] + %2 = icmp ugt i32* %1, inttoptr (i64 1233 to i32*) ; [#uses=1] + br i1 %2, label %bb1, label %bb + +bb: ; preds = %entry + store i32* inttoptr (i64 123 to i32*), i32** %P, align 4 + br label %bb1 + +bb1: ; preds = %entry, %bb + %3 = getelementptr i32* %1, i32 1 ; [#uses=1] + %4 = load i32* %3, align 4 ; [#uses=1] + ret i32 %4 +} From evan.cheng at apple.com Tue Nov 25 20:10:32 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Nov 2008 02:10:32 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60075 - /llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Message-ID: <200811260210.mAQ2AWdT002041@zion.cs.uiuc.edu> Author: evancheng Date: Tue Nov 25 20:10:32 2008 New Revision: 60075 URL: http://llvm.org/viewvc/llvm-project?rev=60075&view=rev Log: Forgot LLVM LOCAL markers. Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.c?rev=60075&r1=60074&r2=60075&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/arm/arm.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.c Tue Nov 25 20:10:32 2008 @@ -84,8 +84,10 @@ static const char *fp_const_from_val (REAL_VALUE_TYPE *); static arm_cc get_arm_condition_code (rtx); static HOST_WIDE_INT int_log2 (HOST_WIDE_INT); +/* LLVM LOCAL */ #ifndef ENABLE_LLVM static rtx is_jump_table (rtx); +/* LLVM LOCAL */ #endif static const char *output_multi_immediate (rtx *, const char *, const char *, int, HOST_WIDE_INT); From sabre at nondot.org Tue Nov 25 20:11:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 02:11:11 -0000 Subject: [llvm-commits] [llvm] r60076 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811260211.mAQ2BBj6002073@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 20:11:11 2008 New Revision: 60076 URL: http://llvm.org/viewvc/llvm-project?rev=60076&view=rev Log: add a comment, make save/restore logic more obvious. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60076&r1=60075&r2=60076&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 20:11:11 2008 @@ -864,22 +864,22 @@ // Worse case, the target should support [reg] addressing modes. :) if (!AddrMode.HasBaseReg) { AddrMode.HasBaseReg = true; + AddrMode.BaseReg = Addr; // Still check for legality in case the target supports [imm] but not [i+r]. - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) { - AddrMode.BaseReg = Addr; + if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) return true; - } AddrMode.HasBaseReg = false; + AddrMode.BaseReg = 0; } // If the base register is already taken, see if we can do [r+r]. if (AddrMode.Scale == 0) { AddrMode.Scale = 1; - if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) { - AddrMode.ScaledReg = Addr; + AddrMode.ScaledReg = Addr; + if (TLI.isLegalAddressingMode(AddrMode, AccessTy)) return true; - } AddrMode.Scale = 0; + AddrMode.ScaledReg = 0; } // Couldn't match. return false; @@ -954,7 +954,7 @@ /// /// Note that this (like most of CodeGenPrepare) is just a rough heuristic. If /// X was live across 'load Z' for other reasons, we actually *would* want to -/// fold the addressing mode in the Z case. +/// fold the addressing mode in the Z case. This would make Y die earlier. bool AddressingModeMatcher:: IsProfitableToFoldIntoAddressingMode(Instruction *I) { if (IgnoreProfitability || !ENABLECRAZYHACK) return true; From isanbard at gmail.com Tue Nov 25 20:19:30 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 02:19:30 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60078 - /llvm-gcc-4.2/trunk/gcc/tree-nested.c Message-ID: <200811260219.mAQ2JUIZ002312@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 20:19:29 2008 New Revision: 60078 URL: http://llvm.org/viewvc/llvm-project?rev=60078&view=rev Log: Don't treat synthesized block helper functions as being nested. They are created and then their addresses may be used in more than one function. Modified: llvm-gcc-4.2/trunk/gcc/tree-nested.c Modified: llvm-gcc-4.2/trunk/gcc/tree-nested.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree-nested.c?rev=60078&r1=60077&r2=60078&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree-nested.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree-nested.c Tue Nov 25 20:19:29 2008 @@ -1703,6 +1703,11 @@ if (TREE_CODE (decl) != FUNCTION_DECL) break; + /* LLVM LOCAL - begin radar 6394879 */ + if (BLOCK_SYNTHESIZED_FUNC (decl)) + break; + /* LLVM LOCAL - end radar 6394879 */ + if (!decl_function_context (decl)) break; From isanbard at gmail.com Tue Nov 25 20:21:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 02:21:13 -0000 Subject: [llvm-commits] [llvm] r60079 - /llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m Message-ID: <200811260221.mAQ2LDIH002388@zion.cs.uiuc.edu> Author: void Date: Tue Nov 25 20:21:12 2008 New Revision: 60079 URL: http://llvm.org/viewvc/llvm-project?rev=60079&view=rev Log: Add test for rdar://6394879. Added: llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m Added: llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m?rev=60079&view=auto ============================================================================== --- llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m (added) +++ llvm/trunk/test/FrontendObjC/2008-11-25-Blocks.m Tue Nov 25 20:21:12 2008 @@ -0,0 +1,17 @@ +// RUN: %llvmgcc -c %s -o /dev/null +// rdar://6394879 + + at interface bork +- (id)B:(void (^)())blk; +- (void)C; + at end + at implementation bork +- (id)B:(void (^)())blk { + __attribute__((__blocks__(byref))) bork* new = ((void *)0); + blk(); +} +- (void)C { + __attribute__((__blocks__(byref))) id var; + [self B:^() {}]; +} + at end From sabre at nondot.org Tue Nov 25 20:54:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 02:54:17 -0000 Subject: [llvm-commits] [llvm] r60080 - in /llvm/trunk: include/llvm/Instructions.h lib/VMCore/Instructions.cpp Message-ID: <200811260254.mAQ2sHFm003422@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 20:54:17 2008 New Revision: 60080 URL: http://llvm.org/viewvc/llvm-project?rev=60080&view=rev Log: add a long-overdue AllocaInst::isStaticAlloca method. Modified: llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=60080&r1=60079&r2=60080&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Nov 25 20:54:17 2008 @@ -167,6 +167,11 @@ : AllocationInst(Ty, ArraySize, Alloca, Align, NameStr, InsertAtEnd) {} virtual AllocaInst *clone() const; + + /// isStaticAlloca - Return true if this alloca is in the entry block of the + /// function and is a constant size. If so, the code generator will fold it + /// into the prolog/epilog code, so it is basically free. + bool isStaticAlloca() const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const AllocaInst *) { return true; } Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=60080&r1=60079&r2=60080&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Nov 25 20:54:17 2008 @@ -732,6 +732,18 @@ Instruction::Alloca, AI.getAlignment()) { } +/// isStaticAlloca - Return true if this alloca is in the entry block of the +/// function and is a constant size. If so, the code generator will fold it +/// into the prolog/epilog code, so it is basically free. +bool AllocaInst::isStaticAlloca() const { + // Must be constant size. + if (!isa(getArraySize())) return false; + + // Must be in the entry block. + const BasicBlock *Parent = getParent(); + return Parent == &Parent->getParent()->front(); +} + MallocInst::MallocInst(const MallocInst &MI) : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0), Instruction::Malloc, MI.getAlignment()) { From xuzhongxing at gmail.com Tue Nov 25 20:57:24 2008 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Wed, 26 Nov 2008 02:57:24 -0000 Subject: [llvm-commits] [llvm] r60081 - /llvm/trunk/tools/opt/opt.cpp Message-ID: <200811260257.mAQ2vOPo003551@zion.cs.uiuc.edu> Author: zhongxingxu Date: Tue Nov 25 20:57:24 2008 New Revision: 60081 URL: http://llvm.org/viewvc/llvm-project?rev=60081&view=rev Log: Adjust indent. Modified: llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=60081&r1=60080&r2=60081&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Tue Nov 25 20:57:24 2008 @@ -264,8 +264,8 @@ /// duplicates llvm-gcc behaviour. /// /// OptLevel - Optimization Level - void AddOptimizationPasses(PassManager &MPM, FunctionPassManager &FPM, - unsigned OptLevel) { +void AddOptimizationPasses(PassManager &MPM, FunctionPassManager &FPM, + unsigned OptLevel) { if (OptLevel == 0) return; From sabre at nondot.org Tue Nov 25 21:02:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 03:02:42 -0000 Subject: [llvm-commits] [llvm] r60082 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811260302.mAQ32giV003748@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 21:02:41 2008 New Revision: 60082 URL: http://llvm.org/viewvc/llvm-project?rev=60082&view=rev Log: Start rewroking a subpiece of the profitability heuristic to be phrased in terms of liveness instead of as a horrible hack. :) In pratice, this doesn't change the generated code for either 255.vortex or 403.gcc, but it could cause minor code changes in theory. This is framework for coming changes. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60082&r1=60081&r2=60082&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 21:02:41 2008 @@ -571,7 +571,10 @@ bool MatchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth); bool MatchAddr(Value *V, unsigned Depth); bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth); - bool IsProfitableToFoldIntoAddressingMode(Instruction *I); + bool IsProfitableToFoldIntoAddressingMode(Instruction *I, + ExtAddrMode &AMBefore, + ExtAddrMode &AMAfter); + bool ValueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2); }; } // end anonymous namespace @@ -843,7 +846,8 @@ // Okay, it's possible to fold this. Check to see if it is actually // *profitable* to do so. We use a simple cost model to avoid increasing // register pressure too much. - if (I->hasOneUse() || IsProfitableToFoldIntoAddressingMode(I)) { + if (I->hasOneUse() || + IsProfitableToFoldIntoAddressingMode(I, BackupAddrMode, AddrMode)) { AddrModeInsts.push_back(I); return true; } @@ -929,7 +933,33 @@ return false; } + + +/// ValueAlreadyLiveAtInst - Retrn true if Val is already known to be live at +/// the use site that we're folding it into. If so, there is no cost to +/// include it in the addressing mode. KnownLive1 and KnownLive2 are two values +/// that we know are live at the instruction already. +bool AddressingModeMatcher::ValueAlreadyLiveAtInst(Value *Val,Value *KnownLive1, + Value *KnownLive2) { + // If Val is either of the known-live values, we know it is live! + if (Val == 0 || Val == KnownLive1 || Val == KnownLive2) + return true; + + // All non-instruction values other than arguments (constants) are live. + if (!isa(Val) && !isa(Val)) return true; + // If Val is a constant sized alloca in the entry block, it is live, this is + // true because it is just a reference to the stack/frame pointer, which is + // live for the whole function. + if (AllocaInst *AI = dyn_cast(Val)) + if (AI->isStaticAlloca()) + return true; + + return false; +} + + + #include "llvm/Support/CommandLine.h" cl::opt ENABLECRAZYHACK("enable-smarter-addr-folding", cl::Hidden); @@ -956,17 +986,32 @@ /// X was live across 'load Z' for other reasons, we actually *would* want to /// fold the addressing mode in the Z case. This would make Y die earlier. bool AddressingModeMatcher:: -IsProfitableToFoldIntoAddressingMode(Instruction *I) { +IsProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore, + ExtAddrMode &AMAfter) { if (IgnoreProfitability || !ENABLECRAZYHACK) return true; - // If 'I' is a constant GEP from an alloca, always fold it. This allows us - // to get an offset from the stack pointer. If a non-memory use uses this GEP - // it will just get an add of a constant to the stack pointer. This increases - // the lifetime of the stack pointer, which is always live anyway. - if (GetElementPtrInst *GEPI = dyn_cast(I)) - // FIXME: This is just a special purpose form of availability hacking. - if (isa(GEPI->getOperand(0)) && GEPI->hasAllConstantIndices()) - return true; + // AMBefore is the addressing mode before this instruction was folded into it, + // and AMAfter is the addressing mode after the instruction was folded. Get + // the set of registers referenced by AMAfter and subtract out those + // referenced by AMBefore: this is the set of values which folding in this + // address extends the lifetime of. + // + // Note that there are only two potential values being referenced here, + // BaseReg and ScaleReg (global addresses are always available, as are any + // folded immediates). + Value *BaseReg = AMAfter.BaseReg, *ScaledReg = AMAfter.ScaledReg; + + // If the BaseReg or ScaledReg was referenced by the previous addrmode, their + // lifetime wasn't extended by adding this instruction. + if (ValueAlreadyLiveAtInst(BaseReg, AMBefore.BaseReg, AMBefore.ScaledReg)) + BaseReg = 0; + if (ValueAlreadyLiveAtInst(ScaledReg, AMBefore.BaseReg, AMBefore.ScaledReg)) + ScaledReg = 0; + + // If folding this instruction (and it's subexprs) didn't extend any live + // ranges, we're ok with it. + if (BaseReg == 0 && ScaledReg == 0) + return true; // If all uses of this instruction are ultimately load/store/inlineasm's, // check to see if their addressing modes will include this instruction. If From nicholas at mxc.ca Tue Nov 25 21:17:27 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 26 Nov 2008 03:17:27 -0000 Subject: [llvm-commits] [llvm] r60083 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200811260317.mAQ3HRsW004216@zion.cs.uiuc.edu> Author: nicholas Date: Tue Nov 25 21:17:27 2008 New Revision: 60083 URL: http://llvm.org/viewvc/llvm-project?rev=60083&view=rev Log: __fastcall and __stdcall are mingw extensions to gcc for windows. Use the __attribute__ notation which is supported on more platforms. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=60083&r1=60082&r2=60083&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Nov 25 21:17:27 2008 @@ -2193,10 +2193,10 @@ if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; switch (F->getCallingConv()) { case CallingConv::X86_StdCall: - Out << "__stdcall "; + Out << "__attribute__((stdcall)) "; break; case CallingConv::X86_FastCall: - Out << "__fastcall "; + Out << "__attribute__((fastcall)) "; break; } From sabre at nondot.org Tue Nov 25 21:20:37 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 03:20:37 -0000 Subject: [llvm-commits] [llvm] r60084 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811260320.mAQ3KbkO004317@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 21:20:37 2008 New Revision: 60084 URL: http://llvm.org/viewvc/llvm-project?rev=60084&view=rev Log: Improve ValueAlreadyLiveAtInst with a cheap and dirty, but effective heuristic: the value is already live at the new memory operation if it is used by some other instruction in the memop's block. This is cheap and simple to compute (moreso than full liveness). This improves the new heuristic even more. For example, it cuts two out of three new instructions out of 255.vortex:DbmFileInGrpHdr, which is one of the functions that the heuristic regressed. This overall eliminates another 40 instructions from 403.gcc and visibly reduces register pressure in 255.vortex (though this only actually ends up saving the 2 instructions from the whole program). Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60084&r1=60083&r2=60084&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 21:20:37 2008 @@ -539,7 +539,14 @@ class AddressingModeMatcher { SmallVectorImpl &AddrModeInsts; const TargetLowering &TLI; + + /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and + /// the memory instruction that we're computing this address for. const Type *AccessTy; + Instruction *MemoryInst; + + /// AddrMode - This is the addressing mode that we're building up. This is + /// part of the return value of this addressing mode matching stuff. ExtAddrMode &AddrMode; /// IgnoreProfitability - This is set to true when we should not do @@ -548,8 +555,9 @@ bool IgnoreProfitability; AddressingModeMatcher(SmallVectorImpl &AMI, - const TargetLowering &T, const Type *AT,ExtAddrMode &AM) - : AddrModeInsts(AMI), TLI(T), AccessTy(AT), AddrMode(AM) { + const TargetLowering &T, const Type *AT, + Instruction *MI, ExtAddrMode &AM) + : AddrModeInsts(AMI), TLI(T), AccessTy(AT), MemoryInst(MI), AddrMode(AM) { IgnoreProfitability = false; } public: @@ -557,13 +565,15 @@ /// Match - Find the maximal addressing mode that a load/store of V can fold, /// give an access type of AccessTy. This returns a list of involved /// instructions in AddrModeInsts. - static ExtAddrMode Match(Value *V, const Type *AccessTy, + static ExtAddrMode Match(Value *V, const Type *AccessTy, + Instruction *MemoryInst, SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI) { ExtAddrMode Result; bool Success = - AddressingModeMatcher(AddrModeInsts,TLI,AccessTy,Result).MatchAddr(V, 0); + AddressingModeMatcher(AddrModeInsts, TLI, AccessTy, + MemoryInst, Result).MatchAddr(V, 0); Success = Success; assert(Success && "Couldn't select *anything*?"); return Result; } @@ -945,7 +955,7 @@ if (Val == 0 || Val == KnownLive1 || Val == KnownLive2) return true; - // All non-instruction values other than arguments (constants) are live. + // All values other than instructions and arguments (e.g. constants) are live. if (!isa(Val) && !isa(Val)) return true; // If Val is a constant sized alloca in the entry block, it is live, this is @@ -955,6 +965,16 @@ if (AI->isStaticAlloca()) return true; + // Check to see if this value is already used in the memory instruction's + // block. If so, it's already live into the block at the very least, so we + // can reasonably fold it. + BasicBlock *MemBB = MemoryInst->getParent(); + for (Value::use_iterator UI = Val->use_begin(), E = Val->use_end(); + UI != E; ++UI) + // We know that uses of arguments and instructions have to be instructions. + if (cast(*UI)->getParent() == MemBB) + return true; + return false; } @@ -1044,7 +1064,7 @@ // *actually* cover the shared instruction. ExtAddrMode Result; AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI, AddressAccessTy, - Result); + MemoryInst, Result); Matcher.IgnoreProfitability = true; bool Success = Matcher.MatchAddr(Address, 0); Success = Success; assert(Success && "Couldn't select *anything*?"); @@ -1082,19 +1102,19 @@ /// /// This method is used to optimize both load/store and inline asms with memory /// operands. -bool CodeGenPrepare::OptimizeMemoryInst(Instruction *LdStInst, Value *Addr, +bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, const Type *AccessTy, DenseMap &SunkAddrs) { // Figure out what addressing mode will be built up for this operation. SmallVector AddrModeInsts; - ExtAddrMode AddrMode = - AddressingModeMatcher::Match(Addr, AccessTy, AddrModeInsts, *TLI); + ExtAddrMode AddrMode = AddressingModeMatcher::Match(Addr, AccessTy,MemoryInst, + AddrModeInsts, *TLI); // Check to see if any of the instructions supersumed by this addr mode are // non-local to I's BB. bool AnyNonLocal = false; for (unsigned i = 0, e = AddrModeInsts.size(); i != e; ++i) { - if (IsNonLocalValue(AddrModeInsts[i], LdStInst->getParent())) { + if (IsNonLocalValue(AddrModeInsts[i], MemoryInst->getParent())) { AnyNonLocal = true; break; } @@ -1109,7 +1129,7 @@ // Insert this computation right after this user. Since our caller is // scanning from the top of the BB to the bottom, reuse of the expr are // guaranteed to happen later. - BasicBlock::iterator InsertPt = LdStInst; + BasicBlock::iterator InsertPt = MemoryInst; // Now that we determined the addressing expression we want to use and know // that we have to sink it into this block. Check to see if we have already @@ -1181,7 +1201,7 @@ SunkAddr = new IntToPtrInst(Result, Addr->getType(), "sunkaddr",InsertPt); } - LdStInst->replaceUsesOfWith(Addr, SunkAddr); + MemoryInst->replaceUsesOfWith(Addr, SunkAddr); if (Addr->use_empty()) EraseDeadInstructions(Addr); From kremenek at apple.com Tue Nov 25 21:33:13 2008 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 26 Nov 2008 03:33:13 -0000 Subject: [llvm-commits] [llvm] r60085 - in /llvm/trunk: include/llvm/Support/raw_ostream.h lib/Support/raw_ostream.cpp Message-ID: <200811260333.mAQ3XDdY004725@zion.cs.uiuc.edu> Author: kremenek Date: Tue Nov 25 21:33:13 2008 New Revision: 60085 URL: http://llvm.org/viewvc/llvm-project?rev=60085&view=rev Log: Add 'tell' method to raw_fd_ostream that clients can use to query the current location in the file the stream is writing to. Modified: llvm/trunk/include/llvm/Support/raw_ostream.h llvm/trunk/lib/Support/raw_ostream.cpp Modified: llvm/trunk/include/llvm/Support/raw_ostream.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/raw_ostream.h?rev=60085&r1=60084&r2=60085&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/raw_ostream.h (original) +++ llvm/trunk/include/llvm/Support/raw_ostream.h Tue Nov 25 21:33:13 2008 @@ -175,7 +175,10 @@ virtual void flush_impl(); /// close - Manually flush the stream and close the file. - void close(); + void close(); + + /// tell - Return the current offset with the file. + uint64_t tell(); }; /// raw_stdout_ostream - This is a stream that always prints to stdout. Modified: llvm/trunk/lib/Support/raw_ostream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=60085&r1=60084&r2=60085&view=diff ============================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp (original) +++ llvm/trunk/lib/Support/raw_ostream.cpp Tue Nov 25 21:33:13 2008 @@ -253,6 +253,14 @@ FD = -1; } +uint64_t raw_fd_ostream::tell() { + // We have to take into account the bytes waiting in the buffer. For now + // we do the easy thing and just flush the buffer before getting the + // current file offset. + flush(); + return (uint64_t) lseek(FD, 0, SEEK_CUR); +} + //===----------------------------------------------------------------------===// // raw_stdout/err_ostream //===----------------------------------------------------------------------===// From dpatel at apple.com Tue Nov 25 22:58:15 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 Nov 2008 04:58:15 -0000 Subject: [llvm-commits] [llvm] r60087 - /llvm/trunk/tools/opt/opt.cpp Message-ID: <200811260458.mAQ4wFfW007490@zion.cs.uiuc.edu> Author: dpatel Date: Tue Nov 25 22:58:14 2008 New Revision: 60087 URL: http://llvm.org/viewvc/llvm-project?rev=60087&view=rev Log: Disable -loop-index-split for now. Modified: llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=60087&r1=60086&r2=60087&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Tue Nov 25 22:58:14 2008 @@ -311,7 +311,7 @@ MPM.add(createLoopRotatePass()); // Rotate Loop MPM.add(createLICMPass()); // Hoist loop invariants MPM.add(createLoopUnswitchPass()); - MPM.add(createLoopIndexSplitPass()); // Split loop index + // MPM.add(createLoopIndexSplitPass()); // Split loop index MPM.add(createInstructionCombiningPass()); MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars MPM.add(createLoopDeletionPass()); // Delete dead loops @@ -383,7 +383,7 @@ addPass(PM, createLoopRotatePass()); addPass(PM, createLICMPass()); // Hoist loop invariants addPass(PM, createLoopUnswitchPass()); // Unswitch loops. - addPass(PM, createLoopIndexSplitPass()); // Index split loops. + // addPass(PM, createLoopIndexSplitPass()); // Index split loops. // FIXME : Removing instcombine causes nestedloop regression. addPass(PM, createInstructionCombiningPass()); addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars From sabre at nondot.org Tue Nov 25 22:59:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 04:59:11 -0000 Subject: [llvm-commits] [llvm] r60088 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811260459.mAQ4xB4h007532@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 22:59:11 2008 New Revision: 60088 URL: http://llvm.org/viewvc/llvm-project?rev=60088&view=rev Log: teach the new heuristic how to handle inline asm. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60088&r1=60087&r2=60088&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Tue Nov 25 22:59:11 2008 @@ -899,12 +899,56 @@ return false; } + +/// IsOperandAMemoryOperand - Check to see if all uses of OpVal by the specified +/// inline asm call are due to memory operands. If so, return true, otherwise +/// return false. +static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, + const TargetLowering &TLI) { + std::vector + Constraints = IA->ParseConstraints(); + + unsigned ArgNo = 1; // ArgNo - The operand of the CallInst. + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + TargetLowering::AsmOperandInfo OpInfo(Constraints[i]); + + // Compute the value type for each operand. + switch (OpInfo.Type) { + case InlineAsm::isOutput: + if (OpInfo.isIndirect) + OpInfo.CallOperandVal = CI->getOperand(ArgNo++); + break; + case InlineAsm::isInput: + OpInfo.CallOperandVal = CI->getOperand(ArgNo++); + break; + case InlineAsm::isClobber: + // Nothing to do. + break; + } + + // Compute the constraint code and ConstraintType to use. + TLI.ComputeConstraintToUse(OpInfo, SDValue(), + OpInfo.ConstraintType == TargetLowering::C_Memory); + + // If this asm operand is our Value*, and if it isn't an indirect memory + // operand, we can't fold it! + if (OpInfo.CallOperandVal == OpVal && + (OpInfo.ConstraintType != TargetLowering::C_Memory || + !OpInfo.isIndirect)) + return false; + } + + return true; +} + + /// FindAllMemoryUses - Recursively walk all the uses of I until we find a /// memory use. If we find an obviously non-foldable instruction, return true. /// Add the ultimately found memory instructions to MemoryUses. static bool FindAllMemoryUses(Instruction *I, SmallVectorImpl > &MemoryUses, - SmallPtrSet &ConsideredInsts) { + SmallPtrSet &ConsideredInsts, + const TargetLowering &TLI) { // If we already considered this instruction, we're done. if (!ConsideredInsts.insert(I)) return false; @@ -930,14 +974,15 @@ if (CallInst *CI = dyn_cast(*UI)) { InlineAsm *IA = dyn_cast(CI->getCalledValue()); if (IA == 0) return true; - - // FIXME: HANDLE MEM OPS - //MemoryUses.push_back(std::make_pair(CI, UI.getOperandNo())); - return true; + // If this is a memory operand, we're cool, otherwise bail out. + if (!IsOperandAMemoryOperand(CI, IA, I, TLI)) + return true; + continue; } - if (FindAllMemoryUses(cast(*UI), MemoryUses, ConsideredInsts)) + if (FindAllMemoryUses(cast(*UI), MemoryUses, ConsideredInsts, + TLI)) return true; } @@ -1039,7 +1084,7 @@ // uses. SmallVector, 16> MemoryUses; SmallPtrSet ConsideredInsts; - if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts)) + if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TLI)) return false; // Has a non-memory, non-foldable use! // Now that we know that all uses of this instruction are part of a chain of From sabre at nondot.org Tue Nov 25 23:10:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 05:10:17 -0000 Subject: [llvm-commits] [test-suite] r60090 - /test-suite/trunk/Makefile.programs Message-ID: <200811260510.mAQ5AHZT007883@zion.cs.uiuc.edu> Author: lattner Date: Tue Nov 25 23:10:17 2008 New Revision: 60090 URL: http://llvm.org/viewvc/llvm-project?rev=60090&view=rev Log: Test my recent CGP changes as llc-beta tonight. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=60090&r1=60089&r2=60090&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Tue Nov 25 23:10:17 2008 @@ -226,7 +226,8 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -disable-post-RA-scheduler=false +LLCBETAOPTION := -enable-smarter-addr-folding +#-disable-post-RA-scheduler=false #-machine-licm #-fast-isel #-aggressive-remat From gohman at apple.com Tue Nov 25 23:50:31 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 Nov 2008 05:50:31 -0000 Subject: [llvm-commits] [llvm] r60092 - in /llvm/trunk: include/llvm/CodeGen/LiveInterval.h lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200811260550.mAQ5oV6W009565@zion.cs.uiuc.edu> Author: djg Date: Tue Nov 25 23:50:31 2008 New Revision: 60092 URL: http://llvm.org/viewvc/llvm-project?rev=60092&view=rev Log: LiveRanges are represented as half-open ranges. Fix the findLiveInMBBs code and the LiveInterval.h top-level comment and accordingly. This fixes blocks having spurious live-in registers in boundary cases. Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=60092&r1=60091&r2=60092&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Tue Nov 25 23:50:31 2008 @@ -9,7 +9,7 @@ // // This file implements the LiveRange and LiveInterval classes. Given some // numbering of each the machine instructions an interval [i, j) is said to be a -// live interval for register v if there is no instruction with number j' > j +// live interval for register v if there is no instruction with number j' >= j // such that v is live at j' and there is no instruction with number i' < i such // that v is live at i'. In this implementation intervals can have holes, // i.e. an interval might look like [1,20), [50,65), [1000,1001). Each Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60092&r1=60091&r2=60092&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Nov 25 23:50:31 2008 @@ -750,7 +750,7 @@ bool ResVal = false; while (I != Idx2MBBMap.end()) { - if (I->first > End) + if (I->first >= End) break; MBBs.push_back(I->second); ResVal = true; From gohman at apple.com Wed Nov 26 00:39:12 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 Nov 2008 06:39:12 -0000 Subject: [llvm-commits] [llvm] r60095 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86RegisterInfo.cpp Message-ID: <200811260639.mAQ6dCZI011295@zion.cs.uiuc.edu> Author: djg Date: Wed Nov 26 00:39:12 2008 New Revision: 60095 URL: http://llvm.org/viewvc/llvm-project?rev=60095&view=rev Log: Fish kill flag annotations in PUSH instructions. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60095&r1=60094&r2=60095&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Nov 26 00:39:12 2008 @@ -1880,7 +1880,8 @@ unsigned Reg = CSI[i-1].getReg(); // Add the callee-saved register as live-in. It's killed at the spill. MBB.addLiveIn(Reg); - BuildMI(MBB, MI, get(Opc)).addReg(Reg); + BuildMI(MBB, MI, get(Opc)) + .addReg(Reg, /*isDef=*/false, /*isImp=*/false, /*isKill=*/true); } return true; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=60095&r1=60094&r2=60095&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Wed Nov 26 00:39:12 2008 @@ -719,7 +719,7 @@ // Save EBP into the appropriate stack slot... BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) - .addReg(FramePtr); + .addReg(FramePtr, /*isDef=*/false, /*isImp=*/false, /*isKill=*/true); if (needsFrameMoves) { // Mark effective beginning of when frame pointer becomes valid. @@ -774,7 +774,8 @@ .addExternalSymbol("_alloca"); } else { // Save EAX - BuildMI(MBB, MBBI, TII.get(X86::PUSH32r), X86::EAX); + BuildMI(MBB, MBBI, TII.get(X86::PUSH32r)) + .addReg(X86::EAX, /*isDef=*/false, /*isImp=*/false, /*isKill=*/true); // Allocate NumBytes-4 bytes on stack. We'll also use 4 already // allocated bytes for EAX. BuildMI(MBB, MBBI, TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes-4); From isanbard at gmail.com Wed Nov 26 01:16:02 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 07:16:02 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60097 - /llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md Message-ID: <200811260716.mAQ7G2Nl012594@zion.cs.uiuc.edu> Author: void Date: Wed Nov 26 01:16:02 2008 New Revision: 60097 URL: http://llvm.org/viewvc/llvm-project?rev=60097&view=rev Log: Revert this back to the old behavior if TARGET_FIX_AND_CONTINUE isn't #defined. This may not be correct, but should help non-Darwin platforms work. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md Modified: llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md?rev=60097&r1=60096&r2=60097&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/predicates.md Wed Nov 26 01:16:02 2008 @@ -467,9 +467,13 @@ /* APPLE LOCAL begin fix-and-continue 6358507 */ if (SYMBOL_REF_LOCAL_P (op)) { +/* LLVM LOCAL begin non-Darwin hack. */ +#ifdef TARGET_FIX_AND_CONTINUE if (!TARGET_FIX_AND_CONTINUE - || machopic_data_defined_p (op)) - return 1; + || machopic_data_defined_p (op)) +#endif +/* LLVM LOCAL end non-Darwin hack */ + return 1; } /* APPLE LOCAL end fix-and-continue 6358507 */ From baldrick at free.fr Wed Nov 26 02:18:21 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Nov 2008 09:18:21 +0100 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <0C8DAB63-4282-41E0-B6C9-3D8478701BA5@apple.com> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <0C8DAB63-4282-41E0-B6C9-3D8478701BA5@apple.com> Message-ID: <200811260918.22327.baldrick@free.fr> > Sure, how about adding a new opUnsupportedOp flag? opInvalidOp means > something to IEEE, opUnsupportedOp could mean "we don't know how to > fold this" which is different. Why not teach APFloat to do arithmetic on PPCF128? Ciao, Duncan. From baldrick at free.fr Wed Nov 26 03:51:45 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Nov 2008 10:51:45 +0100 Subject: [llvm-commits] [llvm] r59960 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/PowerPC/PPCISelLowering.cpp In-Reply-To: <5D51222E-8941-495A-B86A-FDE6433EEADB@apple.com> References: <200811241453.mAOErL7j009491@zion.cs.uiuc.edu> <5D51222E-8941-495A-B86A-FDE6433EEADB@apple.com> Message-ID: <200811261051.45431.baldrick@free.fr> Hi Chris, > Nifty, does this improve anything? Can you add a testcase? it does occasionally improve things. Here's what it does to test/CodeGen/PowerPC/int-fp-conv-0.ll for example (RHS is with the new combine pass). It reduces the number of lines of code by 21 (about 1/4), at the expense of creating some new constants. I will add a testcase. Ciao, Duncan. .machine ppc64 .machine ppc64 .section __TEXT,__textcoal_nt,coalesced,pure_instruct .section __TEXT,__textcoal_nt,coalesced,pure_instruct .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .text .text > .literal4 > > .align 3 > LCPI1_0: > .space 4 > .literal8 > > .align 3 > LCPI1_1: > .quad 5183643171103440896 ; double value: 3.402 > .text .globl _foo .globl _foo .align 4 .align 4 _foo: _foo: mflr r0 mflr r0 std r0, 16(r1) std r0, 16(r1) stdu r1, -224(r1) | stdu r1, -160(r1) std r30, 216(r1) | std r30, 152(r1) stfd f14, 208(r1) | stfd f14, 144(r1) stfd f15, 200(r1) | stfd f15, 136(r1) > stfd f16, 128(r1) > stfd f17, 120(r1) mfcr r0 mfcr r0 rlwinm r0, r0, 8, 0, 31 rlwinm r0, r0, 8, 0, 31 stw r0, 196(r1) | stw r0, 116(r1) mr r30, r3 mr r30, r3 > lis r2, ha16(LCPI1_0) > lfs f14, lo16(LCPI1_0)(r2) > lis r2, ha16(LCPI1_1) > lfd f15, lo16(LCPI1_1)(r2) mr r3, r30 mr r3, r30 bl L___floattitf$stub bl L___floattitf$stub fmr f14, f1 | fmr f16, f1 fmr f15, f2 | fmr f17, f2 stfd f15, 160(r1) | fmr f4, f14 stfd f14, 168(r1) < li r2, 0 < li r3, 1151 < sldi r3, r3, 52 < ld r4, 160(r1) < std r4, 144(r1) < ld r4, 168(r1) < std r4, 152(r1) < std r3, 176(r1) < std r2, 184(r1) < lfd f2, 144(r1) < lfd f1, 152(r1) < lfd f3, 176(r1) < lfd f4, 184(r1) < cmpdi cr2, r30, 0 cmpdi cr2, r30, 0 > fmr f3, f15 bl L___gcc_qadd$stub bl L___gcc_qadd$stub blt cr2, LBB1_2 ; entry blt cr2, LBB1_2 ; entry LBB1_1: ; entry LBB1_1: ; entry fmr f2, f15 | fmr f2, f17 LBB1_2: ; entry LBB1_2: ; entry stfd f2, 128(r1) < blt cr2, LBB1_4 ; entry blt cr2, LBB1_4 ; entry LBB1_3: ; entry LBB1_3: ; entry fmr f1, f14 | fmr f1, f16 LBB1_4: ; entry LBB1_4: ; entry stfd f1, 136(r1) | lwz r0, 116(r1) ld r2, 128(r1) < std r2, 112(r1) < ld r2, 136(r1) < std r2, 120(r1) < lfd f2, 112(r1) < lfd f1, 120(r1) < lwz r0, 196(r1) < rlwinm r0, r0, 24, 0, 31 rlwinm r0, r0, 24, 0, 31 mtcrf 32, r0 mtcrf 32, r0 lfd f15, 200(r1) | lfd f17, 120(r1) lfd f14, 208(r1) | lfd f16, 128(r1) ld r30, 216(r1) | lfd f15, 136(r1) addi r1, r1, 224 | lfd f14, 144(r1) > ld r30, 152(r1) > addi r1, r1, 160 ld r0, 16(r1) ld r0, 16(r1) mtlr r0 mtlr r0 blr blr .globl _boo .globl _boo .align 4 .align 4 _boo: _boo: mflr r0 mflr r0 std r0, 16(r1) std r0, 16(r1) stdu r1, -144(r1) | stdu r1, -112(r1) stfd f2, 128(r1) < stfd f1, 136(r1) < ld r2, 128(r1) < std r2, 112(r1) < ld r2, 136(r1) < std r2, 120(r1) < lfd f2, 112(r1) < lfd f1, 120(r1) < bl L___fixunstfti$stub bl L___fixunstfti$stub addi r1, r1, 144 | addi r1, r1, 112 ld r0, 16(r1) ld r0, 16(r1) mtlr r0 mtlr r0 blr blr .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .align 4 .align 4 L___fixunstfti$stub: L___fixunstfti$stub: .indirect_symbol ___fixunstfti .indirect_symbol ___fixunstfti lis r11,ha16(L___fixunstfti$lazy_ptr) lis r11,ha16(L___fixunstfti$lazy_ptr) ldu r12,lo16(L___fixunstfti$lazy_ptr)(r11) ldu r12,lo16(L___fixunstfti$lazy_ptr)(r11) mtctr r12 mtctr r12 bctr bctr .lazy_symbol_pointer .lazy_symbol_pointer L___fixunstfti$lazy_ptr: L___fixunstfti$lazy_ptr: .indirect_symbol ___fixunstfti .indirect_symbol ___fixunstfti .quad dyld_stub_binding_helper .quad dyld_stub_binding_helper .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .align 4 .align 4 L___floattitf$stub: L___floattitf$stub: .indirect_symbol ___floattitf .indirect_symbol ___floattitf lis r11,ha16(L___floattitf$lazy_ptr) lis r11,ha16(L___floattitf$lazy_ptr) ldu r12,lo16(L___floattitf$lazy_ptr)(r11) ldu r12,lo16(L___floattitf$lazy_ptr)(r11) mtctr r12 mtctr r12 bctr bctr .lazy_symbol_pointer .lazy_symbol_pointer L___floattitf$lazy_ptr: L___floattitf$lazy_ptr: .indirect_symbol ___floattitf .indirect_symbol ___floattitf .quad dyld_stub_binding_helper .quad dyld_stub_binding_helper .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .section __TEXT,__symbol_stub1,symbol_stubs,pure_inst .align 4 .align 4 L___gcc_qadd$stub: L___gcc_qadd$stub: .indirect_symbol ___gcc_qadd .indirect_symbol ___gcc_qadd lis r11,ha16(L___gcc_qadd$lazy_ptr) lis r11,ha16(L___gcc_qadd$lazy_ptr) ldu r12,lo16(L___gcc_qadd$lazy_ptr)(r11) ldu r12,lo16(L___gcc_qadd$lazy_ptr)(r11) mtctr r12 mtctr r12 bctr bctr .lazy_symbol_pointer .lazy_symbol_pointer L___gcc_qadd$lazy_ptr: L___gcc_qadd$lazy_ptr: .indirect_symbol ___gcc_qadd .indirect_symbol ___gcc_qadd .quad dyld_stub_binding_helper .quad dyld_stub_binding_helper .subsections_via_symbols .subsections_via_symbols From sanjiv.gupta at microchip.com Wed Nov 26 04:53:52 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 26 Nov 2008 10:53:52 -0000 Subject: [llvm-commits] [llvm] r60098 - in /llvm/trunk/lib/Target/PIC16: PIC16AsmPrinter.cpp PIC16AsmPrinter.h PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrInfo.td Message-ID: <200811261053.mAQArqHW030535@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 26 04:53:50 2008 New Revision: 60098 URL: http://llvm.org/viewvc/llvm-project?rev=60098&view=rev Log: Emit declaration for globals and externs. Custom lower AND, OR, XOR bitwise operations. Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=60098&r1=60097&r2=60098&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Wed Nov 26 04:53:50 2008 @@ -86,7 +86,7 @@ O << '\n'; } else - O << "_" << CurrentFnName << ":\n"; + O << CurrentFnName << ":\n"; CurrentBankselLabelInBasicBlock = ""; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { @@ -141,15 +141,42 @@ // The processor should be passed to llc as in input and the header file // should be generated accordingly. O << "\t#include P16F1937.INC\n"; - + EmitExternsAndGlobals (M); EmitInitData (M); EmitUnInitData(M); EmitRomData(M); return Result; } -void PIC16AsmPrinter::EmitInitData (Module &M) -{ +void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) { + // Emit declarations for external functions. + O << "section.0" <<"\n"; + for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { + std::string Name = Mang->getValueName(I); + if (Name.compare("abort") == 0) + continue; + if (I->isDeclaration()) { + O << "\textern " <hasExternalLinkage()) { + O << "\tglobal " << Name << "\n"; + O << "\tglobal " << Name << ".retval\n"; + O << "\tglobal " << Name << ".args\n"; + } + } + // Emit declarations for external globals. + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; I++) { + std::string Name = Mang->getValueName(I); + if (I->isDeclaration()) + O << "\textern "<< Name << "\n"; + else if (I->getLinkage() == GlobalValue::CommonLinkage) + O << "\tglobal "<< Name << "\n"; + } +} +void PIC16AsmPrinter::EmitInitData (Module &M) { std::string iDataSection = "idata.#"; SwitchToDataSection(iDataSection.c_str()); for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); @@ -295,16 +322,26 @@ O << "\n"; std::string fDataSection = "fdata." + CurrentFnName + ".#"; SwitchToUDataSection(fDataSection.c_str(), F); - // Emit the label for data section of current function. - O << "_frame_" << CurrentFnName << ":" ; - O << "\n"; - + + //Emit function return value. + O << CurrentFnName << ".retval:\n"; + const Type *RetType = F->getReturnType(); + if (RetType->getTypeID() != Type::VoidTyID) { + unsigned RetSize = TD->getABITypeSize(RetType); + if (RetSize > 0) + O << CurrentFnName << ".retval" << " RES " << RetSize; + } + // Emit function arguments. + O << CurrentFnName << ".args:\n"; + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + std::string ArgName = Mang->getValueName(AI); + const Type *ArgTy = AI->getType(); + unsigned ArgSize = TD->getABITypeSize(ArgTy); + O << CurrentFnName << ".args." << ArgName << " RES " << ArgSize; + } // Emit the function variables. - if (F->hasExternalLinkage()) { - O << "\t" << "GLOBAL _frame_" << CurrentFnName << "\n"; - O << "\t" << "GLOBAL _" << CurrentFnName << "\n"; - } // In PIC16 all the function arguments and local variables are global. // Therefore to get the variable belonging to this function entire // global list will be traversed and variables belonging to this function Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h?rev=60098&r1=60097&r2=60098&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.h Wed Nov 26 04:53:50 2008 @@ -42,6 +42,7 @@ const GlobalValue *GV = NULL); bool printInstruction(const MachineInstr *MI); // definition autogenerated. bool printMachineInstruction(const MachineInstr *MI); + void EmitExternsAndGlobals (Module &M); void EmitInitData (Module &M); void EmitUnInitData (Module &M); void EmitRomData (Module &M); Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=60098&r1=60097&r2=60098&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed Nov 26 04:53:50 2008 @@ -55,6 +55,10 @@ setOperationAction(ISD::ADD, MVT::i8, Legal); setOperationAction(ISD::ADD, MVT::i16, Custom); + setOperationAction(ISD::OR, MVT::i8, Custom); + setOperationAction(ISD::AND, MVT::i8, Custom); + setOperationAction(ISD::XOR, MVT::i8, Custom); + setOperationAction(ISD::SHL, MVT::i16, Custom); setOperationAction(ISD::SHL, MVT::i32, Custom); @@ -532,6 +536,10 @@ return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo()); case ISD::SHL: return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo()); + case ISD::OR: + case ISD::AND: + case ISD::XOR: + return LowerBinOp(Op, DAG); } return SDValue(); } @@ -570,6 +578,21 @@ return Load.getValue(0); } +SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal Op to lower"); + + // Return the original Op if the one of the operands is already a load. + if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load + || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load) + return Op; + + // Put one value on stack. + SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG); + + return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal); +} + SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) { // We should have handled larger operands in type legalizer itself. assert (Op.getValueType() == MVT::i8 && "illegal addc to lower"); Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=60098&r1=60097&r2=60098&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Wed Nov 26 04:53:50 2008 @@ -64,6 +64,7 @@ SDValue LowerADDC(SDValue Op, SelectionDAG &DAG); SDValue LowerSUBE(SDValue Op, SelectionDAG &DAG); SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG); + SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG); SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=60098&r1=60097&r2=60098&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Wed Nov 26 04:53:50 2008 @@ -75,17 +75,44 @@ // Node to match a direct load operation. def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>; +// Nodes to match bitwise operatios. +def OR : SDNode<"ISD::OR", SDTI8BinOp>; +def XOR : SDNode<"ISD::XOR", SDTI8BinOp>; +def AND : SDNode<"ISD::AND", SDTI8BinOp>; //===----------------------------------------------------------------------===// // PIC16 Operand Definitions. //===----------------------------------------------------------------------===// def i8mem : Operand; +include "PIC16InstrFormats.td" +//===----------------------------------------------------------------------===// +// PIC16 Common Classes. +//===----------------------------------------------------------------------===// + +// W = W Op F : Load the value from F and do Op to W +class BinOpFW OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; +// F = F Op W : Load the value from F, do op with W and store in F +class BinOpWF OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; //===----------------------------------------------------------------------===// // PIC16 Instructions. //===----------------------------------------------------------------------===// -include "PIC16InstrFormats.td" // Pseudo-instructions. def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt), @@ -189,36 +216,29 @@ []>; //------------------------- +// Bitwise operations patterns +//-------------------------- +def OrFW : BinOpFW<0, "iorwf", OR>; +def XOrFW : BinOpFW<0, "xorwf", XOR>; +def AndFW : BinOpFW<0, "andwf", AND>; + +def OrWF : BinOpWF<0, "iorwf", OR>; +def XOrWF : BinOpWF<0, "xorwf", XOR>; +def AndWF : BinOpWF<0, "andwf", AND>; + +//------------------------- // Various add/sub patterns. //------------------------- -// W += [F] ; load from F and add the value to W. -class ADDFW OpCode, string OpcStr, SDNode OpNode>: - ByteFormat; + // let isTwoAddress = 1 in { -def addfw_1: ADDFW<0, "addwf", add>; -def addfw_2: ADDFW<0, "addwf", addc>; -def addfwc: ADDFW<0, "addwfc", adde>; // With Carry. +def addfw_1: BinOpFW<0, "addwf", add>; +def addfw_2: BinOpFW<0, "addwf", addc>; +def addfwc: BinOpFW<0, "addwfc", adde>; // With Carry. // } -// [F] += W ; add the value of W to [F]. -class ADDWF OpCode, string OpcStr, SDNode OpNode>: - ByteFormat; -def addwf_1: ADDWF<0, "addwf", add>; -def addwf_2: ADDWF<0, "addwf", addc>; -def addwfc: ADDWF<0, "addwfc", adde>; // With Carry. +def addwf_1: BinOpWF<0, "addwf", add>; +def addwf_2: BinOpWF<0, "addwf", addc>; +def addwfc: BinOpWF<0, "addwfc", adde>; // With Carry. // W -= [F] ; load from F and sub the value from W. class SUBFW OpCode, string OpcStr, SDNode OpNode>: From foldr at codedgers.com Wed Nov 26 04:55:45 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 26 Nov 2008 10:55:45 -0000 Subject: [llvm-commits] [llvm] r60099 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811261055.mAQAtjX3030604@zion.cs.uiuc.edu> Author: foldr Date: Wed Nov 26 04:55:45 2008 New Revision: 60099 URL: http://llvm.org/viewvc/llvm-project?rev=60099&view=rev Log: Small fix: the error message was incorrect in some cases. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60099&r1=60098&r2=60099&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Wed Nov 26 04:55:45 2008 @@ -228,11 +228,11 @@ if (other.Type != Type) throw "Conflicting definitions for the option " + Name + "!"; - if (Help == DefaultHelpString) + if (Help == other.Help || Help == DefaultHelpString) Help = other.Help; else if (other.Help != DefaultHelpString) { - llvm::cerr << "Warning: more than one help string defined for option " - + Name + "\n"; + llvm::cerr << "Warning: several different help strings" + " defined for option " + Name + "\n"; } Flags |= other.Flags; From foldr at codedgers.com Wed Nov 26 04:56:56 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 26 Nov 2008 10:56:56 -0000 Subject: [llvm-commits] [llvm] r60100 - /llvm/trunk/include/llvm/CompilerDriver/Tools.td Message-ID: <200811261056.mAQAuurU030654@zion.cs.uiuc.edu> Author: foldr Date: Wed Nov 26 04:56:56 2008 New Revision: 60100 URL: http://llvm.org/viewvc/llvm-project?rev=60100&view=rev Log: Refactor Tools.td to remove repetition. Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=60100&r1=60099&r2=60100&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Wed Nov 26 04:56:56 2008 @@ -11,20 +11,20 @@ // //===----------------------------------------------------------------------===// -def llvm_gcc_c : Tool< -[(in_language "c"), +class llvm_gcc_based : Tool< +[(in_language in_lang), (out_language "llvm-bitcode"), (output_suffix "bc"), (cmd_line (case (switch_on "E"), (case (not_empty "o"), - "llvm-gcc -E -x c++ $INFILE -o $OUTFILE", + !strconcat(cmd_prefix, " -E $INFILE -o $OUTFILE"), (default), - "llvm-gcc -E -x c++ $INFILE"), + !strconcat(cmd_prefix, " -E $INFILE")), (switch_on "fsyntax-only"), - "llvm-gcc -fsyntax-only -x c $INFILE", + !strconcat(cmd_prefix, " -fsyntax-only $INFILE"), (default), - "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm")), + !strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))), (switch_option "emit-llvm", (stop_compilation), (help "Emit LLVM intermediate files instead of native object files")), (switch_option "E", (stop_compilation), @@ -36,68 +36,10 @@ (sink) ]>; -def llvm_gcc_cpp : Tool< -[(in_language "c++"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (cmd_line (case - (switch_on "E"), - (case (not_empty "o"), - "llvm-g++ -E -x c++ $INFILE -o $OUTFILE", - (default), - "llvm-g++ -E -x c++ $INFILE"), - (switch_on "fsyntax-only"), - "llvm-g++ -fsyntax-only -x c++ $INFILE", - (default), - "llvm-g++ -c -x c++ $INFILE -o $OUTFILE -emit-llvm")), - (switch_option "emit-llvm", (stop_compilation)), - (switch_option "E", (stop_compilation)), - (switch_option "fsyntax-only", (stop_compilation)), - (parameter_list_option "include", (forward)), - (sink) -]>; - -def llvm_gcc_m : Tool< -[(in_language "objective-c"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (cmd_line (case - (switch_on "E"), - (case (not_empty "o"), - "llvm-gcc -E -x objective-c $INFILE -o $OUTFILE", - (default), - "llvm-gcc -E -x objective-c $INFILE"), - (switch_on "fsyntax-only"), - "llvm-gcc -fsyntax-only -x objective-c $INFILE", - (default), - "llvm-gcc -c -x objective-c $INFILE -o $OUTFILE -emit-llvm")), - (switch_option "emit-llvm", (stop_compilation)), - (switch_option "E", (stop_compilation)), - (switch_option "fsyntax-only", (stop_compilation)), - (parameter_list_option "include", (forward)), - (sink) -]>; - -def llvm_gcc_mxx : Tool< -[(in_language "objective-c++"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (cmd_line (case - (switch_on "E"), - (case (not_empty "o"), - "llvm-gcc -E -x objective-c++ $INFILE -o $OUTFILE", - (default), - "llvm-gcc -E -x objective-c++ $INFILE"), - (switch_on "fsyntax-only"), - "llvm-gcc -fsyntax-only -x objective-c++ $INFILE", - (default), - "llvm-gcc -c -x objective-c++ $INFILE -o $OUTFILE -emit-llvm")), - (switch_option "emit-llvm", (stop_compilation)), - (switch_option "E", (stop_compilation)), - (switch_option "fsyntax-only", (stop_compilation)), - (parameter_list_option "include", (forward)), - (sink) -]>; +def llvm_gcc_c : llvm_gcc_based<"llvm-gcc -x c", "c">; +def llvm_gcc_cpp : llvm_gcc_based<"llvm-g++ -x c++", "c++">; +def llvm_gcc_m : llvm_gcc_based<"llvm-gcc -x objective-c", "objective-c">; +def llvm_gcc_mxx : llvm_gcc_based<"llvm-gcc -x objective-c++", "objective-c++">; def opt : Tool< [(in_language "llvm-bitcode"), From foldr at codedgers.com Wed Nov 26 04:57:32 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 26 Nov 2008 10:57:32 -0000 Subject: [llvm-commits] [llvm] r60101 - /llvm/trunk/include/llvm/CompilerDriver/Tools.td Message-ID: <200811261057.mAQAvWL9030682@zion.cs.uiuc.edu> Author: foldr Date: Wed Nov 26 04:57:31 2008 New Revision: 60101 URL: http://llvm.org/viewvc/llvm-project?rev=60101&view=rev Log: Fix the -I option (llvmc -I dir1 -I dir2 didn't work). Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=60101&r1=60100&r2=60101&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Wed Nov 26 04:57:31 2008 @@ -33,6 +33,8 @@ (help "Stop after checking the input for syntax errors")), (parameter_list_option "include", (forward), (help "Include the named file prior to preprocessing")), + (prefix_list_option "I", (forward), + (help "Add a directory to include path")), (sink) ]>; From sanjiv.gupta at microchip.com Wed Nov 26 05:19:01 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Wed, 26 Nov 2008 11:19:01 -0000 Subject: [llvm-commits] [llvm] r60102 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811261119.mAQBJ1rD031388@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 26 05:19:00 2008 New Revision: 60102 URL: http://llvm.org/viewvc/llvm-project?rev=60102&view=rev Log: Allow custom lowering of ADDE/ADDC/SUBE/SUBC operations. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60102&r1=60101&r2=60102&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Nov 26 05:19:00 2008 @@ -3299,11 +3299,26 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); Tmp2 = LegalizeOp(Node->getOperand(1)); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); + Tmp3 = Result.getValue(0); + Tmp4 = Result.getValue(1); + + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: + break; + case TargetLowering::Custom: + Tmp1 = TLI.LowerOperation(Tmp3, DAG); + if (Tmp1.getNode() != NULL) { + Tmp3 = LegalizeOp(Tmp1);; + Tmp4 = LegalizeOp(Tmp1.getValue(1)); + } + break; + } // Since this produces two values, make sure to remember that we legalized // both of them. - AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); - AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); - return Result; + AddLegalizedOperand(SDValue(Node, 0), Tmp3); + AddLegalizedOperand(SDValue(Node, 1), Tmp4); + return Op.getResNo() ? Tmp4 : Tmp3; case ISD::ADDE: case ISD::SUBE: @@ -3311,11 +3326,26 @@ Tmp2 = LegalizeOp(Node->getOperand(1)); Tmp3 = LegalizeOp(Node->getOperand(2)); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); + Tmp3 = Result.getValue(0); + Tmp4 = Result.getValue(1); + + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: + break; + case TargetLowering::Custom: + Tmp1 = TLI.LowerOperation(Tmp3, DAG); + if (Tmp1.getNode() != NULL) { + Tmp3 = LegalizeOp(Tmp1);; + Tmp4 = LegalizeOp(Tmp1.getValue(1)); + } + break; + } // Since this produces two values, make sure to remember that we legalized // both of them. - AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); - AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); - return Result; + AddLegalizedOperand(SDValue(Node, 0), Tmp3); + AddLegalizedOperand(SDValue(Node, 1), Tmp4); + return Op.getResNo() ? Tmp4 : Tmp3; case ISD::BUILD_PAIR: { MVT PairTy = Node->getValueType(0); From nunoplopes at sapo.pt Wed Nov 26 07:10:41 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Wed, 26 Nov 2008 13:10:41 -0000 Subject: [llvm-commits] [llvm] r60104 - in /llvm/trunk/tools/llvmc: driver/ plugins/Base/ Message-ID: <200811261310.mAQDAfWc002708@zion.cs.uiuc.edu> Author: nlopes Date: Wed Nov 26 07:10:39 2008 New Revision: 60104 URL: http://llvm.org/viewvc/llvm-project?rev=60104&view=rev Log: ignore build dirs and generated files Modified: llvm/trunk/tools/llvmc/driver/ (props changed) llvm/trunk/tools/llvmc/plugins/Base/ (props changed) Propchange: llvm/trunk/tools/llvmc/driver/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Wed Nov 26 07:10:39 2008 @@ -0,0 +1,3 @@ +Debug +Release +Release-Asserts Propchange: llvm/trunk/tools/llvmc/plugins/Base/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Wed Nov 26 07:10:39 2008 @@ -0,0 +1,4 @@ +AutoGenerated.inc +Debug +Release +Release-Asserts From foldr at codedgers.com Wed Nov 26 07:40:12 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 26 Nov 2008 13:40:12 -0000 Subject: [llvm-commits] [llvm] r60105 - /llvm/trunk/docs/CommandGuide/llvmc.pod Message-ID: <200811261340.mAQDeCvV003733@zion.cs.uiuc.edu> Author: foldr Date: Wed Nov 26 07:40:08 2008 New Revision: 60105 URL: http://llvm.org/viewvc/llvm-project?rev=60105&view=rev Log: Describe some more options in the man page. Modified: llvm/trunk/docs/CommandGuide/llvmc.pod Modified: llvm/trunk/docs/CommandGuide/llvmc.pod URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvmc.pod?rev=60105&r1=60104&r2=60105&view=diff ============================================================================== --- llvm/trunk/docs/CommandGuide/llvmc.pod (original) +++ llvm/trunk/docs/CommandGuide/llvmc.pod Wed Nov 26 07:40:08 2008 @@ -17,15 +17,69 @@ =head1 OPTIONS +=head2 Built-in Options + +LLVMC has some built-in options that can't be overridden in the +configuration libraries. + =over +=item B<-o> I + +Output file name. + +=item B<-x> I + +Specify the language of the following input files until the next B<-x> +option. + +=item B<-load> I + +Load the specified plugin DLL. Example: +S<-load $LLVM_DIR/Release/lib/LLVMCSimple.so>. + +=item B<-v> or B<--verbose> + +Enable verbose mode, i.e. print out all executed commands. + +=item B<--view-graph> + +Show a graphical representation of the compilation graph. Requires +that you have I and I programs installed. Hidden option, +useful for debugging. + +=item B<--write-graph> + +Write a I file in the current directory with +the compilation graph description in the Graphviz format. Hidden +option, useful for debugging. + +=item B<--save-temps> + +Write temporary files to the current directory and do not delete them +on exit. Hidden option, useful for debugging. + =item B<--help> -Print a summary of command line options. +Print a summary of command-line options and exit. -=item B<-o> I +=item B<--help-hidden> + +Print a summary of command-line options and exit. Print help even for +options intended for developers. + +=item B<--version> -Specify the output file to be I. +Print version information and exit. + +=back + +=head2 Control Options + +By default, LLVMC is built with some standard configuration libraries +that define the following options: + +=over =item B<-I> I @@ -52,11 +106,11 @@ =head1 EXIT STATUS -If B succeeds, it will exit with 0. Otherwise, if an error -occurs, it will exit with a non-zero value. If one of the compilation -tools returns a non-zero status, pending actions will be discarded and -B will return the same result code as the failing compilation -tool. +If B succeeds, it will exit with code 0. Otherwise, if an +error occurs, it will exit with a non-zero value. If one of the +compilation tools returns a non-zero status, pending actions will be +discarded and B will return the same result code as the failing +compilation tool. =head1 SEE ALSO From baldrick at free.fr Wed Nov 26 10:44:38 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Nov 2008 16:44:38 -0000 Subject: [llvm-commits] [llvm] r60108 - /llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll Message-ID: <200811261644.mAQGicMj010964@zion.cs.uiuc.edu> Author: baldrick Date: Wed Nov 26 10:44:30 2008 New Revision: 60108 URL: http://llvm.org/viewvc/llvm-project?rev=60108&view=rev Log: Check that running the DAG combiner between type and operation legalization does something useful. Modified: llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll Modified: llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll?rev=60108&r1=60107&r2=60108&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/int-fp-conv-0.ll Wed Nov 26 10:44:30 2008 @@ -1,3 +1,4 @@ +; RUN: llvm-as < %s | llc -march=ppc64 -debug |& not grep store ; RUN: llvm-as < %s | llc -march=ppc64 > %t ; RUN: grep __floattitf %t ; RUN: grep __fixunstfti %t From baldrick at free.fr Wed Nov 26 10:52:14 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 Nov 2008 17:52:14 +0100 Subject: [llvm-commits] [llvm] r60102 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: <200811261119.mAQBJ1rD031388@zion.cs.uiuc.edu> References: <200811261119.mAQBJ1rD031388@zion.cs.uiuc.edu> Message-ID: <200811261752.14441.baldrick@free.fr> Hi, > + if (Tmp1.getNode() != NULL) { > + Tmp3 = LegalizeOp(Tmp1);; two semicolons at end of line. > + if (Tmp1.getNode() != NULL) { > + Tmp3 = LegalizeOp(Tmp1);; Likewise. Ciao, Duncan. From dalej at apple.com Wed Nov 26 11:45:19 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Nov 2008 09:45:19 -0800 Subject: [llvm-commits] [llvm] r60042 - in /llvm/trunk: lib/Support/APFloat.cpp test/Transforms/IndVarsSimplify/2008-11-25-APFloatAssert.ll In-Reply-To: <200811260918.22327.baldrick@free.fr> References: <200811251900.mAPJ0Twi019026@zion.cs.uiuc.edu> <0C8DAB63-4282-41E0-B6C9-3D8478701BA5@apple.com> <200811260918.22327.baldrick@free.fr> Message-ID: <214C006A-8234-4868-A4C9-11FEBEC2C384@apple.com> On Nov 26, 2008, at 12:18 AMPST, Duncan Sands wrote: >> Sure, how about adding a new opUnsupportedOp flag? opInvalidOp means >> something to IEEE, opUnsupportedOp could mean "we don't know how to >> fold this" which is different. > > Why not teach APFloat to do arithmetic on PPCF128? Sure, that's the most aesthetic solution. It's not straightforward (the existing algorithms aren't usable) and there seems to be no demand for it. It's on the list of "things we might get around to someday." From evan.cheng at apple.com Wed Nov 26 12:00:01 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Nov 2008 18:00:01 -0000 Subject: [llvm-commits] [llvm] r60110 - /llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Message-ID: <200811261800.mAQI01YQ013648@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 26 12:00:00 2008 New Revision: 60110 URL: http://llvm.org/viewvc/llvm-project?rev=60110&view=rev Log: Cosmetic. Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp?rev=60110&r1=60109&r2=60110&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Wed Nov 26 12:00:00 2008 @@ -33,9 +33,9 @@ // Register the targets static RegisterTarget -X("pic16", "PIC16 14-bit (experimental)."); +X("pic16", "PIC16 14-bit [experimental]."); static RegisterTarget -Y("cooper", "PIC16 Cooper (experimental)."); +Y("cooper", "PIC16 Cooper [experimental]."); // PIC16TargetMachine - Traditional PIC16 Machine. PIC16TargetMachine::PIC16TargetMachine(const Module &M, const std::string &FS, From dpatel at apple.com Wed Nov 26 12:13:11 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 Nov 2008 18:13:11 -0000 Subject: [llvm-commits] [llvm] r60111 - /llvm/trunk/include/llvm/Analysis/LoopPass.h Message-ID: <200811261813.mAQIDBFr014021@zion.cs.uiuc.edu> Author: dpatel Date: Wed Nov 26 12:13:11 2008 New Revision: 60111 URL: http://llvm.org/viewvc/llvm-project?rev=60111&view=rev Log: Fix typo. Modified: llvm/trunk/include/llvm/Analysis/LoopPass.h Modified: llvm/trunk/include/llvm/Analysis/LoopPass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopPass.h?rev=60111&r1=60110&r2=60111&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopPass.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopPass.h Wed Nov 26 12:13:11 2008 @@ -123,7 +123,7 @@ // Delete loop from the loop queue and loop nest (LoopInfo). void deleteLoopFromQueue(Loop *L); - // Inset loop into the loop nest(LoopInfo) and loop queue(LQ). + // Insert loop into the loop nest(LoopInfo) and loop queue(LQ). void insertLoop(Loop *L, Loop *ParentLoop); // Reoptimize this loop. LPPassManager will re-insert this loop into the From isanbard at gmail.com Wed Nov 26 13:07:41 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 19:07:41 -0000 Subject: [llvm-commits] [llvm] r60112 - /llvm/trunk/docs/LangRef.html Message-ID: <200811261907.mAQJ7gox015818@zion.cs.uiuc.edu> Author: void Date: Wed Nov 26 13:07:40 2008 New Revision: 60112 URL: http://llvm.org/viewvc/llvm-project?rev=60112&view=rev Log: Update to explain how ssp and sspreq attributes override each other. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=60112&r1=60111&r2=60112&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Nov 26 13:07:40 2008 @@ -992,16 +992,25 @@ state.
    ssp
    -
    This attribute indicates that the function should emit a stack smashing +

    This attribute indicates that the function should emit a stack smashing protector. It is in the form of a "canary"—a random value placed on the stack before the local variables that's checked upon return from the function to see if it has been overwritten. A heuristic is used to determine if a function -needs stack protectors or not.

    +needs stack protectors or not.

    -
    ssp-req
    -
    This attribute indicates that the function should always emit a +

    If a function that has an ssp attribute is inlined into a function +that doesn't have an ssp attribute, then the resulting function will +have an ssp attribute.

    + +
    sspreq
    +

    This attribute indicates that the function should always emit a stack smashing protector. This overrides the ssp -function attribute.

    +function attribute.

    + +

    If a function that has an sspreq attribute is inlined into a +function that doesn't have an sspreq attribute or which has +an ssp attribute, then the resulting function will have +an sspreq attribute.

    From isanbard at gmail.com Wed Nov 26 13:19:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 19:19:05 -0000 Subject: [llvm-commits] [llvm] r60113 - /llvm/trunk/docs/LangRef.html Message-ID: <200811261919.mAQJJ535016278@zion.cs.uiuc.edu> Author: void Date: Wed Nov 26 13:19:05 2008 New Revision: 60113 URL: http://llvm.org/viewvc/llvm-project?rev=60113&view=rev Log: Small formatting change. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=60113&r1=60112&r2=60113&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Nov 26 13:19:05 2008 @@ -992,20 +992,20 @@ state.
    ssp
    -

    This attribute indicates that the function should emit a stack smashing +

    This attribute indicates that the function should emit a stack smashing protector. It is in the form of a "canary"—a random value placed on the stack before the local variables that's checked upon return from the function to see if it has been overwritten. A heuristic is used to determine if a function -needs stack protectors or not.

    +needs stack protectors or not.

    If a function that has an ssp attribute is inlined into a function that doesn't have an ssp attribute, then the resulting function will have an ssp attribute.

    sspreq
    -

    This attribute indicates that the function should always emit a +

    This attribute indicates that the function should always emit a stack smashing protector. This overrides the ssp -function attribute.

    +function attribute.

    If a function that has an sspreq attribute is inlined into a function that doesn't have an sspreq attribute or which has From sabre at nondot.org Wed Nov 26 16:16:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 22:16:46 -0000 Subject: [llvm-commits] [llvm] r60120 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/X86/isel-sink3.ll Message-ID: <200811262216.mAQMGlIh022704@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 26 16:16:44 2008 New Revision: 60120 URL: http://llvm.org/viewvc/llvm-project?rev=60120&view=rev Log: Turn on my codegen prepare heuristic by default. It doesn't affect performance in most cases on the Grawp tester, but does speed some things up (like shootout/hash by 15%). This also doesn't impact compile time in a noticable way on the Grawp tester. It also, of course, gets the testcase it was designed for right :) Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp llvm/trunk/test/CodeGen/X86/isel-sink3.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60120&r1=60119&r2=60120&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Nov 26 16:16:44 2008 @@ -1025,10 +1025,6 @@ -#include "llvm/Support/CommandLine.h" -cl::opt ENABLECRAZYHACK("enable-smarter-addr-folding", cl::Hidden); - - /// IsProfitableToFoldIntoAddressingMode - It is possible for the addressing /// mode of the machine to fold the specified instruction into a load or store /// that ultimately uses it. However, the specified instruction has multiple @@ -1053,7 +1049,7 @@ bool AddressingModeMatcher:: IsProfitableToFoldIntoAddressingMode(Instruction *I, ExtAddrMode &AMBefore, ExtAddrMode &AMAfter) { - if (IgnoreProfitability || !ENABLECRAZYHACK) return true; + if (IgnoreProfitability) return true; // AMBefore is the addressing mode before this instruction was folded into it, // and AMAfter is the addressing mode after the instruction was folded. Get Modified: llvm/trunk/test/CodeGen/X86/isel-sink3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/isel-sink3.ll?rev=60120&r1=60119&r2=60120&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/isel-sink3.ll (original) +++ llvm/trunk/test/CodeGen/X86/isel-sink3.ll Wed Nov 26 16:16:44 2008 @@ -1,5 +1,5 @@ -; RUN: llvm-as < %s | llc -enable-smarter-addr-folding | grep {addl.(%eax), %ecx} -; RUN: llvm-as < %s | llc -enable-smarter-addr-folding | not grep leal +; RUN: llvm-as < %s | llc | grep {addl.(%eax), %ecx} +; RUN: llvm-as < %s | llc | not grep leal ; this should not sink %1 into bb1, that would increase reg pressure. ; rdar://6399178 From sabre at nondot.org Wed Nov 26 16:18:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 26 Nov 2008 22:18:09 -0000 Subject: [llvm-commits] [test-suite] r60121 - /test-suite/trunk/Makefile.programs Message-ID: <200811262218.mAQMI9R8022754@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 26 16:18:09 2008 New Revision: 60121 URL: http://llvm.org/viewvc/llvm-project?rev=60121&view=rev Log: switch llc-beta back. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=60121&r1=60120&r2=60121&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Nov 26 16:18:09 2008 @@ -226,8 +226,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -enable-smarter-addr-folding -#-disable-post-RA-scheduler=false +LLCBETAOPTION := -disable-post-RA-scheduler=false #-machine-licm #-fast-isel #-aggressive-remat From isanbard at gmail.com Wed Nov 26 16:37:40 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 22:37:40 -0000 Subject: [llvm-commits] [llvm] r60123 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86InstrInfo.cpp X86InstrInfo.h X86InstrInfo.td Message-ID: <200811262237.mAQMbeHO023468@zion.cs.uiuc.edu> Author: void Date: Wed Nov 26 16:37:40 2008 New Revision: 60123 URL: http://llvm.org/viewvc/llvm-project?rev=60123&view=rev Log: Generate something sensible for an [SU]ADDO op when the overflow/carry flag is the conditional for the BRCOND statement. For instance, it will generate: addl %eax, %ecx jo LOF instead of addl %eax, %ecx ; About 10 instructions to compare the signs of LHS, RHS, and sum. jl LOF Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60123&r1=60122&r2=60123&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Nov 26 16:37:40 2008 @@ -6150,6 +6150,26 @@ SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy) { + SDNode *N = Op.getNode(); + + for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { + SDNode *UseNode = *I; + + if (UseNode->getOpcode() == ISD::BRCOND) { + // Lower a branch on the overflow/carry flag into a "JO"/"JC" + // instruction. Convert the addition into an actual addition, not just a + // pseudo node. + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + + SDValue Ops[] = { UseNode->getOperand(2), UseNode->getOperand(0) }; + DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : X86::JC, + MVT::Other, Ops, 2); + return Sum; + } + } + return SDValue(); } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60123&r1=60122&r2=60123&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Nov 26 16:37:40 2008 @@ -1382,6 +1382,8 @@ case X86::JNP: return X86::COND_NP; case X86::JO: return X86::COND_O; case X86::JNO: return X86::COND_NO; + case X86::JC: return X86::COND_C; + case X86::JNC: return X86::COND_NC; } } @@ -1404,6 +1406,8 @@ case X86::COND_NP: return X86::JNP; case X86::COND_O: return X86::JO; case X86::COND_NO: return X86::JNO; + case X86::COND_C: return X86::JC; + case X86::COND_NC: return X86::JNC; } } @@ -1428,6 +1432,8 @@ case X86::COND_NP: return X86::COND_P; case X86::COND_O: return X86::COND_NO; case X86::COND_NO: return X86::COND_O; + case X86::COND_C: return X86::COND_NC; + case X86::COND_NC: return X86::COND_C; } } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=60123&r1=60122&r2=60123&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Wed Nov 26 16:37:40 2008 @@ -41,9 +41,11 @@ COND_NO = 10, COND_NP = 11, COND_NS = 12, - COND_O = 13, - COND_P = 14, - COND_S = 15, + COND_NC = 13, + COND_O = 14, + COND_P = 15, + COND_S = 16, + COND_C = 17, // Artificial condition codes. These are used by AnalyzeBranch // to indicate a block terminated with two conditional branches to Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60123&r1=60122&r2=60123&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Nov 26 16:37:40 2008 @@ -235,9 +235,11 @@ def X86_COND_NO : PatLeaf<(i8 10)>; def X86_COND_NP : PatLeaf<(i8 11)>; def X86_COND_NS : PatLeaf<(i8 12)>; -def X86_COND_O : PatLeaf<(i8 13)>; -def X86_COND_P : PatLeaf<(i8 14)>; -def X86_COND_S : PatLeaf<(i8 15)>; +def X86_COND_NC : PatLeaf<(i8 13)>; +def X86_COND_O : PatLeaf<(i8 14)>; +def X86_COND_P : PatLeaf<(i8 15)>; +def X86_COND_S : PatLeaf<(i8 16)>; +def X86_COND_C : PatLeaf<(i8 17)>; def i16immSExt8 : PatLeaf<(i16 imm), [{ // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit @@ -449,6 +451,10 @@ [(X86brcond bb:$dst, X86_COND_O, EFLAGS)]>, TB; def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst", [(X86brcond bb:$dst, X86_COND_NO, EFLAGS)]>, TB; +def JC : IBr<0x82, (ins brtarget:$dst), "jc\t$dst", + [(X86brcond bb:$dst, X86_COND_C, EFLAGS)]>, TB; +def JNC : IBr<0x83, (ins brtarget:$dst), "jnc\t$dst", + [(X86brcond bb:$dst, X86_COND_NC, EFLAGS)]>, TB; } // Uses = [EFLAGS] //===----------------------------------------------------------------------===// From isanbard at gmail.com Wed Nov 26 16:42:19 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 Nov 2008 22:42:19 -0000 Subject: [llvm-commits] [llvm] r60125 - /llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Message-ID: <200811262242.mAQMgJo0023640@zion.cs.uiuc.edu> Author: void Date: Wed Nov 26 16:42:19 2008 New Revision: 60125 URL: http://llvm.org/viewvc/llvm-project?rev=60125&view=rev Log: Add x86-specific test for add-with-overflow intrinsics. Added: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Added: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60125&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (added) +++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Wed Nov 26 16:42:19 2008 @@ -0,0 +1,41 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1 +; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1 + + at ok = internal constant [4 x i8] c"%d\0A\00" + at no = internal constant [4 x i8] c"no\0A\00" + +define i1 @func1(i32 %v1, i32 %v2) nounwind { +entry: + %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %overflow, label %normal + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true + +overflow: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false +} + +define i1 @func2(i32 %v1, i32 %v2) nounwind { +entry: + %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %overflow, label %normal + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true + +overflow: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false +} + +declare i32 @printf(i8*, ...) nounwind +declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) +declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) From evan.cheng at apple.com Wed Nov 26 16:57:42 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 Nov 2008 14:57:42 -0800 Subject: [llvm-commits] [llvm] r60123 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86InstrInfo.cpp X86InstrInfo.h X86InstrInfo.td In-Reply-To: <200811262237.mAQMbeHO023468@zion.cs.uiuc.edu> References: <200811262237.mAQMbeHO023468@zion.cs.uiuc.edu> Message-ID: Bill, I don't think this is the right approach. Details in private email. Evan On Nov 26, 2008, at 2:37 PM, Bill Wendling wrote: > Author: void > Date: Wed Nov 26 16:37:40 2008 > New Revision: 60123 > > URL: http://llvm.org/viewvc/llvm-project?rev=60123&view=rev > Log: > Generate something sensible for an [SU]ADDO op when the overflow/ > carry flag is > the conditional for the BRCOND statement. For instance, it will > generate: > > addl %eax, %ecx > jo LOF > > instead of > > addl %eax, %ecx > ; About 10 instructions to compare the signs of LHS, RHS, and sum. > jl LOF > > > Modified: > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrInfo.h > llvm/trunk/lib/Target/X86/X86InstrInfo.td > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60123&r1=60122&r2=60123&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Nov 26 > 16:37:40 2008 > @@ -6150,6 +6150,26 @@ > > SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, > ISD::NodeType NTy) { > + SDNode *N = Op.getNode(); > + > + for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); > I != E; ++I) { > + SDNode *UseNode = *I; > + > + if (UseNode->getOpcode() == ISD::BRCOND) { > + // Lower a branch on the overflow/carry flag into a "JO"/"JC" > + // instruction. Convert the addition into an actual addition, > not just a > + // pseudo node. > + SDValue LHS = N->getOperand(0); > + SDValue RHS = N->getOperand(1); > + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, > RHS); > + > + SDValue Ops[] = { UseNode->getOperand(2), UseNode- > >getOperand(0) }; > + DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : > X86::JC, > + MVT::Other, Ops, 2); > + return Sum; > + } > + } > + > return SDValue(); > } > > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60123&r1=60122&r2=60123&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Nov 26 16:37:40 > 2008 > @@ -1382,6 +1382,8 @@ > case X86::JNP: return X86::COND_NP; > case X86::JO: return X86::COND_O; > case X86::JNO: return X86::COND_NO; > + case X86::JC: return X86::COND_C; > + case X86::JNC: return X86::COND_NC; > } > } > > @@ -1404,6 +1406,8 @@ > case X86::COND_NP: return X86::JNP; > case X86::COND_O: return X86::JO; > case X86::COND_NO: return X86::JNO; > + case X86::COND_C: return X86::JC; > + case X86::COND_NC: return X86::JNC; > } > } > > @@ -1428,6 +1432,8 @@ > case X86::COND_NP: return X86::COND_P; > case X86::COND_O: return X86::COND_NO; > case X86::COND_NO: return X86::COND_O; > + case X86::COND_C: return X86::COND_NC; > + case X86::COND_NC: return X86::COND_C; > } > } > > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=60123&r1=60122&r2=60123&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Wed Nov 26 16:37:40 2008 > @@ -41,9 +41,11 @@ > COND_NO = 10, > COND_NP = 11, > COND_NS = 12, > - COND_O = 13, > - COND_P = 14, > - COND_S = 15, > + COND_NC = 13, > + COND_O = 14, > + COND_P = 15, > + COND_S = 16, > + COND_C = 17, > > // Artificial condition codes. These are used by AnalyzeBranch > // to indicate a block terminated with two conditional branches to > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60123&r1=60122&r2=60123&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Nov 26 16:37:40 2008 > @@ -235,9 +235,11 @@ > def X86_COND_NO : PatLeaf<(i8 10)>; > def X86_COND_NP : PatLeaf<(i8 11)>; > def X86_COND_NS : PatLeaf<(i8 12)>; > -def X86_COND_O : PatLeaf<(i8 13)>; > -def X86_COND_P : PatLeaf<(i8 14)>; > -def X86_COND_S : PatLeaf<(i8 15)>; > +def X86_COND_NC : PatLeaf<(i8 13)>; > +def X86_COND_O : PatLeaf<(i8 14)>; > +def X86_COND_P : PatLeaf<(i8 15)>; > +def X86_COND_S : PatLeaf<(i8 16)>; > +def X86_COND_C : PatLeaf<(i8 17)>; > > def i16immSExt8 : PatLeaf<(i16 imm), [{ > // i16immSExt8 predicate - True if the 16-bit immediate fits in a > 8-bit > @@ -449,6 +451,10 @@ > [(X86brcond bb:$dst, X86_COND_O, EFLAGS)]>, TB; > def JNO : IBr<0x81, (ins brtarget:$dst), "jno\t$dst", > [(X86brcond bb:$dst, X86_COND_NO, EFLAGS)]>, TB; > +def JC : IBr<0x82, (ins brtarget:$dst), "jc\t$dst", > + [(X86brcond bb:$dst, X86_COND_C, EFLAGS)]>, TB; > +def JNC : IBr<0x83, (ins brtarget:$dst), "jnc\t$dst", > + [(X86brcond bb:$dst, X86_COND_NC, EFLAGS)]>, TB; > } // Uses = [EFLAGS] > > // > = > = > = > ----------------------------------------------------------------------= > ==// > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From foldr at codedgers.com Wed Nov 26 16:59:45 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Wed, 26 Nov 2008 22:59:45 -0000 Subject: [llvm-commits] [llvm] r60127 - in /llvm/trunk: include/llvm/CompilerDriver/CompilationGraph.h tools/llvmc/doc/LLVMC-Reference.rst tools/llvmc/driver/CompilationGraph.cpp Message-ID: <200811262259.mAQMxjRg024185@zion.cs.uiuc.edu> Author: foldr Date: Wed Nov 26 16:59:45 2008 New Revision: 60127 URL: http://llvm.org/viewvc/llvm-project?rev=60127&view=rev Log: Disallow multiple edges. Modified: llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h?rev=60127&r1=60126&r2=60127&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h Wed Nov 26 16:59:45 2008 @@ -83,8 +83,7 @@ /// AddEdge - Add an outward edge. Takes ownership of the provided /// Edge object. - void AddEdge(Edge* E) - { OutEdges.push_back(llvm::IntrusiveRefCntPtr(E)); } + void AddEdge(Edge* E); // Inward edge counter. Used to implement topological sort. void IncrInEdges() { ++InEdges; } Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=60127&r1=60126&r2=60127&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Wed Nov 26 16:59:45 2008 @@ -63,7 +63,7 @@ ================== LLVMC has some built-in options that can't be overridden in the -configuration files: +configuration libraries: * ``-o FILE`` - Output file name. @@ -154,7 +154,7 @@ make this work, however, that plugin should be loaded first. To achieve this, the concept of plugin priority was introduced. By default, every plugin has priority zero; to specify the priority -explicitly, put the following line in your ``.td`` file:: +explicitly, put the following line in your plugin's TableGen file:: def Priority : PluginPriority<$PRIORITY_VALUE>; # Where PRIORITY_VALUE is some integer > 0 @@ -220,7 +220,9 @@ true in the ``case`` expression. It is also possible to provide an integer parameter to ``inc_weight`` and ``dec_weight`` - in this case, the weight is increased (or decreased) by the provided value instead -of the default 2. +of the default 2. It is also possible to change the default weight of +an optional edge by using the ``default`` clause of the ``case`` +construct. When passing an input file through the graph, LLVMC picks the edge with the maximum weight. To avoid ambiguity, there should be only one @@ -228,6 +230,12 @@ which gets a special treatment - there you are allowed to specify one default edge *per language*). +When multiple plugins are loaded, their compilation graphs are merged +together. Since multiple edges are not allowed, an edge defined in +several plugins will be replaced by the definition from the plugin +that was loaded last. Plugin load order can be controlled by using the +plugin priority feature described above. + To get a visual representation of the compilation graph (useful for debugging), run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for this to work properly. Modified: llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp?rev=60127&r1=60126&r2=60127&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp (original) +++ llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Wed Nov 26 16:59:45 2008 @@ -79,6 +79,20 @@ } +void Node::AddEdge(Edge* Edg) { + // If there already was an edge between two nodes, modify it instead + // of adding a new edge. + const std::string& ToolName = Edg->ToolName(); + for (container_type::iterator B = OutEdges.begin(), E = OutEdges.end(); + B != E; ++B) { + if ((*B)->ToolName() == ToolName) { + llvm::IntrusiveRefCntPtr(Edg).swap(*B); + return; + } + } + OutEdges.push_back(llvm::IntrusiveRefCntPtr(Edg)); +} + CompilationGraph::CompilationGraph() { NodesMap["root"] = Node(this); } From dalej at apple.com Wed Nov 26 17:29:51 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 Nov 2008 23:29:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60129 - /llvm-gcc-4.2/trunk/gcc/config/i386/i386.md Message-ID: <200811262329.mAQNTpGH025280@zion.cs.uiuc.edu> Author: johannes Date: Wed Nov 26 17:29:51 2008 New Revision: 60129 URL: http://llvm.org/viewvc/llvm-project?rev=60129&view=rev Log: Refix warning, with local comments so maybe it will stay fixed. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.md Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.md URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.md?rev=60129&r1=60128&r2=60129&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.md (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.md Wed Nov 26 17:29:51 2008 @@ -19254,7 +19254,8 @@ (define_insn "x86_movdicc_0_m1_rex64" [(set (match_operand:DI 0 "register_operand" "=r") - (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") +;; LLVM LOCAL fix warning + (if_then_else:DI (match_operand:DI 1 "ix86_carry_flag_operator" "") (const_int -1) (const_int 0))) (clobber (reg:CC FLAGS_REG))] @@ -19297,7 +19298,8 @@ (define_insn "x86_movsicc_0_m1" [(set (match_operand:SI 0 "register_operand" "=r") - (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") +;; LLVM LOCAL fix warning + (if_then_else:SI (match_operand:SI 1 "ix86_carry_flag_operator" "") (const_int -1) (const_int 0))) (clobber (reg:CC FLAGS_REG))] From kremenek at apple.com Wed Nov 26 18:17:25 2008 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 27 Nov 2008 00:17:25 -0000 Subject: [llvm-commits] [llvm] r60134 - /llvm/trunk/include/llvm/ADT/StringMap.h Message-ID: <200811270017.mAR0HQhM026937@zion.cs.uiuc.edu> Author: kremenek Date: Wed Nov 26 18:17:25 2008 New Revision: 60134 URL: http://llvm.org/viewvc/llvm-project?rev=60134&view=rev Log: Add typedef to StringMapEntry. Modified: llvm/trunk/include/llvm/ADT/StringMap.h Modified: llvm/trunk/include/llvm/ADT/StringMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=60134&r1=60133&r2=60134&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringMap.h (original) +++ llvm/trunk/include/llvm/ADT/StringMap.h Wed Nov 26 18:17:25 2008 @@ -420,16 +420,18 @@ protected: StringMapImpl::ItemBucket *Ptr; public: + typedef StringMapEntry value_type; + explicit StringMapConstIterator(StringMapImpl::ItemBucket *Bucket, bool NoAdvance = false) : Ptr(Bucket) { if (!NoAdvance) AdvancePastEmptyBuckets(); } - const StringMapEntry &operator*() const { + const value_type &operator*() const { return *static_cast*>(Ptr->Item); } - const StringMapEntry *operator->() const { + const value_type *operator->() const { return static_cast*>(Ptr->Item); } From evan.cheng at apple.com Wed Nov 26 18:37:06 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 Nov 2008 00:37:06 -0000 Subject: [llvm-commits] [llvm] r60135 - /llvm/trunk/test/CodeGen/X86/fold-load.ll Message-ID: <200811270037.mAR0b6ag027545@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 26 18:37:06 2008 New Revision: 60135 URL: http://llvm.org/viewvc/llvm-project?rev=60135&view=rev Log: Add -march=x86. Modified: llvm/trunk/test/CodeGen/X86/fold-load.ll Modified: llvm/trunk/test/CodeGen/X86/fold-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-load.ll?rev=60135&r1=60134&r2=60135&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-load.ll (original) +++ llvm/trunk/test/CodeGen/X86/fold-load.ll Wed Nov 26 18:37:06 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc +; RUN: llvm-as < %s | llc -march=x86 %struct._obstack_chunk = type { i8*, %struct._obstack_chunk*, [4 x i8] } %struct.obstack = type { i32, %struct._obstack_chunk*, i8*, i8*, i8*, i32, i32, %struct._obstack_chunk* (...)*, void (...)*, i8*, i8 } @stmt_obstack = external global %struct.obstack ; <%struct.obstack*> [#uses=1] From dalej at apple.com Wed Nov 26 18:43:21 2008 From: dalej at apple.com (Dale Johannesen) Date: Thu, 27 Nov 2008 00:43:21 -0000 Subject: [llvm-commits] [llvm] r60137 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200811270043.mAR0hMra027758@zion.cs.uiuc.edu> Author: johannes Date: Wed Nov 26 18:43:21 2008 New Revision: 60137 URL: http://llvm.org/viewvc/llvm-project?rev=60137&view=rev Log: Add a missing case in visitADD. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=60137&r1=60136&r2=60137&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Nov 26 18:43:21 2008 @@ -1010,6 +1010,9 @@ // fold (A+(B-A)) -> B if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1)) return N1.getOperand(0); + // fold ((B-A)+A) -> B + if (N0.getOpcode() == ISD::SUB && N1 == N0.getOperand(1)) + return N0.getOperand(0); if (!VT.isVector() && SimplifyDemandedBits(SDValue(N, 0))) return SDValue(N, 0); From evan.cheng at apple.com Wed Nov 26 18:49:46 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 Nov 2008 00:49:46 -0000 Subject: [llvm-commits] [llvm] r60139 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGISel.h lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/fold-imm.ll test/CodeGen/X86/isel-sink3.ll utils/TableGen/DAGISelEmitter.cpp Message-ID: <200811270049.mAR0nkf6028005@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 26 18:49:46 2008 New Revision: 60139 URL: http://llvm.org/viewvc/llvm-project?rev=60139&view=rev Log: On x86 favors folding short immediate into some arithmetic operations (e.g. add, and, xor, etc.) because materializing an immediate in a register is expensive in turns of code size. e.g. movl 4(%esp), %eax addl $4, %eax is 2 bytes shorter than movl $4, %eax addl 4(%esp), %eax Added: llvm/trunk/test/CodeGen/X86/fold-imm.ll Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/test/CodeGen/X86/isel-sink3.ll llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=60139&r1=60138&r2=60139&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Wed Nov 26 18:49:46 2008 @@ -80,9 +80,11 @@ return true; } - /// CanBeFoldedBy - Returns true if the specific operand node N of U can be - /// folded during instruction selection that starts at Root? - virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const { + /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of + /// U can be folded during instruction selection that starts at Root and + /// folding N is profitable. + virtual + bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const { return true; } Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=60139&r1=60138&r2=60139&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Nov 26 18:49:46 2008 @@ -141,7 +141,8 @@ virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF); - virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const; + virtual + bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const; // Include the pieces autogenerated from the target description. #include "X86GenDAGISel.inc" @@ -280,7 +281,8 @@ /// isNonImmUse - Start searching from Root up the DAG to check is Def can /// be reached. Return true if that's the case. However, ignore direct uses /// by ImmedUse (which would be U in the example illustrated in -/// CanBeFoldedBy) and by Root (which can happen in the store case). +/// IsLegalAndProfitableToFold) and by Root (which can happen in the store +/// case). /// FIXME: to be really generic, we should allow direct use by any node /// that is being folded. But realisticly since we only fold loads which /// have one non-chain use, we only need to watch out for load/op/store @@ -294,9 +296,42 @@ } -bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const { +bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, + SDNode *Root) const { if (Fast) return false; + if (U == Root) + switch (U->getOpcode()) { + default: break; + case ISD::ADD: + case ISD::ADDC: + case ISD::ADDE: + case ISD::AND: + case ISD::OR: + case ISD::XOR: { + // If the other operand is a 8-bit immediate we should fold the immediate + // instead. This reduces code size. + // e.g. + // movl 4(%esp), %eax + // addl $4, %eax + // vs. + // movl $4, %eax + // addl 4(%esp), %eax + // The former is 2 bytes shorter. In case where the increment is 1, then + // the saving can be 4 bytes (by using incl %eax). + ConstantSDNode *Imm = dyn_cast(U->getOperand(1)); + if (Imm) { + if (U->getValueType(0) == MVT::i64) { + if ((int32_t)Imm->getZExtValue() == (int64_t)Imm->getZExtValue()) + return false; + } else { + if ((int8_t)Imm->getZExtValue() == (int64_t)Imm->getZExtValue()) + return false; + } + } + } + } + // If Root use can somehow reach N through a path that that doesn't contain // U then folding N would create a cycle. e.g. In the following // diagram, Root can reach N through X. If N is folded into into Root, then @@ -999,7 +1034,7 @@ if (ISD::isNON_EXTLoad(InChain.getNode()) && InChain.getValue(0).hasOneUse() && N.hasOneUse() && - CanBeFoldedBy(N.getNode(), Pred.getNode(), Op.getNode())) { + IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op.getNode())) { LoadSDNode *LD = cast(InChain); if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp)) return false; @@ -1086,7 +1121,7 @@ SDValue &Index, SDValue &Disp) { if (ISD::isNON_EXTLoad(N.getNode()) && N.hasOneUse() && - CanBeFoldedBy(N.getNode(), P.getNode(), P.getNode())) + IsLegalAndProfitableToFold(N.getNode(), P.getNode(), P.getNode())) return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp); return false; } Added: llvm/trunk/test/CodeGen/X86/fold-imm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-imm.ll?rev=60139&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-imm.ll (added) +++ llvm/trunk/test/CodeGen/X86/fold-imm.ll Wed Nov 26 18:49:46 2008 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep inc +; RUN: llvm-as < %s | llc -march=x86 | grep add | grep 4 + +define i32 @test(i32 %X) nounwind { +entry: + %0 = add i32 %X, 1 + ret i32 %0 +} + +define i32 @test2(i32 %X) nounwind { +entry: + %0 = add i32 %X, 4 + ret i32 %0 +} Modified: llvm/trunk/test/CodeGen/X86/isel-sink3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/isel-sink3.ll?rev=60139&r1=60138&r2=60139&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/isel-sink3.ll (original) +++ llvm/trunk/test/CodeGen/X86/isel-sink3.ll Wed Nov 26 18:49:46 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc | grep {addl.(%eax), %ecx} +; RUN: llvm-as < %s | llc | grep {addl.\$4, %ecx} ; RUN: llvm-as < %s | llc | not grep leal ; this should not sink %1 into bb1, that would increase reg pressure. Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=60139&r1=60138&r2=60139&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Wed Nov 26 18:49:46 2008 @@ -522,8 +522,8 @@ if (NeedCheck) { std::string ParentName(RootName.begin(), RootName.end()-1); - emitCheck("CanBeFoldedBy(" + RootName + ".getNode(), " + ParentName + - ".getNode(), N.getNode())"); + emitCheck("IsLegalAndProfitableToFold(" + RootName + + ".getNode(), " + ParentName + ".getNode(), N.getNode())"); } } } From evan.cheng at apple.com Wed Nov 26 19:16:00 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 Nov 2008 01:16:00 -0000 Subject: [llvm-commits] [llvm] r60141 - in /llvm/trunk: lib/CodeGen/LoopAligner.cpp test/CodeGen/X86/avoid-loop-align.ll Message-ID: <200811270116.mAR1G0kp028827@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 26 19:16:00 2008 New Revision: 60141 URL: http://llvm.org/viewvc/llvm-project?rev=60141&view=rev Log: Avoid inserting noop's in the middle of a loop. Added: llvm/trunk/test/CodeGen/X86/avoid-loop-align.ll Modified: llvm/trunk/lib/CodeGen/LoopAligner.cpp Modified: llvm/trunk/lib/CodeGen/LoopAligner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LoopAligner.cpp?rev=60141&r1=60140&r2=60141&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LoopAligner.cpp (original) +++ llvm/trunk/lib/CodeGen/LoopAligner.cpp Wed Nov 26 19:16:00 2008 @@ -64,8 +64,14 @@ for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = I; - if (MLI->isLoopHeader(MBB)) + if (MLI->isLoopHeader(MBB)) { + MachineBasicBlock *PredBB = prior(I); + if (MLI->getLoopFor(MBB) == MLI->getLoopFor(PredBB)) + // If previously BB is in the same loop, don't align this BB. We want + // to prevent adding noop's inside a loop. + continue; MBB->setAlignment(Align); + } } return true; Added: llvm/trunk/test/CodeGen/X86/avoid-loop-align.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avoid-loop-align.ll?rev=60141&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/avoid-loop-align.ll (added) +++ llvm/trunk/test/CodeGen/X86/avoid-loop-align.ll Wed Nov 26 19:16:00 2008 @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | grep align | count 1 + + at A = common global [100 x i32] zeroinitializer, align 32 ; <[100 x i32]*> [#uses=1] + +define i8* @test(i8* %Q, i32* %L) nounwind { +entry: + %tmp = tail call i32 (...)* @foo() nounwind ; [#uses=2] + %tmp1 = inttoptr i32 %tmp to i8* ; [#uses=1] + br label %bb1 + +bb: ; preds = %bb1, %bb1 + %indvar.next = add i32 %P.0.rec, 1 ; [#uses=1] + br label %bb1 + +bb1: ; preds = %bb, %entry + %P.0.rec = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=2] + %P.0 = getelementptr i8* %tmp1, i32 %P.0.rec ; [#uses=3] + %tmp2 = load i8* %P.0, align 1 ; [#uses=1] + switch i8 %tmp2, label %bb4 [ + i8 12, label %bb + i8 42, label %bb + ] + +bb4: ; preds = %bb1 + %tmp3 = ptrtoint i8* %P.0 to i32 ; [#uses=1] + %tmp4 = sub i32 %tmp3, %tmp ; [#uses=1] + %tmp5 = getelementptr [100 x i32]* @A, i32 0, i32 %tmp4 ; [#uses=1] + store i32 4, i32* %tmp5, align 4 + ret i8* %P.0 +} + +declare i32 @foo(...) From echristo at apple.com Wed Nov 26 19:22:16 2008 From: echristo at apple.com (Eric Christopher) Date: Wed, 26 Nov 2008 17:22:16 -0800 Subject: [llvm-commits] [llvm] r60141 - in /llvm/trunk: lib/CodeGen/LoopAligner.cpp test/CodeGen/X86/avoid-loop-align.ll In-Reply-To: <200811270116.mAR1G0kp028827@zion.cs.uiuc.edu> References: <200811270116.mAR1G0kp028827@zion.cs.uiuc.edu> Message-ID: <4ED9E30C-C4C1-4E86-ADF2-F3B41B119999@apple.com> On Nov 26, 2008, at 5:16 PM, Evan Cheng wrote: > Avoid inserting noop's in the middle of a loop. Out of curiosity... why since we're trying to align the loop? -eric From evan.cheng at apple.com Wed Nov 26 20:29:26 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 Nov 2008 02:29:26 -0000 Subject: [llvm-commits] [llvm] r60145 - /llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Message-ID: <200811270229.mAR2TQra031210@zion.cs.uiuc.edu> Author: evancheng Date: Wed Nov 26 20:29:25 2008 New Revision: 60145 URL: http://llvm.org/viewvc/llvm-project?rev=60145&view=rev Log: Eliminate a compile time warning. Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=60145&r1=60144&r2=60145&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed Nov 26 20:29:25 2008 @@ -478,7 +478,7 @@ SDVTList Tys; SDValue ShfCom; // Shift Component - Lo component should be shifted SDValue RotCom; // Rotate Component- Hi component should be rotated - PIC16ISD::NodeType ShfNode, RotNode; + PIC16ISD::NodeType ShfNode = PIC16ISD::Dummy, RotNode = PIC16ISD::Dummy; // Currently handling Constant shift only if (Amt.getOpcode() != ISD::Constant) From sabre at nondot.org Wed Nov 26 23:07:54 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 05:07:54 -0000 Subject: [llvm-commits] [llvm] r60148 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/thread-loads.ll Message-ID: <200811270507.mAR57tCW004036@zion.cs.uiuc.edu> Author: lattner Date: Wed Nov 26 23:07:53 2008 New Revision: 60148 URL: http://llvm.org/viewvc/llvm-project?rev=60148&view=rev Log: Make jump threading substantially more powerful, in the following ways: 1. Make it fold blocks separated by an unconditional branch. This enables jump threading to see a broader scope. 2. Make jump threading able to eliminate locally redundant loads when they feed the branch condition of a block. This frequently occurs due to reg2mem running. 3. Make jump threading able to eliminate *partially redundant* loads when they feed the branch condition of a block. This is common in code with lots of loads and stores like C++ code and 255.vortex. This implements thread-loads.ll and rdar://6402033. Per the fixme's, several pieces of this should be moved into Transforms/Utils. Added: llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60148&r1=60147&r2=60148&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Nov 26 23:07:53 2008 @@ -22,6 +22,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/SmallPtrSet.h" using namespace llvm; STATISTIC(NumThreads, "Number of jumps threaded"); @@ -62,6 +63,8 @@ bool ProcessJumpOnPHI(PHINode *PN); bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd); bool ProcessBranchOnCompare(CmpInst *Cmp, BasicBlock *BB); + + bool SimplifyPartiallyRedundantLoad(LoadInst *LI); }; } @@ -153,10 +156,50 @@ return Size; } +/// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its +/// predecessor is known to have one successor (DestBB!). Eliminate the edge +/// between them, moving the instructions in the predecessor into DestBB and +/// deleting the predecessor block. +/// +/// FIXME: Move to TransformUtils to share with simplifycfg and codegenprepare. +static void MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB) { + // If BB has single-entry PHI nodes, fold them. + while (PHINode *PN = dyn_cast(DestBB->begin())) { + Value *NewVal = PN->getIncomingValue(0); + // Replace self referencing PHI with undef, it must be dead. + if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); + PN->replaceAllUsesWith(NewVal); + PN->eraseFromParent(); + } + + BasicBlock *PredBB = DestBB->getSinglePredecessor(); + assert(PredBB && "Block doesn't have a single predecessor!"); + + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + + // Anything that branched to PredBB now branches to DestBB. + PredBB->replaceAllUsesWith(DestBB); + + // Nuke BB. + PredBB->eraseFromParent(); +} + /// ThreadBlock - If there are any predecessors whose control can be threaded /// through to a successor, transform them now. bool JumpThreading::ThreadBlock(BasicBlock *BB) { + // If this block has a single predecessor, and if that pred has a single + // successor, merge the blocks. This encourages recursive jump threading + // because now the condition in this block can be threaded through + // predecessors of our predecessor block. + if (BasicBlock *SinglePred = BB->getSinglePredecessor()) + if (SinglePred->getTerminator()->getNumSuccessors() == 1) { + MergeBasicBlockIntoOnlyPred(BB); + return true; + } + // See if this block ends with a branch or switch. If so, see if the // condition is a phi node. If so, and if an entry of the phi node is a // constant, we can thread the block. @@ -208,10 +251,240 @@ isa(CondCmp->getOperand(1)) && ProcessBranchOnCompare(CondCmp, BB)) return true; + + // Check for some cases that are worth simplifying. Right now we want to look + // for loads that are used by a switch or by the condition for the branch. If + // we see one, check to see if it's partially redundant. If so, insert a PHI + // which can then be used to thread the values. + // + // This is particularly important because reg2mem inserts loads and stores all + // over the place, and this blocks jump threading if we don't zap them. + Value *SimplifyValue = Condition; + if (CmpInst *CondCmp = dyn_cast(SimplifyValue)) + if (isa(CondCmp->getOperand(1))) + SimplifyValue = CondCmp->getOperand(0); + + if (LoadInst *LI = dyn_cast(SimplifyValue)) + if (SimplifyPartiallyRedundantLoad(LI)) + return true; + + // TODO: If we have: "br (X > 0)" and we have a predecessor where we know + // "(X == 4)" thread through this block. return false; } + +/// FindAvailableLoadedValue - Scan backwards from ScanFrom checking to see if +/// we have the value at the memory address *Ptr locally available within a +/// small number of instructions. If the value is available, return it. +/// +/// If not, return the iterator for the last validated instruction that the +/// value would be live through. If we scanned the entire block, ScanFrom would +/// be left at begin(). +/// +/// FIXME: Move this to transform utils and use from +/// InstCombiner::visitLoadInst. It would also be nice to optionally take AA so +/// that GVN could do this. +static Value *FindAvailableLoadedValue(Value *Ptr, + BasicBlock *ScanBB, + BasicBlock::iterator &ScanFrom) { + + unsigned NumToScan = 6; + while (ScanFrom != ScanBB->begin()) { + // Don't scan huge blocks. + if (--NumToScan == 0) return 0; + + Instruction *Inst = --ScanFrom; + + // If this is a load of Ptr, the loaded value is available. + if (LoadInst *LI = dyn_cast(Inst)) + if (LI->getOperand(0) == Ptr) + return LI; + + if (StoreInst *SI = dyn_cast(Inst)) { + // If this is a store through Ptr, the value is available! + if (SI->getOperand(1) == Ptr) + return SI->getOperand(0); + + // If Ptr is an alloca and this is a store to a different alloca, ignore + // the store. This is a trivial form of alias analysis that is important + // for reg2mem'd code. + if ((isa(Ptr) || isa(Ptr)) && + (isa(SI->getOperand(1)) || + isa(SI->getOperand(1)))) + continue; + + // Otherwise the store that may or may not alias the pointer, bail out. + ++ScanFrom; + return 0; + } + + + // If this is some other instruction that may clobber Ptr, bail out. + if (Inst->mayWriteToMemory()) { + // May modify the pointer, bail out. + ++ScanFrom; + return 0; + } + } + + // Got to the start of the block, we didn't find it, but are done for this + // block. + return 0; +} + + +/// SimplifyPartiallyRedundantLoad - If LI is an obviously partially redundant +/// load instruction, eliminate it by replacing it with a PHI node. This is an +/// important optimization that encourages jump threading, and needs to be run +/// interlaced with other jump threading tasks. +bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) { + // Don't hack volatile loads. + if (LI->isVolatile()) return false; + + // If the load is defined in a block with exactly one predecessor, it can't be + // partially redundant. + BasicBlock *LoadBB = LI->getParent(); + if (LoadBB->getSinglePredecessor()) + return false; + + Value *LoadedPtr = LI->getOperand(0); + + // If the loaded operand is defined in the LoadBB, it can't be available. + // FIXME: Could do PHI translation, that would be fun :) + if (Instruction *PtrOp = dyn_cast(LoadedPtr)) + if (PtrOp->getParent() == LoadBB) + return false; + + // Scan a few instructions up from the load, to see if it is obviously live at + // the entry to its block. + BasicBlock::iterator BBIt = LI; + + if (Value *AvailableVal = FindAvailableLoadedValue(LoadedPtr, LoadBB, BBIt)) { + // If the value if the load is locally available within the block, just use + // it. This frequently occurs for reg2mem'd allocas. + //cerr << "LOAD ELIMINATED:\n" << *BBIt << *LI << "\n"; + LI->replaceAllUsesWith(AvailableVal); + LI->eraseFromParent(); + return true; + } + + // Otherwise, if we scanned the whole block and got to the top of the block, + // we know the block is locally transparent to the load. If not, something + // might clobber its value. + if (BBIt != LoadBB->begin()) + return false; + + + SmallPtrSet PredsScanned; + typedef SmallVector, 8> AvailablePredsTy; + AvailablePredsTy AvailablePreds; + BasicBlock *OneUnavailablePred = 0; + + // If we got here, the loaded value is transparent through to the start of the + // block. Check to see if it is available in any of the predecessor blocks. + for (pred_iterator PI = pred_begin(LoadBB), PE = pred_end(LoadBB); + PI != PE; ++PI) { + BasicBlock *PredBB = *PI; + + // If we already scanned this predecessor, skip it. + if (!PredsScanned.insert(PredBB)) + continue; + + // Scan the predecessor to see if the value is available in the pred. + BBIt = PredBB->end(); + Value *PredAvailable = FindAvailableLoadedValue(LoadedPtr, PredBB, BBIt); + if (!PredAvailable) { + OneUnavailablePred = PredBB; + continue; + } + + // If so, this load is partially redundant. Remember this info so that we + // can create a PHI node. + AvailablePreds.push_back(std::make_pair(PredBB, PredAvailable)); + } + + // If the loaded value isn't available in any predecessor, it isn't partially + // redundant. + if (AvailablePreds.empty()) return false; + + // Okay, the loaded value is available in at least one (and maybe all!) + // predecessors. If the value is unavailable in more than one unique + // predecessor, we want to insert a merge block for those common predecessors. + // This ensures that we only have to insert one reload, thus not increasing + // code size. + BasicBlock *UnavailablePred = 0; + + // If there is exactly one predecessor where the value is unavailable, the + // already computed 'OneUnavailablePred' block is it. If it ends in an + // unconditional branch, we know that it isn't a critical edge. + if (PredsScanned.size() == AvailablePreds.size()+1 && + OneUnavailablePred->getTerminator()->getNumSuccessors() == 1) { + UnavailablePred = OneUnavailablePred; + } else if (PredsScanned.size() != AvailablePreds.size()) { + // Otherwise, we had multiple unavailable predecessors or we had a critical + // edge from the one. + SmallVector PredsToSplit; + SmallPtrSet AvailablePredSet; + + for (unsigned i = 0, e = AvailablePreds.size(); i != e; ++i) + AvailablePredSet.insert(AvailablePreds[i].first); + + // Add all the unavailable predecessors to the PredsToSplit list. + for (pred_iterator PI = pred_begin(LoadBB), PE = pred_end(LoadBB); + PI != PE; ++PI) + if (!AvailablePredSet.count(*PI)) + PredsToSplit.push_back(*PI); + + // Split them out to their own block. + UnavailablePred = + SplitBlockPredecessors(LoadBB, &PredsToSplit[0], PredsToSplit.size(), + "thread-split", this); + } + + // If the value isn't available in all predecessors, then there will be + // exactly one where it isn't available. Insert a load on that edge and add + // it to the AvailablePreds list. + if (UnavailablePred) { + assert(UnavailablePred->getTerminator()->getNumSuccessors() == 1 && + "Can't handle critical edge here!"); + Value *NewVal = new LoadInst(LoadedPtr, LI->getName()+".pr", + UnavailablePred->getTerminator()); + AvailablePreds.push_back(std::make_pair(UnavailablePred, NewVal)); + } + + // Now we know that each predecessor of this block has a value in + // AvailablePreds, sort them for efficient access as we're walking the preds. + std::sort(AvailablePreds.begin(), AvailablePreds.end()); + + // Create a PHI node at the start of the block for the PRE'd load value. + PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin()); + PN->takeName(LI); + + // Insert new entries into the PHI for each predecessor. A single block may + // have multiple entries here. + for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); PI != E; + ++PI) { + AvailablePredsTy::iterator I = + std::lower_bound(AvailablePreds.begin(), AvailablePreds.end(), + std::make_pair(*PI, (Value*)0)); + + assert(I != AvailablePreds.end() && I->first == *PI && + "Didn't find entry for predecessor!"); + + PN->addIncoming(I->second, I->first); + } + + //cerr << "PRE: " << *LI << *PN << "\n"; + + LI->replaceAllUsesWith(PN); + LI->eraseFromParent(); + + return true; +} + + /// ProcessJumpOnPHI - We have a conditional branch of switch on a PHI node in /// the current block. See if there are any simplifications we can do based on /// inputs to the phi node. Added: llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll?rev=60148&view=auto ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll (added) +++ llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll Wed Nov 26 23:07:53 2008 @@ -0,0 +1,34 @@ +; RUN: llvm-as < %s | opt -jump-threading -mem2reg -simplifycfg | llvm-dis | grep {ret i32 1} +; rdar://6402033 + +; Test that we can thread through the block with the partially redundant load (%2). +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i32 @foo(i32* %P) nounwind { +entry: + %0 = tail call i32 (...)* @f1() nounwind ; [#uses=1] + %1 = icmp eq i32 %0, 0 ; [#uses=1] + br i1 %1, label %bb1, label %bb + +bb: ; preds = %entry + store i32 42, i32* %P, align 4 + br label %bb1 + +bb1: ; preds = %entry, %bb + %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] ; [#uses=2] + %2 = load i32* %P, align 4 ; [#uses=1] + %3 = icmp sgt i32 %2, 36 ; [#uses=1] + br i1 %3, label %bb3, label %bb2 + +bb2: ; preds = %bb1 + %4 = tail call i32 (...)* @f2() nounwind ; [#uses=0] + ret i32 %res.0 + +bb3: ; preds = %bb1 + ret i32 %res.0 +} + +declare i32 @f1(...) + +declare i32 @f2(...) From sanjiv.gupta at microchip.com Wed Nov 26 23:58:04 2008 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Thu, 27 Nov 2008 05:58:04 -0000 Subject: [llvm-commits] [llvm] r60149 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200811270558.mAR5w4hx005735@zion.cs.uiuc.edu> Author: sgupta Date: Wed Nov 26 23:58:04 2008 New Revision: 60149 URL: http://llvm.org/viewvc/llvm-project?rev=60149&view=rev Log: Removing redundant semicolons. No functionality change. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60149&r1=60148&r2=60149&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Nov 26 23:58:04 2008 @@ -3309,7 +3309,7 @@ case TargetLowering::Custom: Tmp1 = TLI.LowerOperation(Tmp3, DAG); if (Tmp1.getNode() != NULL) { - Tmp3 = LegalizeOp(Tmp1);; + Tmp3 = LegalizeOp(Tmp1); Tmp4 = LegalizeOp(Tmp1.getValue(1)); } break; @@ -3336,7 +3336,7 @@ case TargetLowering::Custom: Tmp1 = TLI.LowerOperation(Tmp3, DAG); if (Tmp1.getNode() != NULL) { - Tmp3 = LegalizeOp(Tmp1);; + Tmp3 = LegalizeOp(Tmp1); Tmp4 = LegalizeOp(Tmp1.getValue(1)); } break; From brukman+llvm at gmail.com Thu Nov 27 00:41:21 2008 From: brukman+llvm at gmail.com (Misha Brukman) Date: Thu, 27 Nov 2008 06:41:21 -0000 Subject: [llvm-commits] [llvm] r60153 - /llvm/trunk/docs/LangRef.html Message-ID: <200811270641.mAR6fLTF007131@zion.cs.uiuc.edu> Author: brukman Date: Thu Nov 27 00:41:20 2008 New Revision: 60153 URL: http://llvm.org/viewvc/llvm-project?rev=60153&view=rev Log: Fixed HTML closing tag, cleaned up some spacing. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=60153&r1=60152&r2=60153&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Thu Nov 27 00:41:20 2008 @@ -1406,8 +1406,8 @@ {i32, i32} (i32) - A function taking an i32>, returning two - i32 values as an aggregate of type { i32, i32 } + A function taking an i32, returning two + i32 values as an aggregate of type { i32, i32 } From brukman+llvm at gmail.com Thu Nov 27 01:01:53 2008 From: brukman+llvm at gmail.com (Misha Brukman) Date: Thu, 27 Nov 2008 07:01:53 -0000 Subject: [llvm-commits] [nightly-test-server] r60154 - /nightly-test-server/trunk/index.php Message-ID: <200811270701.mAR71rYE007785@zion.cs.uiuc.edu> Author: brukman Date: Thu Nov 27 01:01:53 2008 New Revision: 60154 URL: http://llvm.org/viewvc/llvm-project?rev=60154&view=rev Log: Changed the target large-format LOC graph dimensions from 800x600 to 900x500, mostly to test the website auto-updater. Modified: nightly-test-server/trunk/index.php Modified: nightly-test-server/trunk/index.php URL: http://llvm.org/viewvc/llvm-project/nightly-test-server/trunk/index.php?rev=60154&r1=60153&r2=60154&view=diff ============================================================================== --- nightly-test-server/trunk/index.php (original) +++ nightly-test-server/trunk/index.php Thu Nov 27 01:01:53 2008 @@ -21,7 +21,7 @@ Lines of code graph

    \n"; +print "

    Lines of code graph

    \n"; /* * the following lists the tests in the last 24 hours From brukman+llvm at gmail.com Thu Nov 27 01:10:16 2008 From: brukman+llvm at gmail.com (Misha Brukman) Date: Thu, 27 Nov 2008 07:10:16 -0000 Subject: [llvm-commits] [nightly-test-server] r60155 - /nightly-test-server/trunk/index.php Message-ID: <200811270710.mAR7AGve008341@zion.cs.uiuc.edu> Author: brukman Date: Thu Nov 27 01:10:15 2008 New Revision: 60155 URL: http://llvm.org/viewvc/llvm-project?rev=60155&view=rev Log: Reverting the large LOC graph back to 800x600 to test the website auto-updater. Modified: nightly-test-server/trunk/index.php Modified: nightly-test-server/trunk/index.php URL: http://llvm.org/viewvc/llvm-project/nightly-test-server/trunk/index.php?rev=60155&r1=60154&r2=60155&view=diff ============================================================================== --- nightly-test-server/trunk/index.php (original) +++ nightly-test-server/trunk/index.php Thu Nov 27 01:10:15 2008 @@ -21,7 +21,7 @@ Lines of code graph

    \n"; +print "

    Lines of code graph

    \n"; /* * the following lists the tests in the last 24 hours From isanbard at gmail.com Thu Nov 27 01:18:35 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 27 Nov 2008 07:18:35 -0000 Subject: [llvm-commits] [llvm] r60156 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200811270718.mAR7IZ0Y008587@zion.cs.uiuc.edu> Author: void Date: Thu Nov 27 01:18:35 2008 New Revision: 60156 URL: http://llvm.org/viewvc/llvm-project?rev=60156&view=rev Log: Comment out code that isn't entirely correct. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60156&r1=60155&r2=60156&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Nov 27 01:18:35 2008 @@ -6150,6 +6150,8 @@ SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy) { +#if 0 + // FIXME: Lowering XADDO should use BRCOND as well. SDNode *N = Op.getNode(); for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { @@ -6169,7 +6171,7 @@ return Sum; } } - +#endif return SDValue(); } From sabre at nondot.org Thu Nov 27 01:20:04 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 07:20:04 -0000 Subject: [llvm-commits] [llvm] r60157 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200811270720.mAR7K44r008650@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 01:20:04 2008 New Revision: 60157 URL: http://llvm.org/viewvc/llvm-project?rev=60157&view=rev Log: rename ThreadBlock to ProcessBlock, since it does other things than just simple threading. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60157&r1=60156&r2=60157&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Nov 27 01:20:04 2008 @@ -56,7 +56,7 @@ JumpThreading() : FunctionPass(&ID) {} bool runOnFunction(Function &F); - bool ThreadBlock(BasicBlock *BB); + bool ProcessBlock(BasicBlock *BB); void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB); BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal); @@ -85,7 +85,7 @@ AnotherIteration = false; bool Changed = false; for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - while (ThreadBlock(I)) + while (ProcessBlock(I)) Changed = true; AnotherIteration = Changed; EverChanged |= Changed; @@ -187,9 +187,9 @@ } -/// ThreadBlock - If there are any predecessors whose control can be threaded +/// ProcessBlock - If there are any predecessors whose control can be threaded /// through to a successor, transform them now. -bool JumpThreading::ThreadBlock(BasicBlock *BB) { +bool JumpThreading::ProcessBlock(BasicBlock *BB) { // If this block has a single predecessor, and if that pred has a single // successor, merge the blocks. This encourages recursive jump threading // because now the condition in this block can be threaded through From isanbard at gmail.com Thu Nov 27 01:20:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 27 Nov 2008 07:20:05 -0000 Subject: [llvm-commits] [llvm] r60158 - /llvm/tags/Apple/llvmCore-2083/ Message-ID: <200811270720.mAR7K58A008661@zion.cs.uiuc.edu> Author: void Date: Thu Nov 27 01:20:04 2008 New Revision: 60158 URL: http://llvm.org/viewvc/llvm-project?rev=60158&view=rev Log: Creating llvmCore-2083 branch Added: llvm/tags/Apple/llvmCore-2083/ - copied from r60156, llvm/trunk/ From isanbard at gmail.com Thu Nov 27 01:20:12 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 27 Nov 2008 07:20:12 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60159 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2083/ Message-ID: <200811270720.mAR7KCDR008672@zion.cs.uiuc.edu> Author: void Date: Thu Nov 27 01:20:11 2008 New Revision: 60159 URL: http://llvm.org/viewvc/llvm-project?rev=60159&view=rev Log: Creating llvmgcc42-2083 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2083/ - copied from r60158, llvm-gcc-4.2/trunk/ From isanbard at gmail.com Thu Nov 27 01:34:10 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 27 Nov 2008 07:34:10 -0000 Subject: [llvm-commits] [llvm] r60161 - /llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Message-ID: <200811270734.mAR7YAMP009101@zion.cs.uiuc.edu> Author: void Date: Thu Nov 27 01:34:10 2008 New Revision: 60161 URL: http://llvm.org/viewvc/llvm-project?rev=60161&view=rev Log: XFAil test due to reverting of patch. Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60161&r1=60160&r2=60161&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (original) +++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Thu Nov 27 01:34:10 2008 @@ -1,5 +1,6 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1 ; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1 +; XFAIL: * @ok = internal constant [4 x i8] c"%d\0A\00" @no = internal constant [4 x i8] c"no\0A\00" From sabre at nondot.org Thu Nov 27 01:43:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 07:43:12 -0000 Subject: [llvm-commits] [llvm] r60162 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Scalar/JumpThreading.cpp lib/Transforms/Utils/Local.cpp Message-ID: <200811270743.mAR7hDUZ009406@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 01:43:12 2008 New Revision: 60162 URL: http://llvm.org/viewvc/llvm-project?rev=60162&view=rev Log: move MergeBasicBlockIntoOnlyPred to Transforms/Utils. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=60162&r1=60161&r2=60162&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Nov 27 01:43:12 2008 @@ -62,6 +62,14 @@ // Control Flow Graph Restructuring... // +/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its +/// predecessor is known to have one successor (BB!). Eliminate the edge +/// between them, moving the instructions in the predecessor into BB. This +/// deletes the predecessor block. +/// +void MergeBasicBlockIntoOnlyPred(BasicBlock *BB); + + /// SimplifyCFG - This function is used to do simplification of a CFG. For /// example, it adjusts branches to branches to eliminate the extra hop, it /// eliminates unreachable basic blocks, and does other "peephole" optimization Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60162&r1=60161&r2=60162&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Nov 27 01:43:12 2008 @@ -156,37 +156,6 @@ return Size; } -/// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its -/// predecessor is known to have one successor (DestBB!). Eliminate the edge -/// between them, moving the instructions in the predecessor into DestBB and -/// deleting the predecessor block. -/// -/// FIXME: Move to TransformUtils to share with simplifycfg and codegenprepare. -static void MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB) { - // If BB has single-entry PHI nodes, fold them. - while (PHINode *PN = dyn_cast(DestBB->begin())) { - Value *NewVal = PN->getIncomingValue(0); - // Replace self referencing PHI with undef, it must be dead. - if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); - PN->replaceAllUsesWith(NewVal); - PN->eraseFromParent(); - } - - BasicBlock *PredBB = DestBB->getSinglePredecessor(); - assert(PredBB && "Block doesn't have a single predecessor!"); - - // Splice all the instructions from PredBB to DestBB. - PredBB->getTerminator()->eraseFromParent(); - DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); - - // Anything that branched to PredBB now branches to DestBB. - PredBB->replaceAllUsesWith(DestBB); - - // Nuke BB. - PredBB->eraseFromParent(); -} - - /// ProcessBlock - If there are any predecessors whose control can be threaded /// through to a successor, transform them now. bool JumpThreading::ProcessBlock(BasicBlock *BB) { Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60162&r1=60161&r2=60162&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 01:43:12 2008 @@ -200,3 +200,36 @@ } return false; } + +//===----------------------------------------------------------------------===// +// Control Flow Graph Restructuring... +// + +/// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its +/// predecessor is known to have one successor (DestBB!). Eliminate the edge +/// between them, moving the instructions in the predecessor into DestBB and +/// deleting the predecessor block. +/// +void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB) { + // If BB has single-entry PHI nodes, fold them. + while (PHINode *PN = dyn_cast(DestBB->begin())) { + Value *NewVal = PN->getIncomingValue(0); + // Replace self referencing PHI with undef, it must be dead. + if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); + PN->replaceAllUsesWith(NewVal); + PN->eraseFromParent(); + } + + BasicBlock *PredBB = DestBB->getSinglePredecessor(); + assert(PredBB && "Block doesn't have a single predecessor!"); + + // Splice all the instructions from PredBB to DestBB. + PredBB->getTerminator()->eraseFromParent(); + DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList()); + + // Anything that branched to PredBB now branches to DestBB. + PredBB->replaceAllUsesWith(DestBB); + + // Nuke BB. + PredBB->eraseFromParent(); +} From sabre at nondot.org Thu Nov 27 01:54:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 07:54:12 -0000 Subject: [llvm-commits] [llvm] r60163 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811270754.mAR7sClP009729@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 01:54:12 2008 New Revision: 60163 URL: http://llvm.org/viewvc/llvm-project?rev=60163&view=rev Log: Use the new MergeBasicBlockIntoOnlyPred function. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60163&r1=60162&r2=60163&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Thu Nov 27 01:54:12 2008 @@ -205,25 +205,7 @@ // If the destination block has a single pred, then this is a trivial edge, // just collapse it. if (DestBB->getSinglePredecessor()) { - // If DestBB has single-entry PHI nodes, fold them. - while (PHINode *PN = dyn_cast(DestBB->begin())) { - Value *NewVal = PN->getIncomingValue(0); - // Replace self referencing PHI with undef, it must be dead. - if (NewVal == PN) NewVal = UndefValue::get(PN->getType()); - PN->replaceAllUsesWith(NewVal); - PN->eraseFromParent(); - } - - // Splice all the PHI nodes from BB over to DestBB. - DestBB->getInstList().splice(DestBB->begin(), BB->getInstList(), - BB->begin(), BI); - - // Anything that branched to BB now branches to DestBB. - BB->replaceAllUsesWith(DestBB); - - // Nuke BB. - BB->eraseFromParent(); - + MergeBasicBlockIntoOnlyPred(DestBB); DOUT << "AFTER:\n" << *DestBB << "\n\n\n"; return; } From sabre at nondot.org Thu Nov 27 01:54:38 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 07:54:38 -0000 Subject: [llvm-commits] [llvm] r60164 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200811270754.mAR7sdFf009757@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 01:54:38 2008 New Revision: 60164 URL: http://llvm.org/viewvc/llvm-project?rev=60164&view=rev Log: simplify this code a bit. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60164&r1=60163&r2=60164&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Nov 27 01:54:38 2008 @@ -1709,9 +1709,9 @@ assert(&BB->getParent()->getEntryBlock() != BB && "Can't Simplify entry block!"); - // Remove basic blocks that have no predecessors... which are unreachable. - if ((pred_begin(BB) == pred_end(BB)) || - (*pred_begin(BB) == BB && ++pred_begin(BB) == pred_end(BB))) { + // Remove basic blocks that have no predecessors... or that just have themself + // as a predecessor. These are unreachable. + if (pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) { DOUT << "Removing BB: \n" << *BB; // Loop through all of our successors and make sure they know that one @@ -1733,7 +1733,7 @@ // Remove the instruction from the basic block BB->getInstList().pop_back(); } - M->getBasicBlockList().erase(BB); + BB->eraseFromParent(); return true; } From isanbard at gmail.com Thu Nov 27 02:00:18 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 27 Nov 2008 08:00:18 -0000 Subject: [llvm-commits] [llvm] r60165 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200811270800.mAR80JOi009930@zion.cs.uiuc.edu> Author: void Date: Thu Nov 27 02:00:12 2008 New Revision: 60165 URL: http://llvm.org/viewvc/llvm-project?rev=60165&view=rev Log: Get rid of bogus "control may reach end of non-void function ?...? being inlined" message. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=60165&r1=60164&r2=60165&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Nov 27 02:00:12 2008 @@ -2290,8 +2290,8 @@ if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) return convertFromHexadecimalString(p + 2, rounding_mode); - else - return convertFromDecimalString(p, rounding_mode); + + return convertFromDecimalString(p, rounding_mode); } /* Write out a hexadecimal representation of the floating point value From sabre at nondot.org Thu Nov 27 02:10:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 08:10:08 -0000 Subject: [llvm-commits] [llvm] r60166 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Transforms/Scalar/JumpThreading.cpp lib/Transforms/Utils/BasicBlockUtils.cpp Message-ID: <200811270810.mAR8A8kF010248@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 02:10:05 2008 New Revision: 60166 URL: http://llvm.org/viewvc/llvm-project?rev=60166&view=rev Log: move FindAvailableLoadedValue from JumpThreading to Transforms/Utils. Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=60166&r1=60165&r2=60166&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Thu Nov 27 02:10:05 2008 @@ -24,6 +24,7 @@ class Instruction; class Pass; +class AliasAnalysis; /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. @@ -47,6 +48,25 @@ // void ReplaceInstWithInst(Instruction *From, Instruction *To); +/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the +/// instruction before ScanFrom) checking to see if we have the value at the +/// memory address *Ptr locally available within a small number of instructions. +/// If the value is available, return it. +/// +/// If not, return the iterator for the last validated instruction that the +/// value would be live through. If we scanned the entire block and didn't find +/// something that invalidates *Ptr or provides it, ScanFrom would be left at +/// begin() and this returns null. ScanFrom could also be left +/// +/// MaxInstsToScan specifies the maximum instructions to scan in the block. If +/// it is set to 0, it will scan the whole block. You can also optionally +/// specify an alias analysis implementation, which makes this more precise. +Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, + BasicBlock::iterator &ScanFrom, + unsigned MaxInstsToScan = 6, + AliasAnalysis *AA = 0); + + // RemoveSuccessor - Change the specified terminator instruction such that its // successor #SuccNum no longer exists. Because this reduces the outgoing Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60166&r1=60165&r2=60166&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Nov 27 02:10:05 2008 @@ -243,67 +243,6 @@ return false; } - -/// FindAvailableLoadedValue - Scan backwards from ScanFrom checking to see if -/// we have the value at the memory address *Ptr locally available within a -/// small number of instructions. If the value is available, return it. -/// -/// If not, return the iterator for the last validated instruction that the -/// value would be live through. If we scanned the entire block, ScanFrom would -/// be left at begin(). -/// -/// FIXME: Move this to transform utils and use from -/// InstCombiner::visitLoadInst. It would also be nice to optionally take AA so -/// that GVN could do this. -static Value *FindAvailableLoadedValue(Value *Ptr, - BasicBlock *ScanBB, - BasicBlock::iterator &ScanFrom) { - - unsigned NumToScan = 6; - while (ScanFrom != ScanBB->begin()) { - // Don't scan huge blocks. - if (--NumToScan == 0) return 0; - - Instruction *Inst = --ScanFrom; - - // If this is a load of Ptr, the loaded value is available. - if (LoadInst *LI = dyn_cast(Inst)) - if (LI->getOperand(0) == Ptr) - return LI; - - if (StoreInst *SI = dyn_cast(Inst)) { - // If this is a store through Ptr, the value is available! - if (SI->getOperand(1) == Ptr) - return SI->getOperand(0); - - // If Ptr is an alloca and this is a store to a different alloca, ignore - // the store. This is a trivial form of alias analysis that is important - // for reg2mem'd code. - if ((isa(Ptr) || isa(Ptr)) && - (isa(SI->getOperand(1)) || - isa(SI->getOperand(1)))) - continue; - - // Otherwise the store that may or may not alias the pointer, bail out. - ++ScanFrom; - return 0; - } - - - // If this is some other instruction that may clobber Ptr, bail out. - if (Inst->mayWriteToMemory()) { - // May modify the pointer, bail out. - ++ScanFrom; - return 0; - } - } - - // Got to the start of the block, we didn't find it, but are done for this - // block. - return 0; -} - - /// SimplifyPartiallyRedundantLoad - If LI is an obviously partially redundant /// load instruction, eliminate it by replacing it with a PHI node. This is an /// important optimization that encourages jump threading, and needs to be run @@ -330,7 +269,8 @@ // the entry to its block. BasicBlock::iterator BBIt = LI; - if (Value *AvailableVal = FindAvailableLoadedValue(LoadedPtr, LoadBB, BBIt)) { + if (Value *AvailableVal = FindAvailableLoadedValue(LoadedPtr, LoadBB, + BBIt, 6)) { // If the value if the load is locally available within the block, just use // it. This frequently occurs for reg2mem'd allocas. //cerr << "LOAD ELIMINATED:\n" << *BBIt << *LI << "\n"; @@ -363,7 +303,7 @@ // Scan the predecessor to see if the value is available in the pred. BBIt = PredBB->end(); - Value *PredAvailable = FindAvailableLoadedValue(LoadedPtr, PredBB, BBIt); + Value *PredAvailable = FindAvailableLoadedValue(LoadedPtr, PredBB, BBIt, 6); if (!PredAvailable) { OneUnavailablePred = PredBB; continue; Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60166&r1=60165&r2=60166&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Nov 27 02:10:05 2008 @@ -371,3 +371,65 @@ return NewBB; } + +/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the +/// instruction before ScanFrom) checking to see if we have the value at the +/// memory address *Ptr locally available within a small number of instructions. +/// If the value is available, return it. +/// +/// If not, return the iterator for the last validated instruction that the +/// value would be live through. If we scanned the entire block and didn't find +/// something that invalidates *Ptr or provides it, ScanFrom would be left at +/// begin() and this returns null. ScanFrom could also be left +/// +/// MaxInstsToScan specifies the maximum instructions to scan in the block. If +/// it is set to 0, it will scan the whole block. You can also optionally +/// specify an alias analysis implementation, which makes this more precise. +Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, + BasicBlock::iterator &ScanFrom, + unsigned MaxInstsToScan, + AliasAnalysis *AA) { + if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; + + while (ScanFrom != ScanBB->begin()) { + // Don't scan huge blocks. + if (MaxInstsToScan-- == 0) return 0; + + Instruction *Inst = --ScanFrom; + + // If this is a load of Ptr, the loaded value is available. + if (LoadInst *LI = dyn_cast(Inst)) + if (LI->getOperand(0) == Ptr) + return LI; + + if (StoreInst *SI = dyn_cast(Inst)) { + // If this is a store through Ptr, the value is available! + if (SI->getOperand(1) == Ptr) + return SI->getOperand(0); + + // If Ptr is an alloca and this is a store to a different alloca, ignore + // the store. This is a trivial form of alias analysis that is important + // for reg2mem'd code. + if ((isa(Ptr) || isa(Ptr)) && + (isa(SI->getOperand(1)) || + isa(SI->getOperand(1)))) + continue; + + // Otherwise the store that may or may not alias the pointer, bail out. + ++ScanFrom; + return 0; + } + + + // If this is some other instruction that may clobber Ptr, bail out. + if (Inst->mayWriteToMemory()) { + // May modify the pointer, bail out. + ++ScanFrom; + return 0; + } + } + + // Got to the start of the block, we didn't find it, but are done for this + // block. + return 0; +} From sabre at nondot.org Thu Nov 27 02:18:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 08:18:21 -0000 Subject: [llvm-commits] [llvm] r60167 - /llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Message-ID: <200811270818.mAR8IMrq010522@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 02:18:12 2008 New Revision: 60167 URL: http://llvm.org/viewvc/llvm-project?rev=60167&view=rev Log: enhance FindAvailableLoadedValue to make use of AliasAnalysis if it has it. Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60167&r1=60166&r2=60167&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Nov 27 02:18:12 2008 @@ -20,6 +20,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Target/TargetData.h" #include using namespace llvm; @@ -390,6 +391,13 @@ unsigned MaxInstsToScan, AliasAnalysis *AA) { if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; + + // If we're using alias analysis to disambiguate get the size of *Ptr. + unsigned AccessSize = 0; + if (AA) { + const Type *AccessTy = cast(Ptr->getType())->getElementType(); + AccessSize = AA->getTargetData().getTypeStoreSizeInBits(AccessTy); + } while (ScanFrom != ScanBB->begin()) { // Don't scan huge blocks. @@ -415,14 +423,25 @@ isa(SI->getOperand(1)))) continue; + // If we have alias analysis and it says the store won't modify the loaded + // value, ignore the store. + if (AA && + (AA->getModRefInfo(SI, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) + continue; + // Otherwise the store that may or may not alias the pointer, bail out. ++ScanFrom; return 0; } - // If this is some other instruction that may clobber Ptr, bail out. if (Inst->mayWriteToMemory()) { + // If alias analysis claims that it really won't modify the load, + // ignore it. + if (AA && + (AA->getModRefInfo(Inst, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) + continue; + // May modify the pointer, bail out. ++ScanFrom; return 0; From sabre at nondot.org Thu Nov 27 02:39:22 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 08:39:22 -0000 Subject: [llvm-commits] [llvm] r60168 - in /llvm/trunk: include/llvm/Instruction.h lib/VMCore/Instruction.cpp Message-ID: <200811270839.mAR8dN8U012400@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 02:39:18 2008 New Revision: 60168 URL: http://llvm.org/viewvc/llvm-project?rev=60168&view=rev Log: improve const correctness. Modified: llvm/trunk/include/llvm/Instruction.h llvm/trunk/lib/VMCore/Instruction.cpp Modified: llvm/trunk/include/llvm/Instruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=60168&r1=60167&r2=60168&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Thu Nov 27 02:39:18 2008 @@ -58,7 +58,7 @@ /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any /// extra information (e.g. load is volatile) agree. - bool isIdenticalTo(Instruction *I) const; + bool isIdenticalTo(const Instruction *I) const; /// This function determines if the specified instruction executes the same /// operation as the current one. This means that the opcodes, type, operand @@ -68,7 +68,7 @@ /// @returns true if the specified instruction is the same operation as /// the current one. /// @brief Determine if one instruction is the same operation as another. - bool isSameOperationAs(Instruction *I) const; + bool isSameOperationAs(const Instruction *I) const; /// isUsedOutsideOfBlock - Return true if there are any uses of this /// instruction in blocks other than the specified block. Note that PHI nodes Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=60168&r1=60167&r2=60168&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Thu Nov 27 02:39:18 2008 @@ -158,7 +158,7 @@ /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any /// extra information (e.g. load is volatile) agree. -bool Instruction::isIdenticalTo(Instruction *I) const { +bool Instruction::isIdenticalTo(const Instruction *I) const { if (getOpcode() != I->getOpcode() || getNumOperands() != I->getNumOperands() || getType() != I->getType()) @@ -209,7 +209,7 @@ } // isSameOperationAs -bool Instruction::isSameOperationAs(Instruction *I) const { +bool Instruction::isSameOperationAs(const Instruction *I) const { if (getOpcode() != I->getOpcode() || getType() != I->getType() || getNumOperands() != I->getNumOperands()) return false; From sabre at nondot.org Thu Nov 27 02:56:30 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 08:56:30 -0000 Subject: [llvm-commits] [llvm] r60169 - in /llvm/trunk/lib/Transforms: Scalar/InstructionCombining.cpp Utils/BasicBlockUtils.cpp Message-ID: <200811270856.mAR8uV72017747@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 02:56:30 2008 New Revision: 60169 URL: http://llvm.org/viewvc/llvm-project?rev=60169&view=rev Log: switch InstCombine::visitLoadInst to use FindAvailableLoadedValue Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60169&r1=60168&r2=60169&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Nov 27 02:56:30 2008 @@ -10762,31 +10762,6 @@ return false; } -/// equivalentAddressValues - Test if A and B will obviously have the same -/// value. This includes recognizing that %t0 and %t1 will have the same -/// value in code like this: -/// %t0 = getelementptr @a, 0, 3 -/// store i32 0, i32* %t0 -/// %t1 = getelementptr @a, 0, 3 -/// %t2 = load i32* %t1 -/// -static bool equivalentAddressValues(Value *A, Value *B) { - // Test if the values are trivially equivalent. - if (A == B) return true; - - // Test if the values come form identical arithmetic instructions. - if (isa(A) || - isa(A) || - isa(A) || - isa(A)) - if (Instruction *BI = dyn_cast(B)) - if (cast(A)->isIdenticalTo(BI)) - return true; - - // Otherwise they may not be equivalent. - return false; -} - Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { Value *Op = LI.getOperand(0); @@ -10809,22 +10784,8 @@ // where there are several consequtive memory accesses to the same location, // separated by a few arithmetic operations. BasicBlock::iterator BBI = &LI; - for (unsigned ScanInsts = 6; BBI != LI.getParent()->begin() && ScanInsts; - --ScanInsts) { - --BBI; - - if (StoreInst *SI = dyn_cast(BBI)) { - if (equivalentAddressValues(SI->getOperand(1), LI.getOperand(0))) - return ReplaceInstUsesWith(LI, SI->getOperand(0)); - } else if (LoadInst *LIB = dyn_cast(BBI)) { - if (equivalentAddressValues(LIB->getOperand(0), LI.getOperand(0))) - return ReplaceInstUsesWith(LI, LIB); - } - - // Don't skip over things that can modify memory. - if (BBI->mayWriteToMemory()) - break; - } + if (Value *AvailableVal = FindAvailableLoadedValue(Op, LI.getParent(), BBI,6)) + return ReplaceInstUsesWith(LI, AvailableVal); if (GetElementPtrInst *GEPI = dyn_cast(Op)) { const Value *GEPI0 = GEPI->getOperand(0); @@ -10991,6 +10952,31 @@ return 0; } +/// equivalentAddressValues - Test if A and B will obviously have the same +/// value. This includes recognizing that %t0 and %t1 will have the same +/// value in code like this: +/// %t0 = getelementptr @a, 0, 3 +/// store i32 0, i32* %t0 +/// %t1 = getelementptr @a, 0, 3 +/// %t2 = load i32* %t1 +/// +static bool equivalentAddressValues(Value *A, Value *B) { + // Test if the values are trivially equivalent. + if (A == B) return true; + + // Test if the values come form identical arithmetic instructions. + if (isa(A) || + isa(A) || + isa(A) || + isa(A)) + if (Instruction *BI = dyn_cast(B)) + if (cast(A)->isIdenticalTo(BI)) + return true; + + // Otherwise they may not be equivalent. + return false; +} + Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { Value *Val = SI.getOperand(0); Value *Ptr = SI.getOperand(1); @@ -11036,8 +11022,8 @@ if (StoreInst *PrevSI = dyn_cast(BBI)) { // Prev store isn't volatile, and stores to the same location? - if (!PrevSI->isVolatile() && equivalentAddressValues(PrevSI->getOperand(1), - SI.getOperand(1))) { + if (!PrevSI->isVolatile() &&equivalentAddressValues(PrevSI->getOperand(1), + SI.getOperand(1))) { ++NumDeadStore; ++BBI; EraseInstFromFunction(*PrevSI); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60169&r1=60168&r2=60169&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Nov 27 02:56:30 2008 @@ -373,6 +373,29 @@ return NewBB; } +/// AreEquivalentAddressValues - Test if A and B will obviously have the same +/// value. This includes recognizing that %t0 and %t1 will have the same +/// value in code like this: +/// %t0 = getelementptr @a, 0, 3 +/// store i32 0, i32* %t0 +/// %t1 = getelementptr @a, 0, 3 +/// %t2 = load i32* %t1 +/// +static bool AreEquivalentAddressValues(const Value *A, const Value *B) { + // Test if the values are trivially equivalent. + if (A == B) return true; + + // Test if the values come form identical arithmetic instructions. + if (isa(A) || isa(A) || + isa(A) || isa(A)) + if (const Instruction *BI = dyn_cast(B)) + if (cast(A)->isIdenticalTo(BI)) + return true; + + // Otherwise they may not be equivalent. + return false; +} + /// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the /// instruction before ScanFrom) checking to see if we have the value at the /// memory address *Ptr locally available within a small number of instructions. @@ -407,12 +430,12 @@ // If this is a load of Ptr, the loaded value is available. if (LoadInst *LI = dyn_cast(Inst)) - if (LI->getOperand(0) == Ptr) + if (AreEquivalentAddressValues(LI->getOperand(0), Ptr)) return LI; if (StoreInst *SI = dyn_cast(Inst)) { // If this is a store through Ptr, the value is available! - if (SI->getOperand(1) == Ptr) + if (AreEquivalentAddressValues(SI->getOperand(1), Ptr)) return SI->getOperand(0); // If Ptr is an alloca and this is a store to a different alloca, ignore From baldrick at free.fr Thu Nov 27 08:22:31 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 27 Nov 2008 14:22:31 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60171 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200811271422.mAREMVhE001836@zion.cs.uiuc.edu> Author: baldrick Date: Thu Nov 27 08:22:29 2008 New Revision: 60171 URL: http://llvm.org/viewvc/llvm-project?rev=60171&view=rev Log: Make "-mllvm --disable-llvm-optzns" work again. Two problems: the option parser expects the first option to be the program name, but here a real option was being passed meaning it was skipped. The other problem is that the std::string returned by getToken was being freed at the end of the local block, resulting in the option parser reading freed memory, with very strange consequences. The first problem is solved by parsing all options at the same time, rather than it two sets (the first lot of option parsing code correctly added the program name). The second by introducing an array of std::string in order to keep the tokens alive until the end of the function. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=60171&r1=60170&r2=60171&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Thu Nov 27 08:22:29 2008 @@ -174,8 +174,15 @@ for (unsigned i = 0, e = ArgStrings.size(); i != e; ++i) Args.push_back(ArgStrings[i].c_str()); + + std::vector LLVM_Optns; // Avoid deallocation before opts parsed! + if (llvm_optns) { + SplitString(llvm_optns, LLVM_Optns); + for(unsigned i = 0, e = LLVM_Optns.size(); i != e; ++i) + Args.push_back(LLVM_Optns[i].c_str()); + } + Args.push_back(0); // Null terminator. - int pseudo_argc = Args.size()-1; cl::ParseCommandLineOptions(pseudo_argc, (char**)&Args[0]); @@ -239,19 +246,7 @@ RegisterRegAlloc::setDefault(createLinearScanRegisterAllocator); else RegisterRegAlloc::setDefault(createLocalRegisterAllocator); - - Args.clear(); - if (llvm_optns) { - std::string Opts = llvm_optns; - for (std::string Opt = getToken(Opts); !Opt.empty(); Opt = getToken(Opts)) - Args.push_back(Opt.c_str()); - } - if (!Args.empty()) { - Args.push_back(0); // Null terminator. - pseudo_argc = Args.size()-1; - cl::ParseCommandLineOptions(pseudo_argc, (char**)&Args[0]); - } - + if (!optimize && debug_info_level > DINFO_LEVEL_NONE) TheDebugInfo = new DebugInfo(TheModule); } From nunoplopes at sapo.pt Thu Nov 27 10:37:03 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Thu, 27 Nov 2008 16:37:03 -0000 Subject: [llvm-commits] [llvm] r60174 - /llvm/trunk/lib/Support/Annotation.cpp Message-ID: <200811271637.mARGb3va006892@zion.cs.uiuc.edu> Author: nlopes Date: Thu Nov 27 10:37:02 2008 New Revision: 60174 URL: http://llvm.org/viewvc/llvm-project?rev=60174&view=rev Log: fix my previous commit r60064: compare strings instead of pointers Modified: llvm/trunk/lib/Support/Annotation.cpp Modified: llvm/trunk/lib/Support/Annotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Annotation.cpp?rev=60174&r1=60173&r2=60174&view=diff ============================================================================== --- llvm/trunk/lib/Support/Annotation.cpp (original) +++ llvm/trunk/lib/Support/Annotation.cpp Thu Nov 27 10:37:02 2008 @@ -27,7 +27,16 @@ } } -typedef std::map IDMapType; +namespace { + class StrCmp { + public: + bool operator()(const char *a, const char *b) { + return strcmp(a, b) < 0; + } + }; +} + +typedef std::map IDMapType; static unsigned IDCounter = 0; // Unique ID counter // Static member to ensure initialiation on demand. From nunoplopes at sapo.pt Thu Nov 27 10:42:44 2008 From: nunoplopes at sapo.pt (Nuno Lopes) Date: Thu, 27 Nov 2008 16:42:44 -0000 Subject: [llvm-commits] [llvm] r60175 - /llvm/trunk/lib/Support/Annotation.cpp Message-ID: <200811271642.mARGgi52007125@zion.cs.uiuc.edu> Author: nlopes Date: Thu Nov 27 10:42:44 2008 New Revision: 60175 URL: http://llvm.org/viewvc/llvm-project?rev=60175&view=rev Log: fix build on some machines. thanks buildbot Modified: llvm/trunk/lib/Support/Annotation.cpp Modified: llvm/trunk/lib/Support/Annotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Annotation.cpp?rev=60175&r1=60174&r2=60175&view=diff ============================================================================== --- llvm/trunk/lib/Support/Annotation.cpp (original) +++ llvm/trunk/lib/Support/Annotation.cpp Thu Nov 27 10:42:44 2008 @@ -14,6 +14,7 @@ #include "llvm/Support/Annotation.h" #include "llvm/Support/ManagedStatic.h" #include +#include using namespace llvm; Annotation::~Annotation() {} // Designed to be subclassed From nicholas at mxc.ca Thu Nov 27 11:29:52 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 27 Nov 2008 17:29:52 -0000 Subject: [llvm-commits] [llvm] r60177 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200811271729.mARHTrCg009015@zion.cs.uiuc.edu> Author: nicholas Date: Thu Nov 27 11:29:52 2008 New Revision: 60177 URL: http://llvm.org/viewvc/llvm-project?rev=60177&view=rev Log: Silence a warning. Despite changing the order of evaluation, this doesn't actually change the meaning of the statement. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60177&r1=60176&r2=60177&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Thu Nov 27 11:29:52 2008 @@ -397,7 +397,7 @@ // Determine AntiDepReg's register class, if it is live and is // consistently used within a single class. const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; - assert(AntiDepReg == 0 || RC != NULL && + assert((AntiDepReg == 0 || RC != NULL) && "Register should be live if it's causing an anti-dependence!"); if (RC == reinterpret_cast(-1)) AntiDepReg = 0; From sabre at nondot.org Thu Nov 27 13:25:19 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 19:25:19 -0000 Subject: [llvm-commits] [llvm] r60179 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll Message-ID: <200811271925.mARJPJZT012748@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 13:25:19 2008 New Revision: 60179 URL: http://llvm.org/viewvc/llvm-project?rev=60179&view=rev Log: Fix PR3138: if we merge the entry block into another block, make sure to move the other block back up into the entry position! Added: llvm/trunk/test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60179&r1=60178&r2=60179&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Nov 27 13:25:19 2008 @@ -165,7 +165,13 @@ // predecessors of our predecessor block. if (BasicBlock *SinglePred = BB->getSinglePredecessor()) if (SinglePred->getTerminator()->getNumSuccessors() == 1) { + // Remember if SinglePred was the entry block of the function. If so, we + // will need to move BB back to the entry position. + bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); MergeBasicBlockIntoOnlyPred(BB); + + if (isEntry && BB != &BB->getParent()->getEntryBlock()) + BB->moveBefore(&BB->getParent()->getEntryBlock()); return true; } Added: llvm/trunk/test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll?rev=60179&view=auto ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll (added) +++ llvm/trunk/test/Transforms/JumpThreading/2008-11-27-EntryMunge.ll Thu Nov 27 13:25:19 2008 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | opt -jump-threading -simplifycfg | llvm-dis | grep {ret i32 0} +; PR3138 + +define i32 @jt() { +entry: + br i1 true, label %bb3, label %bb + +bb: ; preds = %entry + unreachable + +bb3: ; preds = %entry + ret i32 0 +} From sabre at nondot.org Thu Nov 27 13:29:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 19:29:14 -0000 Subject: [llvm-commits] [llvm] r60180 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <200811271929.mARJTEFK012926@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 13:29:14 2008 New Revision: 60180 URL: http://llvm.org/viewvc/llvm-project?rev=60180&view=rev Log: defensive patch: if CGP is merging a block with the entry block, make sure it ends up being the entry block. Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60180&r1=60179&r2=60180&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Thu Nov 27 13:29:14 2008 @@ -204,8 +204,15 @@ // If the destination block has a single pred, then this is a trivial edge, // just collapse it. - if (DestBB->getSinglePredecessor()) { + if (BasicBlock *SinglePred = DestBB->getSinglePredecessor()) { + // Remember if SinglePred was the entry block of the function. If so, we + // will need to move BB back to the entry position. + bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); MergeBasicBlockIntoOnlyPred(DestBB); + + if (isEntry && BB != &BB->getParent()->getEntryBlock()) + BB->moveBefore(&BB->getParent()->getEntryBlock()); + DOUT << "AFTER:\n" << *DestBB << "\n\n\n"; return; } From nicholas at mxc.ca Thu Nov 27 14:21:10 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 27 Nov 2008 20:21:10 -0000 Subject: [llvm-commits] [llvm] r60182 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-11-27-IDivVector.ll test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll Message-ID: <200811272021.mARKLA40014500@zion.cs.uiuc.edu> Author: nicholas Date: Thu Nov 27 14:21:08 2008 New Revision: 60182 URL: http://llvm.org/viewvc/llvm-project?rev=60182&view=rev Log: Add a couple of missed optimizations on integer vectors. Multiply and divide by 1, as well as multiply by -1. Added: llvm/trunk/test/Transforms/InstCombine/2008-11-27-IDivVector.ll llvm/trunk/test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60182&r1=60181&r2=60182&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Nov 27 14:21:08 2008 @@ -2576,12 +2576,21 @@ } else if (isa(Op1->getType())) { if (isa(Op1)) return ReplaceInstUsesWith(I, Op1); - - // As above, vector X*splat(1.0) -> X in all defined cases. - if (ConstantVector *Op1V = dyn_cast(Op1)) - if (ConstantFP *F = dyn_cast_or_null(Op1V->getSplatValue())) - if (F->isExactlyValue(1.0)) - return ReplaceInstUsesWith(I, Op0); + + if (ConstantVector *Op1V = dyn_cast(Op1)) { + if (Op1V->isAllOnesValue()) // X * -1 == 0 - X + return BinaryOperator::CreateNeg(Op0, I.getName()); + + // As above, vector X*splat(1.0) -> X in all defined cases. + if (Constant *Splat = Op1V->getSplatValue()) { + if (ConstantFP *F = dyn_cast(Splat)) + if (F->isExactlyValue(1.0)) + return ReplaceInstUsesWith(I, Op0); + if (ConstantInt *CI = dyn_cast(Splat)) + if (CI->equalsInt(1)) + return ReplaceInstUsesWith(I, Op0); + } + } } if (BinaryOperator *Op0I = dyn_cast(Op0)) @@ -2856,6 +2865,13 @@ if (I.getType() == Type::Int1Ty) return ReplaceInstUsesWith(I, Op0); + if (ConstantVector *Op1V = dyn_cast(Op1)) { + if (ConstantInt *X = cast_or_null(Op1V->getSplatValue())) + // div X, 1 == X + if (X->isOne()) + return ReplaceInstUsesWith(I, Op0); + } + return 0; } Added: llvm/trunk/test/Transforms/InstCombine/2008-11-27-IDivVector.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-11-27-IDivVector.ll?rev=60182&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-11-27-IDivVector.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2008-11-27-IDivVector.ll Thu Nov 27 14:21:08 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div + +define <2 x i8> @f(<2 x i8> %x) { + %A = udiv <2 x i8> %x, + ret <2 x i8> %A +} + +define <2 x i8> @g(<2 x i8> %x) { + %A = sdiv <2 x i8> %x, + ret <2 x i8> %A +} Added: llvm/trunk/test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll?rev=60182&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2008-11-27-MultiplyIntVec.ll Thu Nov 27 14:21:08 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep mul + +define <2 x i8> @f(<2 x i8> %x) { + %A = mul <2 x i8> %x, + ret <2 x i8> %A +} + +define <2 x i8> @g(<2 x i8> %x) { + %A = mul <2 x i8> %x, + ret <2 x i8> %A +} From nicholas at mxc.ca Thu Nov 27 16:12:22 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 27 Nov 2008 22:12:22 -0000 Subject: [llvm-commits] [llvm] r60186 - /llvm/trunk/lib/Target/README.txt Message-ID: <200811272212.mARMCMTv017765@zion.cs.uiuc.edu> Author: nicholas Date: Thu Nov 27 16:12:22 2008 New Revision: 60186 URL: http://llvm.org/viewvc/llvm-project?rev=60186&view=rev Log: Add a synthetic missed optimization. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60186&r1=60185&r2=60186&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Nov 27 16:12:22 2008 @@ -984,3 +984,27 @@ } //===---------------------------------------------------------------------===// + +These three functions all perform the same computation, but produce different +assembly. On x86, they are sorted from slowest to fastest. + +define i8 @udiv(i8 %x) readnone nounwind { + %A = udiv i8 %x, 250 + ret i8 %A +} + +define i8 @select(i8 %x) readnone nounwind { + %A = icmp ult i8 %x, 250 + %B = select i1 %A, i8 0, i8 1 + ret i8 %B +} + +define i8 @addshr(i8 %x) readnone nounwind { + %A = zext i8 %x to i9 + %B = add i9 %A, 6 ;; 256 - 250 == 6 + %C = lshr i9 %B, 8 + %D = trunc i9 %C to i8 + ret i8 %D +} + +//===---------------------------------------------------------------------===// From nicholas at mxc.ca Thu Nov 27 16:41:10 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 27 Nov 2008 22:41:10 -0000 Subject: [llvm-commits] [llvm] r60187 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-11-27-UDivNegative.ll test/Transforms/InstCombine/udiv-simplify-bug-1.ll Message-ID: <200811272241.mARMfBsT018760@zion.cs.uiuc.edu> Author: nicholas Date: Thu Nov 27 16:41:10 2008 New Revision: 60187 URL: http://llvm.org/viewvc/llvm-project?rev=60187&view=rev Log: Chris prefers icmp/select over udiv! Added: llvm/trunk/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60187&r1=60186&r2=60187&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Nov 27 16:41:10 2008 @@ -2882,13 +2882,21 @@ if (Instruction *Common = commonIDivTransforms(I)) return Common; - // X udiv C^2 -> X >> C - // Check to see if this is an unsigned division with an exact power of 2, - // if so, convert to a right shift. if (ConstantInt *C = dyn_cast(Op1)) { + // X udiv C^2 -> X >> C + // Check to see if this is an unsigned division with an exact power of 2, + // if so, convert to a right shift. if (C->getValue().isPowerOf2()) // 0 not included in isPowerOf2 return BinaryOperator::CreateLShr(Op0, ConstantInt::get(Op0->getType(), C->getValue().logBase2())); + + // X udiv C, where C >= signbit + if (C->getValue().isNegative()) { + Value *IC = InsertNewInstBefore(new ICmpInst(ICmpInst::ICMP_ULT, Op0, C), + I); + return SelectInst::Create(IC, Constant::getNullValue(I.getType()), + ConstantInt::get(I.getType(), 1)); + } } // X udiv (C1 << N), where C1 is "1< X >> (N+C2) Added: llvm/trunk/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll?rev=60187&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll Thu Nov 27 16:41:10 2008 @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div + +define i8 @test(i8 %x) readnone nounwind { + %A = udiv i8 %x, 250 + ret i8 %A +} Modified: llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll?rev=60187&r1=60186&r2=60187&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll Thu Nov 27 16:41:10 2008 @@ -1,16 +1,11 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t1.ll -; RUN: grep udiv %t1.ll | count 3 -; RUN: grep zext %t1.ll | count 3 +; RUN: grep udiv %t1.ll | count 2 +; RUN: grep zext %t1.ll | count 2 ; PR2274 ; The udiv instructions shouldn't be optimized away, and the ; sext instructions should be optimized to zext. -define i64 @foo(i32 %x) nounwind { - %r = udiv i32 %x, -1 - %z = sext i32 %r to i64 - ret i64 %z -} define i64 @bar(i32 %x) nounwind { %y = lshr i32 %x, 30 %r = udiv i32 %y, 3 From nicholas at mxc.ca Thu Nov 27 16:41:45 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 27 Nov 2008 22:41:45 -0000 Subject: [llvm-commits] [llvm] r60188 - /llvm/trunk/lib/Target/README.txt Message-ID: <200811272241.mARMfjfB018812@zion.cs.uiuc.edu> Author: nicholas Date: Thu Nov 27 16:41:45 2008 New Revision: 60188 URL: http://llvm.org/viewvc/llvm-project?rev=60188&view=rev Log: Also update the README. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60188&r1=60187&r2=60188&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Nov 27 16:41:45 2008 @@ -985,13 +985,7 @@ //===---------------------------------------------------------------------===// -These three functions all perform the same computation, but produce different -assembly. On x86, they are sorted from slowest to fastest. - -define i8 @udiv(i8 %x) readnone nounwind { - %A = udiv i8 %x, 250 - ret i8 %A -} +These functions perform the same computation, but produce different assembly. define i8 @select(i8 %x) readnone nounwind { %A = icmp ult i8 %x, 250 From sabre at nondot.org Thu Nov 27 16:46:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 22:46:09 -0000 Subject: [llvm-commits] [llvm] r60189 - /llvm/trunk/lib/Transforms/Scalar/DCE.cpp Message-ID: <200811272246.mARMk9XH019064@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 16:46:09 2008 New Revision: 60189 URL: http://llvm.org/viewvc/llvm-project?rev=60189&view=rev Log: simplify this logic. Modified: llvm/trunk/lib/Transforms/Scalar/DCE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DCE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DCE.cpp?rev=60189&r1=60188&r2=60189&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DCE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DCE.cpp Thu Nov 27 16:46:09 2008 @@ -39,12 +39,14 @@ DeadInstElimination() : BasicBlockPass(intptr_t(&ID)) {} virtual bool runOnBasicBlock(BasicBlock &BB) { bool Changed = false; - for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); ) - if (dceInstruction(DI)) { + for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); ) { + Instruction *Inst = DI++; + if (isInstructionTriviallyDead(Inst)) { + Inst->eraseFromParent(); Changed = true; ++DIEEliminated; - } else - ++DI; + } + } return Changed; } From sabre at nondot.org Thu Nov 27 16:56:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 22:56:14 -0000 Subject: [llvm-commits] [llvm] r60190 - /llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp Message-ID: <200811272256.mARMuExK019598@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 16:56:14 2008 New Revision: 60190 URL: http://llvm.org/viewvc/llvm-project?rev=60190&view=rev Log: simplify code. Modified: llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp Modified: llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp?rev=60190&r1=60189&r2=60190&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp Thu Nov 27 16:56:14 2008 @@ -27,6 +27,7 @@ #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/Support/CFG.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" @@ -348,10 +349,17 @@ // instructions one last time, constant propagating and DCE'ing them, because // they may not be needed anymore. // - if (HadPHINodes) - while (BI != SourceBlock->end()) - if (!dceInstruction(BI) && !doConstantPropagation(BI)) - ++BI; + if (HadPHINodes) { + while (BI != SourceBlock->end()) { + Instruction *Inst = BI++; + if (isInstructionTriviallyDead(Inst)) + Inst->eraseFromParent(); + else if (Constant *C = ConstantFoldInstruction(Inst)) { + Inst->replaceAllUsesWith(C); + Inst->eraseFromParent(); + } + } + } ++NumEliminated; // We just killed a branch! } From sabre at nondot.org Thu Nov 27 16:57:53 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 22:57:53 -0000 Subject: [llvm-commits] [llvm] r60191 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Scalar/CodeGenPrepare.cpp lib/Transforms/Utils/Local.cpp Message-ID: <200811272257.mARMvrHH019694@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 16:57:53 2008 New Revision: 60191 URL: http://llvm.org/viewvc/llvm-project?rev=60191&view=rev Log: remove doConstantPropagation and dceInstruction, they are just wrappers around the interesting code and use an obscure iterator abstraction that dates back many many years. Move EraseDeadInstructions to Transforms/Utils and name it RecursivelyDeleteTriviallyDeadInstructions. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=60191&r1=60190&r2=60191&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Nov 27 16:57:53 2008 @@ -26,14 +26,9 @@ class TargetData; //===----------------------------------------------------------------------===// -// Local constant propagation... +// Local constant propagation. // -/// doConstantPropagation - Constant prop a specific instruction. Returns true -/// and potentially moves the iterator if constant propagation was performed. -/// -bool doConstantPropagation(BasicBlock::iterator &I, const TargetData *TD = 0); - /// ConstantFoldTerminator - If a terminator instruction is predicated on a /// constant value, convert it into an unconditional branch to the constant /// destination. This is a nontrivial operation because the successors of this @@ -42,7 +37,7 @@ bool ConstantFoldTerminator(BasicBlock *BB); //===----------------------------------------------------------------------===// -// Local dead code elimination... +// Local dead code elimination. // /// isInstructionTriviallyDead - Return true if the result produced by the @@ -50,14 +45,12 @@ /// bool isInstructionTriviallyDead(Instruction *I); - -/// dceInstruction - Inspect the instruction at *BBI and figure out if it -/// isTriviallyDead. If so, remove the instruction and update the iterator to -/// point to the instruction that immediately succeeded the original -/// instruction. -/// -bool dceInstruction(BasicBlock::iterator &BBI); - + +/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a +/// trivially dead instruction, delete it. If that makes any of its operands +/// trivially dead, delete them too, recursively. +void RecursivelyDeleteTriviallyDeadInstructions(Value *V); + //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring... // Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60191&r1=60190&r2=60191&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Thu Nov 27 16:57:53 2008 @@ -454,26 +454,6 @@ return MadeChange; } -/// EraseDeadInstructions - Erase any dead instructions, recursively. -static void EraseDeadInstructions(Value *V) { - Instruction *I = dyn_cast(V); - if (!I || !I->use_empty()) return; - - SmallPtrSet Insts; - Insts.insert(I); - - while (!Insts.empty()) { - I = *Insts.begin(); - Insts.erase(I); - if (isInstructionTriviallyDead(I)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Instruction *U = dyn_cast(I->getOperand(i))) - Insts.insert(U); - I->eraseFromParent(); - } - } -} - //===----------------------------------------------------------------------===// // Addressing Mode Analysis and Optimization //===----------------------------------------------------------------------===// @@ -1234,7 +1214,7 @@ MemoryInst->replaceUsesOfWith(Addr, SunkAddr); if (Addr->use_empty()) - EraseDeadInstructions(Addr); + RecursivelyDeleteTriviallyDeadInstructions(Addr); return true; } Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60191&r1=60190&r2=60191&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 16:57:53 2008 @@ -22,30 +22,13 @@ #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" -#include +#include "llvm/ADT/SmallPtrSet.h" using namespace llvm; //===----------------------------------------------------------------------===// -// Local constant propagation... +// Local constant propagation. // -/// doConstantPropagation - If an instruction references constants, try to fold -/// them together... -/// -bool llvm::doConstantPropagation(BasicBlock::iterator &II, - const TargetData *TD) { - if (Constant *C = ConstantFoldInstruction(II, TD)) { - // Replaces all of the uses of a variable with uses of the constant. - II->replaceAllUsesWith(C); - - // Remove the instruction from the basic block... - II = II->getParent()->getInstList().erase(II); - return true; - } - - return false; -} - // ConstantFoldTerminator - If a terminator instruction is predicated on a // constant value, convert it into an unconditional branch to the constant // destination. @@ -171,6 +154,9 @@ // Local dead code elimination... // +/// isInstructionTriviallyDead - Return true if the result produced by the +/// instruction is not used, and the instruction has no side effects. +/// bool llvm::isInstructionTriviallyDead(Instruction *I) { if (!I->use_empty() || isa(I)) return false; @@ -187,20 +173,29 @@ return false; } -// dceInstruction - Inspect the instruction at *BBI and figure out if it's -// [trivially] dead. If so, remove the instruction and update the iterator -// to point to the instruction that immediately succeeded the original -// instruction. -// -bool llvm::dceInstruction(BasicBlock::iterator &BBI) { - // Look for un"used" definitions... - if (isInstructionTriviallyDead(BBI)) { - BBI = BBI->getParent()->getInstList().erase(BBI); // Bye bye - return true; +/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a +/// trivially dead instruction, delete it. If that makes any of its operands +/// trivially dead, delete them too, recursively. +void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) { + Instruction *I = dyn_cast(V); + if (!I || !I->use_empty()) return; + + SmallPtrSet Insts; + Insts.insert(I); + + while (!Insts.empty()) { + I = *Insts.begin(); + Insts.erase(I); + if (isInstructionTriviallyDead(I)) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Instruction *U = dyn_cast(I->getOperand(i))) + Insts.insert(U); + I->eraseFromParent(); + } } - return false; } + //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring... // From sabre at nondot.org Thu Nov 27 17:00:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 23:00:21 -0000 Subject: [llvm-commits] [llvm] r60192 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200811272300.mARN0L16019844@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 17:00:20 2008 New Revision: 60192 URL: http://llvm.org/viewvc/llvm-project?rev=60192&view=rev Log: use continue to reduce indentation Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60192&r1=60191&r2=60192&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Nov 27 17:00:20 2008 @@ -2076,25 +2076,26 @@ // // FIXME: this needs to eliminate an induction variable even if it's being // compared against some value to decide loop termination. - if (PN->hasOneUse()) { - SmallPtrSet PHIs; - for (Instruction *J = dyn_cast(*PN->use_begin()); - J && J->hasOneUse() && !J->mayWriteToMemory(); - J = dyn_cast(*J->use_begin())) { - // If we find the original PHI, we've discovered a cycle. - if (J == PN) { - // Break the cycle and mark the PHI for deletion. - SE->deleteValueFromRecords(PN); - PN->replaceAllUsesWith(UndefValue::get(PN->getType())); - DeadInsts.insert(PN); - Changed = true; - break; - } - // If we find a PHI more than once, we're on a cycle that - // won't prove fruitful. - if (isa(J) && !PHIs.insert(cast(J))) - break; + if (!PN->hasOneUse()) + continue; + + SmallPtrSet PHIs; + for (Instruction *J = dyn_cast(*PN->use_begin()); + J && J->hasOneUse() && !J->mayWriteToMemory(); + J = dyn_cast(*J->use_begin())) { + // If we find the original PHI, we've discovered a cycle. + if (J == PN) { + // Break the cycle and mark the PHI for deletion. + SE->deleteValueFromRecords(PN); + PN->replaceAllUsesWith(UndefValue::get(PN->getType())); + DeadInsts.insert(PN); + Changed = true; + break; } + // If we find a PHI more than once, we're on a cycle that + // won't prove fruitful. + if (isa(J) && !PHIs.insert(cast(J))) + break; } } DeleteTriviallyDeadInstructions(DeadInsts); From sabre at nondot.org Thu Nov 27 17:14:34 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 23:14:34 -0000 Subject: [llvm-commits] [llvm] r60193 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp Message-ID: <200811272314.mARNEY9g020336@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 17:14:34 2008 New Revision: 60193 URL: http://llvm.org/viewvc/llvm-project?rev=60193&view=rev Log: Enhance RecursivelyDeleteTriviallyDeadInstructions to optionally return a list of deleted instructions. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=60193&r1=60192&r2=60193&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Nov 27 17:14:34 2008 @@ -24,7 +24,7 @@ class AllocaInst; class ConstantExpr; class TargetData; - + //===----------------------------------------------------------------------===// // Local constant propagation. // @@ -49,7 +49,11 @@ /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. -void RecursivelyDeleteTriviallyDeadInstructions(Value *V); +/// +/// If DeadInst is specified, the vector is filled with the instructions that +/// are actually deleted. +void RecursivelyDeleteTriviallyDeadInstructions(Value *V, + SmallVectorImpl *DeadInst = 0); //===----------------------------------------------------------------------===// // Control Flow Graph Restructuring... Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60193&r1=60192&r2=60193&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 17:14:34 2008 @@ -176,7 +176,11 @@ /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. -void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) { +/// +/// If DeadInst is specified, the vector is filled with the instructions that +/// are actually deleted. +void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V, + SmallVectorImpl *DeadInst) { Instruction *I = dyn_cast(V); if (!I || !I->use_empty()) return; @@ -186,12 +190,16 @@ while (!Insts.empty()) { I = *Insts.begin(); Insts.erase(I); - if (isInstructionTriviallyDead(I)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Instruction *U = dyn_cast(I->getOperand(i))) - Insts.insert(U); - I->eraseFromParent(); - } + if (!isInstructionTriviallyDead(I)) + continue; + + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Instruction *U = dyn_cast(I->getOperand(i))) + Insts.insert(U); + I->eraseFromParent(); + + if (DeadInst) + DeadInst->push_back(I); } } From sabre at nondot.org Thu Nov 27 17:18:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 23:18:12 -0000 Subject: [llvm-commits] [llvm] r60194 - /llvm/trunk/lib/Transforms/Utils/Local.cpp Message-ID: <200811272318.mARNICxl020437@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 17:18:11 2008 New Revision: 60194 URL: http://llvm.org/viewvc/llvm-project?rev=60194&view=rev Log: enhance RecursivelyDeleteTriviallyDeadInstructions to make PHIs dead if they are single-value. Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60194&r1=60193&r2=60194&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 17:18:11 2008 @@ -190,6 +190,15 @@ while (!Insts.empty()) { I = *Insts.begin(); Insts.erase(I); + + // If this is a PHI node, we may be able to make it dead if we know all the + // input values are the same. + if (PHINode *PN = dyn_cast(I)) { + if (Value *PNV = PN->hasConstantValue()) + PN->replaceAllUsesWith(PNV); + } + + // Okay, if the instruction is dead, delete it. if (!isInstructionTriviallyDead(I)) continue; From sabre at nondot.org Thu Nov 27 17:23:35 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 23:23:35 -0000 Subject: [llvm-commits] [llvm] r60195 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200811272323.mARNNZlS020592@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 17:23:35 2008 New Revision: 60195 URL: http://llvm.org/viewvc/llvm-project?rev=60195&view=rev Log: Simplify LoopStrengthReduce::DeleteTriviallyDeadInstructions by making it use RecursivelyDeleteTriviallyDeadInstructions to do the heavy lifting. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60195&r1=60194&r2=60195&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Nov 27 17:23:35 2008 @@ -240,31 +240,30 @@ /// their operands subsequently dead. void LoopStrengthReduce:: DeleteTriviallyDeadInstructions(SetVector &Insts) { + SmallVector DeadInsts; + while (!Insts.empty()) { Instruction *I = Insts.back(); Insts.pop_back(); + + // If I is dead, delete it and all the things that it recursively uses + // that become dead. + RecursivelyDeleteTriviallyDeadInstructions(I, &DeadInsts); + + if (DeadInsts.empty()) continue; + Changed = true; - if (PHINode *PN = dyn_cast(I)) { - // If all incoming values to the Phi are the same, we can replace the Phi - // with that value. - if (Value *PNV = PN->hasConstantValue()) { - if (Instruction *U = dyn_cast(PNV)) - Insts.insert(U); - SE->deleteValueFromRecords(PN); - PN->replaceAllUsesWith(PNV); - PN->eraseFromParent(); - Changed = true; - continue; - } - } - - if (isInstructionTriviallyDead(I)) { - for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) - if (Instruction *U = dyn_cast(*i)) - Insts.insert(U); - SE->deleteValueFromRecords(I); - I->eraseFromParent(); - Changed = true; + while (!DeadInsts.empty()) { + Instruction *DeadInst = DeadInsts.back(); + DeadInsts.pop_back(); + + // Make sure ScalarEvolutions knows this instruction is gone. + SE->deleteValueFromRecords(DeadInst); + + // Make sure that this instruction is removed from DeadInsts if it was + // recursively removed. + if (DeadInst != I) + Insts.remove(DeadInst); } } } From sabre at nondot.org Thu Nov 27 17:25:45 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 27 Nov 2008 23:25:45 -0000 Subject: [llvm-commits] [llvm] r60196 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200811272325.mARNPjSj020658@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 17:25:44 2008 New Revision: 60196 URL: http://llvm.org/viewvc/llvm-project?rev=60196&view=rev Log: delete ErasePossiblyDeadInstructionTree, replacing uses of it with RecursivelyDeleteTriviallyDeadInstructions. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60196&r1=60195&r2=60196&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Nov 27 17:25:44 2008 @@ -494,40 +494,8 @@ return false; } -/// ErasePossiblyDeadInstructionTree - If the specified instruction is dead and -/// has no side effects, nuke it. If it uses any instructions that become dead -/// because the instruction is now gone, nuke them too. -static void ErasePossiblyDeadInstructionTree(Instruction *I) { - if (!isInstructionTriviallyDead(I)) return; - - SmallVector InstrsToInspect; - InstrsToInspect.push_back(I); - - while (!InstrsToInspect.empty()) { - I = InstrsToInspect.back(); - InstrsToInspect.pop_back(); - - if (!isInstructionTriviallyDead(I)) continue; - - // If I is in the work list multiple times, remove previous instances. - for (unsigned i = 0, e = InstrsToInspect.size(); i != e; ++i) - if (InstrsToInspect[i] == I) { - InstrsToInspect.erase(InstrsToInspect.begin()+i); - --i, --e; - } - - // Add operands of dead instruction to worklist. - for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) - if (Instruction *OpI = dyn_cast(*i)) - InstrsToInspect.push_back(OpI); - - // Remove dead instruction. - I->eraseFromParent(); - } -} - -// isValueEqualityComparison - Return true if the specified terminator checks to -// see if a value is equal to constant integer value. +/// isValueEqualityComparison - Return true if the specified terminator checks +/// to see if a value is equal to constant integer value. static Value *isValueEqualityComparison(TerminatorInst *TI) { if (SwitchInst *SI = dyn_cast(TI)) { // Do not permit merging of large switch instructions into their @@ -548,8 +516,8 @@ return 0; } -// Given a value comparison instruction, decode all of the 'cases' that it -// represents and return the 'default' block. +/// Given a value comparison instruction, decode all of the 'cases' that it +/// represents and return the 'default' block. static BasicBlock * GetValueEqualityComparisonCases(TerminatorInst *TI, std::vectoreraseFromParent(); // Nuke the old one. // If condition is now dead, nuke it. if (Instruction *CondI = dyn_cast(Cond)) - ErasePossiblyDeadInstructionTree(CondI); + RecursivelyDeleteTriviallyDeadInstructions(CondI); return true; } else { @@ -734,7 +702,7 @@ Cond = dyn_cast(BI->getCondition()); TI->eraseFromParent(); // Nuke the old one. - if (Cond) ErasePossiblyDeadInstructionTree(Cond); + if (Cond) RecursivelyDeleteTriviallyDeadInstructions(Cond); return true; } return false; @@ -850,7 +818,7 @@ Pred->getInstList().erase(PTI); // If the condition is dead now, remove the instruction tree. - if (DeadCond) ErasePossiblyDeadInstructionTree(DeadCond); + if (DeadCond) RecursivelyDeleteTriviallyDeadInstructions(DeadCond); // Okay, last check. If BB is still a successor of PSI, then we must // have an infinite loop case. If so, add an infinitely looping block @@ -1425,7 +1393,7 @@ BI->eraseFromParent(); if (Instruction *BrCondI = dyn_cast(BrCond)) - ErasePossiblyDeadInstructionTree(BrCondI); + RecursivelyDeleteTriviallyDeadInstructions(BrCondI); return true; } @@ -2146,7 +2114,7 @@ // Erase the potentially condition tree that was used to computed the // branch condition. - ErasePossiblyDeadInstructionTree(Cond); + RecursivelyDeleteTriviallyDeadInstructions(Cond); return true; } } From foldr at codedgers.com Thu Nov 27 18:12:09 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Fri, 28 Nov 2008 00:12:09 -0000 Subject: [llvm-commits] [llvm] r60197 - /llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Message-ID: <200811280012.mAS0C9N1022288@zion.cs.uiuc.edu> Author: foldr Date: Thu Nov 27 18:12:09 2008 New Revision: 60197 URL: http://llvm.org/viewvc/llvm-project?rev=60197&view=rev Log: Documentation: clarify what is meant by 'multiple edges'. Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=60197&r1=60196&r2=60197&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Thu Nov 27 18:12:09 2008 @@ -231,7 +231,8 @@ default edge *per language*). When multiple plugins are loaded, their compilation graphs are merged -together. Since multiple edges are not allowed, an edge defined in +together. Since multiple edges that have the same end nodes are not +allowed (i.e. the graph is not a multigraph), an edge defined in several plugins will be replaced by the definition from the plugin that was loaded last. Plugin load order can be controlled by using the plugin priority feature described above. From foldr at codedgers.com Thu Nov 27 18:13:26 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Fri, 28 Nov 2008 00:13:26 -0000 Subject: [llvm-commits] [llvm] r60198 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td tools/llvmc/doc/LLVMC-Reference.rst utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811280013.mAS0DQuw022337@zion.cs.uiuc.edu> Author: foldr Date: Thu Nov 27 18:13:25 2008 New Revision: 60198 URL: http://llvm.org/viewvc/llvm-project?rev=60198&view=rev Log: Add 'hidden' and 'really_hidden' option properties. Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=60198&r1=60197&r2=60198&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Thu Nov 27 18:13:25 2008 @@ -38,10 +38,12 @@ def append_cmd; def forward; def forward_as; -def stop_compilation; -def unpack_values; def help; +def hidden; +def really_hidden; def required; +def stop_compilation; +def unpack_values; // Empty DAG marker. def empty; Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=60198&r1=60197&r2=60198&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Thu Nov 27 18:13:25 2008 @@ -353,6 +353,12 @@ - ``required`` - this option is obligatory. + - ``hidden`` - this option should not appear in the ``--help`` + output (but should appear in the ``--help-hidden`` output). + + - ``really_hidden`` - the option should not appear in any help + output. + Option list - specifying all options in a single place ====================================================== Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60198&r1=60197&r2=60198&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Thu Nov 27 18:13:25 2008 @@ -198,7 +198,8 @@ // Global option description. namespace GlobalOptionDescriptionFlags { - enum GlobalOptionDescriptionFlags { Required = 0x1 }; + enum GlobalOptionDescriptionFlags { Required = 0x1, Hidden = 0x2, + ReallyHidden = 0x4 }; } struct GlobalOptionDescription : public OptionDescription { @@ -222,6 +223,20 @@ Flags |= GlobalOptionDescriptionFlags::Required; } + bool isHidden() const { + return Flags & GlobalOptionDescriptionFlags::Hidden; + } + void setHidden() { + Flags |= GlobalOptionDescriptionFlags::Hidden; + } + + bool isReallyHidden() const { + return Flags & GlobalOptionDescriptionFlags::ReallyHidden; + } + void setReallyHidden() { + Flags |= GlobalOptionDescriptionFlags::ReallyHidden; + } + /// Merge - Merge two option descriptions. void Merge (const GlobalOptionDescription& other) { @@ -412,8 +427,12 @@ &CollectOptionProperties::onForwardAs; optionPropertyHandlers_["help"] = &CollectOptionProperties::onHelp; + optionPropertyHandlers_["hidden"] = + &CollectOptionProperties::onHidden; optionPropertyHandlers_["output_suffix"] = &CollectOptionProperties::onOutputSuffix; + optionPropertyHandlers_["really_hidden"] = + &CollectOptionProperties::onReallyHidden; optionPropertyHandlers_["required"] = &CollectOptionProperties::onRequired; optionPropertyHandlers_["stop_compilation"] = @@ -493,6 +512,18 @@ optDesc_.Help = help_message; } + void onHidden (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + optDesc_.setHidden(); + } + + void onReallyHidden (const DagInit* d) { + checkNumberOfArguments(d, 0); + checkToolProps(d); + optDesc_.setReallyHidden(); + } + void onRequired (const DagInit* d) { checkNumberOfArguments(d, 0); checkToolProps(d); @@ -1413,6 +1444,17 @@ } } + if (val.isReallyHidden() || val.isHidden()) { + if (val.isRequired()) + O << " |"; + else + O << ","; + if (val.isReallyHidden()) + O << " cl::ReallyHidden"; + else + O << " cl::Hidden"; + } + if (!val.Help.empty()) O << ", cl::desc(\"" << val.Help << "\")"; From foldr at codedgers.com Thu Nov 27 18:13:47 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Fri, 28 Nov 2008 00:13:47 -0000 Subject: [llvm-commits] [llvm] r60199 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200811280013.mAS0DlgN022357@zion.cs.uiuc.edu> Author: foldr Date: Thu Nov 27 18:13:47 2008 New Revision: 60199 URL: http://llvm.org/viewvc/llvm-project?rev=60199&view=rev Log: Support multiple compilation graph definitions. Not terribly useful, but makes the code more generic. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60199&r1=60198&r2=60199&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Thu Nov 27 18:13:47 2008 @@ -1539,20 +1539,18 @@ /// on all edges do match. This doesn't do much when the information /// about the whole graph is not available (i.e. when compiling most /// plugins). -// TODO: add a --check-graph switch to llvmc2. It would also make it -// possible to detect cycles and multiple default edges. -void TypecheckGraph (const Record* CompilationGraph, +void TypecheckGraph (const RecordVector& EdgeVector, const ToolPropertiesList& TPList) { StringMap > ToolToInLang; StringMap ToolToOutLang; FillInToolToLang(TPList, ToolToInLang, ToolToOutLang); - ListInit* edges = CompilationGraph->getValueAsListInit("edges"); StringMap::iterator IAE = ToolToOutLang.end(); StringMap >::iterator IBE = ToolToInLang.end(); - for (unsigned i = 0; i < edges->size(); ++i) { - const Record* Edge = edges->getElementAsRecord(i); + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); StringMap::iterator IA = ToolToOutLang.find(A); @@ -1613,31 +1611,28 @@ } /// EmitEdgeClasses - Emit Edge* classes that represent graph edges. -void EmitEdgeClasses (const Record* CompilationGraph, +void EmitEdgeClasses (const RecordVector& EdgeVector, const GlobalOptionDescriptions& OptDescs, std::ostream& O) { - ListInit* edges = CompilationGraph->getValueAsListInit("edges"); - - for (unsigned i = 0; i < edges->size(); ++i) { - const Record* Edge = edges->getElementAsRecord(i); + int i = 0; + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); - if (isDagEmpty(Weight)) - continue; - - EmitEdgeClass(i, B, Weight, OptDescs, O); + if (!isDagEmpty(Weight)) + EmitEdgeClass(i, B, Weight, OptDescs, O); + ++i; } } /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() /// function. -void EmitPopulateCompilationGraph (const Record* CompilationGraph, +void EmitPopulateCompilationGraph (const RecordVector& EdgeVector, const ToolPropertiesList& ToolProps, std::ostream& O) { - ListInit* edges = CompilationGraph->getValueAsListInit("edges"); - O << "namespace {\n\n"; O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n"; @@ -1649,8 +1644,10 @@ // Insert edges. - for (unsigned i = 0; i < edges->size(); ++i) { - const Record* Edge = edges->getElementAsRecord(i); + int i = 0; + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); @@ -1663,6 +1660,7 @@ O << "new Edge" << i << "()"; O << ");\n"; + ++i; } O << "}\n\n}\n\n"; @@ -1796,15 +1794,16 @@ /// FilterNotInGraph - Filter out from ToolProps all Tools not /// mentioned in the compilation graph definition. -void FilterNotInGraph (const Record* CompilationGraph, +void FilterNotInGraph (const RecordVector& EdgeVector, ToolPropertiesList& ToolProps) { // List all tools mentioned in the graph. llvm::StringSet<> ToolsInGraph; - ListInit* edges = CompilationGraph->getValueAsListInit("edges"); - for (unsigned i = 0; i < edges->size(); ++i) { - const Record* Edge = edges->getElementAsRecord(i); + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + + const Record* Edge = *B; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); @@ -1820,6 +1819,7 @@ ToolProps.erase(new_end, ToolProps.end()); } +/// CalculatePriority - Calculate the priority of this plugin. int CalculatePriority(RecordVector::const_iterator B, RecordVector::const_iterator E) { int total = 0; @@ -1829,6 +1829,18 @@ return total; } +/// FillInEdgeVector - Merge all compilation graph definitions into +/// one single edge list. +void FillInEdgeVector(RecordVector::const_iterator B, + RecordVector::const_iterator E, RecordVector& Out) { + for (; B != E; ++B) { + const ListInit* edges = (*B)->getValueAsListInit("edges"); + + for (unsigned i = 0; i < edges->size(); ++i) + Out.push_back(edges->getElementAsRecord(i)); + } +} + // End of anonymous namespace } @@ -1840,33 +1852,30 @@ EmitSourceFileHeader("LLVMC Configuration Library", O); EmitIncludes(O); - // Get a list of all defined Tools. - + // Collect tool properties. RecordVector Tools = Records.getAllDerivedDefinitions("Tool"); - if (Tools.empty()) - throw std::string("No tool definitions found!"); - - // Gather information from the Tool description dags. ToolPropertiesList ToolProps; GlobalOptionDescriptions OptDescs; CollectToolProperties(Tools.begin(), Tools.end(), ToolProps, OptDescs); + // Collect option properties. const RecordVector& OptionLists = Records.getAllDerivedDefinitions("OptionList"); CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(), OptDescs); - // TOTHINK: Nothing actually prevents us from having multiple - // compilation graphs in a single plugin; OTOH, I do not see how - // that could be useful. - const Record* CompilationGraphRecord = Records.getDef("CompilationGraph"); - if (!CompilationGraphRecord) - throw std::string("Compilation graph description not found!"); + // Collect compilation graph edges. + const RecordVector& CompilationGraphs = + Records.getAllDerivedDefinitions("CompilationGraph"); + RecordVector EdgeVector; + FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(), + EdgeVector); - FilterNotInGraph(CompilationGraphRecord, ToolProps); + // Filter out all tools not mentioned in the compilation graph. + FilterNotInGraph(EdgeVector, ToolProps); // Typecheck the compilation graph. - TypecheckGraph(CompilationGraphRecord, ToolProps); + TypecheckGraph(EdgeVector, ToolProps); // Check that there are no options without side effects (specified // only in the OptionList). @@ -1888,16 +1897,16 @@ EmitToolClassDefinition(*(*B), OptDescs, O); // Emit Edge# classes. - EmitEdgeClasses(CompilationGraphRecord, OptDescs, O); + EmitEdgeClasses(EdgeVector, OptDescs, O); // Emit PopulateCompilationGraph() function. - EmitPopulateCompilationGraph(CompilationGraphRecord, ToolProps, O); + EmitPopulateCompilationGraph(EdgeVector, ToolProps, O); // Emit code for plugin registration. const RecordVector& Priorities = Records.getAllDerivedDefinitions("PluginPriority"); - EmitRegisterPlugin(CalculatePriority(Priorities.begin(), Priorities.end()), - O); + EmitRegisterPlugin(CalculatePriority(Priorities.begin(), + Priorities.end()), O); // EOF } catch (std::exception& Error) { From foldr at codedgers.com Thu Nov 27 18:14:11 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Fri, 28 Nov 2008 00:14:11 -0000 Subject: [llvm-commits] [llvm] r60200 - /llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Message-ID: <200811280014.mAS0ECr5022378@zion.cs.uiuc.edu> Author: foldr Date: Thu Nov 27 18:14:11 2008 New Revision: 60200 URL: http://llvm.org/viewvc/llvm-project?rev=60200&view=rev Log: Scrap some boilerplate. Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?rev=60200&r1=60199&r2=60200&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Thu Nov 27 18:14:11 2008 @@ -5,53 +5,33 @@ include "llvm/CompilerDriver/Common.td" - def Options : OptionList<[ (switch_option "E", (help "Stop after the preprocessing stage, do not run the compiler")) ]>; -class clang_base : Tool< +class clang_based : Tool< [(in_language language), (out_language "llvm-bitcode"), (output_suffix "bc"), - (cmd_line cmdline), + (cmd_line (case + (switch_on "E"), + (case + (not_empty "o"), + !strconcat(cmd, " -E $INFILE -o $OUTFILE"), + (default), + !strconcat(cmd, " -E $INFILE")), + (default), + !strconcat(cmd, " -emit-llvm-bc $INFILE -o $OUTFILE"))), (switch_option "E", (stop_compilation), (output_suffix "i")), (sink) ]>; -def clang_c : clang_base<"c", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x c $INFILE -o $OUTFILE", - (default), - "clang -E -x c $INFILE"), -(default), - "clang -emit-llvm-bc -x c $INFILE -o $OUTFILE")>; - -def clang_cpp : clang_base<"c++", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x c++ $INFILE -o $OUTFILE", - (default), - "clang -E -x c++ $INFILE"), -(default), - "clang -emit-llvm-bc -x c++ $INFILE -o $OUTFILE")>; - -def clang_objective_c : clang_base<"objective-c", -(case -(switch_on "E"), - (case - (not_empty "o"), - "clang -E -x objective-c $INFILE -o $OUTFILE", - (default), - "clang -E -x objective-c $INFILE"), -(default), - "clang -emit-llvm-bc -x objective-c $INFILE -o $OUTFILE")>; +def clang_c : clang_based<"c", "clang -x c">; +def clang_cpp : clang_based<"c++", "clang -x c++">; +def clang_objective_c : clang_based<"objective-c", "clang -x objective-c">; +def clang_objective_cpp : clang_based<"objective-c++", + "clang -x objective-c++">; // Default linker def llvm_ld : Tool< From sabre at nondot.org Thu Nov 27 18:27:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 00:27:14 -0000 Subject: [llvm-commits] [llvm] r60201 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200811280027.mAS0RE5i022776@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 18:27:14 2008 New Revision: 60201 URL: http://llvm.org/viewvc/llvm-project?rev=60201&view=rev Log: rewrite a big chunk of how DSE does recursive dead operand elimination to use more modern infrastructure. Also do a bunch of small cleanups. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60201&r1=60200&r2=60201&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Thu Nov 27 18:27:14 2008 @@ -22,7 +22,6 @@ #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -49,17 +48,14 @@ } bool runOnBasicBlock(BasicBlock &BB); - bool handleFreeWithNonTrivialDependency(FreeInst* F, - Instruction* dependency, - SetVector& possiblyDead); - bool handleEndBlock(BasicBlock& BB, SetVector& possiblyDead); + bool handleFreeWithNonTrivialDependency(FreeInst *F, Instruction *Dep); + bool handleEndBlock(BasicBlock &BB); bool RemoveUndeadPointers(Value* pointer, uint64_t killPointerSize, BasicBlock::iterator& BBI, - SmallPtrSet& deadPointers, - SetVector& possiblyDead); - void DeleteDeadInstructionChains(Instruction *I, - SetVector &DeadInsts); - + SmallPtrSet& deadPointers); + void DeleteDeadInstruction(Instruction *I, + SmallPtrSet *deadPointers = 0); + // getAnalysisUsage - We require post dominance frontiers (aka Control // Dependence Graph) @@ -87,8 +83,6 @@ // Record the last-seen store to this pointer DenseMap lastStore; - // Record instructions possibly made dead by deleting a store - SetVector possiblyDead; bool MadeChange = false; @@ -127,20 +121,11 @@ continue; } - // Remove it! - MD.removeInstruction(last); - - // DCE instructions only used to calculate that store - if (Instruction* D = dyn_cast(last->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(last->getOperand(1))) - possiblyDead.insert(D); - - last->eraseFromParent(); + // Delete the store and now-dead instructions that feed it. + DeleteDeadInstruction(last); NumFastStores++; deletedStore = true; MadeChange = true; - break; } } @@ -148,9 +133,8 @@ // Handle frees whose dependencies are non-trivial. if (FreeInst* F = dyn_cast(BBI)) { if (!deletedStore) - MadeChange |= handleFreeWithNonTrivialDependency(F, - MD.getDependency(F), - possiblyDead); + MadeChange |= handleFreeWithNonTrivialDependency(F,MD.getDependency(F)); + // No known stores after the free last = 0; } else { @@ -164,19 +148,13 @@ if (!S->isVolatile() && S->getParent() == L->getParent() && S->getPointerOperand() == L->getPointerOperand() && - ( dep == MemoryDependenceAnalysis::None || - dep == MemoryDependenceAnalysis::NonLocal || - DT.dominates(dep, L))) { - if (Instruction* D = dyn_cast(S->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(S->getOperand(1))) - possiblyDead.insert(D); + (dep == MemoryDependenceAnalysis::None || + dep == MemoryDependenceAnalysis::NonLocal || + DT.dominates(dep, L))) { // Avoid iterator invalidation. - BBI--; - - MD.removeInstruction(S); - S->eraseFromParent(); + BBI++; + DeleteDeadInstruction(S); NumFastStores++; MadeChange = true; } else @@ -191,25 +169,16 @@ // If this block ends in a return, unwind, unreachable, and eventually // tailcall, then all allocas are dead at its end. if (BB.getTerminator()->getNumSuccessors() == 0) - MadeChange |= handleEndBlock(BB, possiblyDead); - - // Do a trivial DCE - while (!possiblyDead.empty()) { - Instruction *I = possiblyDead.back(); - possiblyDead.pop_back(); - DeleteDeadInstructionChains(I, possiblyDead); - } + MadeChange |= handleEndBlock(BB); return MadeChange; } /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose -/// dependency is a store to a field of that structure -bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, Instruction* dep, - SetVector& possiblyDead) { +/// dependency is a store to a field of that structure. +bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, Instruction* dep) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); - MemoryDependenceAnalysis& MD = getAnalysis(); if (dep == MemoryDependenceAnalysis::None || dep == MemoryDependenceAnalysis::NonLocal) @@ -229,22 +198,13 @@ AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0U, depPointer, depPointerSize); - if (A == AliasAnalysis::MustAlias) { - // Remove it! - MD.removeInstruction(dependency); - - // DCE instructions only used to calculate that store - if (Instruction* D = dyn_cast(dependency->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(dependency->getOperand(1))) - possiblyDead.insert(D); - - dependency->eraseFromParent(); - NumFastStores++; - return true; - } + if (A != AliasAnalysis::MustAlias) + return false; - return false; + // DCE instructions only used to calculate that store + DeleteDeadInstruction(dependency); + NumFastStores++; + return true; } /// handleEndBlock - Remove dead stores to stack-allocated locations in the @@ -253,22 +213,23 @@ /// ... /// store i32 1, i32* %A /// ret void -bool DSE::handleEndBlock(BasicBlock& BB, - SetVector& possiblyDead) { +bool DSE::handleEndBlock(BasicBlock &BB) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); - MemoryDependenceAnalysis& MD = getAnalysis(); bool MadeChange = false; // Pointers alloca'd in this function are dead in the end block SmallPtrSet deadPointers; - // Find all of the alloca'd pointers in the entry block + // Find all of the alloca'd pointers in the entry block. BasicBlock *Entry = BB.getParent()->begin(); for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(I)) deadPointers.insert(AI); + + // Treat byval arguments the same, stores to them are dead at the end of the + // function. for (Function::arg_iterator AI = BB.getParent()->arg_begin(), AE = BB.getParent()->arg_end(); AI != AE; ++AI) if (AI->hasByValAttr()) @@ -278,7 +239,7 @@ for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){ --BBI; - // If we find a store whose pointer is dead... + // If we find a store whose pointer is dead. if (StoreInst* S = dyn_cast(BBI)) { if (!S->isVolatile()) { // See through pointer-to-pointer bitcasts @@ -287,71 +248,45 @@ // Alloca'd pointers or byval arguments (which are functionally like // alloca's) are valid candidates for removal. if (deadPointers.count(pointerOperand)) { - // Remove it! - MD.removeInstruction(S); - - // DCE instructions only used to calculate that store - if (Instruction* D = dyn_cast(S->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(S->getOperand(1))) - possiblyDead.insert(D); - + // DCE instructions only used to calculate that store. BBI++; - MD.removeInstruction(S); - S->eraseFromParent(); + DeleteDeadInstruction(S, &deadPointers); NumFastStores++; MadeChange = true; } } continue; + } - // We can also remove memcpy's to local variables at the end of a function - } else if (MemCpyInst* M = dyn_cast(BBI)) { - Value* dest = M->getDest()->getUnderlyingObject(); + // We can also remove memcpy's to local variables at the end of a function. + if (MemCpyInst *M = dyn_cast(BBI)) { + Value *dest = M->getDest()->getUnderlyingObject(); if (deadPointers.count(dest)) { - MD.removeInstruction(M); - - // DCE instructions only used to calculate that memcpy - if (Instruction* D = dyn_cast(M->getRawSource())) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(M->getLength())) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(M->getRawDest())) - possiblyDead.insert(D); - BBI++; - M->eraseFromParent(); + DeleteDeadInstruction(M, &deadPointers); NumFastOther++; MadeChange = true; - continue; } - // Because a memcpy is also a load, we can't skip it if we didn't remove it + // Because a memcpy is also a load, we can't skip it if we didn't remove + // it. } Value* killPointer = 0; uint64_t killPointerSize = ~0UL; // If we encounter a use of the pointer, it is no longer considered dead - if (LoadInst* L = dyn_cast(BBI)) { + if (LoadInst *L = dyn_cast(BBI)) { // However, if this load is unused and not volatile, we can go ahead and // remove it, and not have to worry about it making our pointer undead! if (L->use_empty() && !L->isVolatile()) { - MD.removeInstruction(L); - - // DCE instructions only used to calculate that load - if (Instruction* D = dyn_cast(L->getPointerOperand())) - possiblyDead.insert(D); - BBI++; - L->eraseFromParent(); + DeleteDeadInstruction(L, &deadPointers); NumFastOther++; MadeChange = true; - possiblyDead.remove(L); - continue; } @@ -368,17 +303,10 @@ // Dead alloca's can be DCE'd when we reach them if (A->use_empty()) { - MD.removeInstruction(A); - - // DCE instructions only used to calculate that load - if (Instruction* D = dyn_cast(A->getArraySize())) - possiblyDead.insert(D); - BBI++; - A->eraseFromParent(); + DeleteDeadInstruction(A, &deadPointers); NumFastOther++; MadeChange = true; - possiblyDead.remove(A); } continue; @@ -434,25 +362,14 @@ deadPointers.erase(*I); continue; - } else { + } else if (isInstructionTriviallyDead(BBI)) { // For any non-memory-affecting non-terminators, DCE them as we reach them - Instruction *CI = BBI; - if (!CI->isTerminator() && CI->use_empty() && !isa(CI)) { - - // DCE instructions only used to calculate that load - for (Instruction::op_iterator OI = CI->op_begin(), OE = CI->op_end(); - OI != OE; ++OI) - if (Instruction* D = dyn_cast(OI)) - possiblyDead.insert(D); - - BBI++; - CI->eraseFromParent(); - NumFastOther++; - MadeChange = true; - possiblyDead.remove(CI); - - continue; - } + Instruction *Inst = BBI; + BBI++; + DeleteDeadInstruction(Inst, &deadPointers); + NumFastOther++; + MadeChange = true; + continue; } if (!killPointer) @@ -462,7 +379,7 @@ // Deal with undead pointers MadeChange |= RemoveUndeadPointers(killPointer, killPointerSize, BBI, - deadPointers, possiblyDead); + deadPointers); } return MadeChange; @@ -471,38 +388,36 @@ /// RemoveUndeadPointers - check for uses of a pointer that make it /// undead when scanning for dead stores to alloca's. bool DSE::RemoveUndeadPointers(Value* killPointer, uint64_t killPointerSize, - BasicBlock::iterator& BBI, - SmallPtrSet& deadPointers, - SetVector& possiblyDead) { + BasicBlock::iterator &BBI, + SmallPtrSet& deadPointers) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); - MemoryDependenceAnalysis& MD = getAnalysis(); // If the kill pointer can be easily reduced to an alloca, - // don't bother doing extraneous AA queries + // don't bother doing extraneous AA queries. if (deadPointers.count(killPointer)) { deadPointers.erase(killPointer); return false; - } else if (isa(killPointer)) { - // A global can't be in the dead pointer set - return false; } + // A global can't be in the dead pointer set. + if (isa(killPointer)) + return false; + bool MadeChange = false; - std::vector undead; + SmallVector undead; for (SmallPtrSet::iterator I = deadPointers.begin(), E = deadPointers.end(); I != E; ++I) { - // Get size information for the alloca + // Get size information for the alloca. unsigned pointerSize = ~0U; if (AllocaInst* A = dyn_cast(*I)) { if (ConstantInt* C = dyn_cast(A->getArraySize())) - pointerSize = C->getZExtValue() * \ + pointerSize = C->getZExtValue() * TD.getABITypeSize(A->getAllocatedType()); } else { - const PointerType* PT = cast( - cast(*I)->getType()); + const PointerType* PT = cast(cast(*I)->getType()); pointerSize = TD.getABITypeSize(PT->getElementType()); } @@ -515,56 +430,65 @@ StoreInst* S = cast(BBI); // Remove it! - MD.removeInstruction(S); - - // DCE instructions only used to calculate that store - if (Instruction* D = dyn_cast(S->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(S->getOperand(1))) - possiblyDead.insert(D); - BBI++; - S->eraseFromParent(); + DeleteDeadInstruction(S, &deadPointers); NumFastStores++; MadeChange = true; continue; // Otherwise, it is undead - } else if (A != AliasAnalysis::NoAlias) - undead.push_back(*I); + } else if (A != AliasAnalysis::NoAlias) + undead.push_back(*I); } - for (std::vector::iterator I = undead.begin(), E = undead.end(); + for (SmallVector::iterator I = undead.begin(), E = undead.end(); I != E; ++I) deadPointers.erase(*I); return MadeChange; } -/// DeleteDeadInstructionChains - takes an instruction and a setvector of -/// dead instructions. If I is dead, it is erased, and its operands are -/// checked for deadness. If they are dead, they are added to the dead -/// setvector. -void DSE::DeleteDeadInstructionChains(Instruction *I, - SetVector &DeadInsts) { - // Instruction must be dead. - if (!I->use_empty() || !isInstructionTriviallyDead(I)) return; - - // Let the memory dependence know - getAnalysis().removeInstruction(I); - - // See if this made any operands dead. We do it this way in case the - // instruction uses the same operand twice. We don't want to delete a - // value then reference it. - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - if (I->getOperand(i)->hasOneUse()) - if (Instruction* Op = dyn_cast(I->getOperand(i))) - DeadInsts.insert(Op); // Attempt to nuke it later. +/// DeleteDeadInstruction - Delete this instruction. Before we do, go through +/// and zero out all the operands of this instruction. If any of them become +/// dead, delete them and the computation tree that feeds them. +/// +/// If ValueSet is non-null, remove any deleted instructions from it as well. +/// +void DSE::DeleteDeadInstruction(Instruction *I, + SmallPtrSet *ValueSet) { + SmallVector NowDeadInsts; + + NowDeadInsts.push_back(I); + --NumFastOther; + + // Before we touch this instruction, remove it from memdep! + MemoryDependenceAnalysis &MDA = getAnalysis(); + while (!NowDeadInsts.empty()) { + Instruction *DeadInst = NowDeadInsts.back(); + NowDeadInsts.pop_back(); + + ++NumFastOther; + + // This instruction is dead, zap it, in stages. Start by removing it from + // MemDep, which needs to know the operands and needs it to be in the + // function. + MDA.removeInstruction(DeadInst); - I->setOperand(i, 0); // Drop from the operand list. + for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) { + Value *Op = DeadInst->getOperand(op); + DeadInst->setOperand(op, 0); + + // If this operand just became dead, add it to the NowDeadInsts list. + if (!Op->use_empty()) continue; + + if (Instruction *OpI = dyn_cast(Op)) + if (isInstructionTriviallyDead(OpI)) + NowDeadInsts.push_back(OpI); + } + + DeadInst->eraseFromParent(); + + if (ValueSet) ValueSet->erase(DeadInst); } - - I->eraseFromParent(); - ++NumFastOther; } From sabre at nondot.org Thu Nov 27 18:58:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 00:58:15 -0000 Subject: [llvm-commits] [llvm] r60202 - /llvm/trunk/lib/Transforms/Utils/Local.cpp Message-ID: <200811280058.mAS0wFUU023585@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 18:58:15 2008 New Revision: 60202 URL: http://llvm.org/viewvc/llvm-project?rev=60202&view=rev Log: remove some weirdness that came from the LSR code that has nothing to do with dead instruction elimination. No tests in dejagnu depend on this, so I don't know what it was needed for. Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60202&r1=60201&r2=60202&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 18:58:15 2008 @@ -190,14 +190,7 @@ while (!Insts.empty()) { I = *Insts.begin(); Insts.erase(I); - - // If this is a PHI node, we may be able to make it dead if we know all the - // input values are the same. - if (PHINode *PN = dyn_cast(I)) { - if (Value *PNV = PN->hasConstantValue()) - PN->replaceAllUsesWith(PNV); - } - + // Okay, if the instruction is dead, delete it. if (!isInstructionTriviallyDead(I)) continue; From sabre at nondot.org Thu Nov 27 19:20:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 01:20:46 -0000 Subject: [llvm-commits] [llvm] r60203 - /llvm/trunk/lib/Transforms/Utils/Local.cpp Message-ID: <200811280120.mAS1KkmZ024179@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 27 19:20:46 2008 New Revision: 60203 URL: http://llvm.org/viewvc/llvm-project?rev=60203&view=rev Log: rewrite RecursivelyDeleteTriviallyDeadInstructions to use a more efficient formulation that doesn't require set lookups or scanning a set. Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=60203&r1=60202&r2=60203&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Nov 27 19:20:46 2008 @@ -22,7 +22,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" -#include "llvm/ADT/SmallPtrSet.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -182,26 +181,37 @@ void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V, SmallVectorImpl *DeadInst) { Instruction *I = dyn_cast(V); - if (!I || !I->use_empty()) return; + if (!I || !I->use_empty() || !isInstructionTriviallyDead(I)) + return; - SmallPtrSet Insts; - Insts.insert(I); + SmallVector DeadInsts; + DeadInsts.push_back(I); - while (!Insts.empty()) { - I = *Insts.begin(); - Insts.erase(I); - - // Okay, if the instruction is dead, delete it. - if (!isInstructionTriviallyDead(I)) - continue; - - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Instruction *U = dyn_cast(I->getOperand(i))) - Insts.insert(U); - I->eraseFromParent(); - + while (!DeadInsts.empty()) { + I = DeadInsts.back(); + DeadInsts.pop_back(); + + // If the client wanted to know, tell it about deleted instructions. if (DeadInst) DeadInst->push_back(I); + + // Null out all of the instruction's operands to see if any operand becomes + // dead as we go. + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + Value *OpV = I->getOperand(i); + I->setOperand(i, 0); + + if (!OpV->use_empty()) continue; + + // If the operand is an instruction that became dead as we nulled out the + // operand, and if it is 'trivially' dead, delete it in a future loop + // iteration. + if (Instruction *OpI = dyn_cast(OpV)) + if (isInstructionTriviallyDead(OpI)) + DeadInsts.push_back(OpI); + } + + I->eraseFromParent(); } } From baldrick at free.fr Fri Nov 28 03:29:39 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 28 Nov 2008 09:29:39 -0000 Subject: [llvm-commits] [llvm] r60208 - in /llvm/trunk/lib/Target/X86: X86Subtarget.cpp X86Subtarget.h X86TargetMachine.cpp Message-ID: <200811280929.mAS9Tdjx018009@zion.cs.uiuc.edu> Author: baldrick Date: Fri Nov 28 03:29:37 2008 New Revision: 60208 URL: http://llvm.org/viewvc/llvm-project?rev=60208&view=rev Log: Fix build with gcc-4.4: it doesn't like PICStyle being both a namespace and a variable name. Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.h llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60208&r1=60207&r2=60208&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Fri Nov 28 03:29:37 2008 @@ -239,7 +239,7 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) : AsmFlavor(AsmWriterFlavor) - , PICStyle(PICStyle::None) + , PICStyle(PICStyles::None) , X86SSELevel(NoMMXSSE) , X863DNowLevel(NoThreeDNow) , HasX86_64(false) Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=60208&r1=60207&r2=60208&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Fri Nov 28 03:29:37 2008 @@ -23,7 +23,7 @@ class GlobalValue; class TargetMachine; -namespace PICStyle { +namespace PICStyles { enum Style { Stub, GOT, RIPRel, WinPIC, None }; @@ -51,7 +51,7 @@ /// PICStyle - Which PIC style to use /// - PICStyle::Style PICStyle; + PICStyles::Style PICStyle; /// X86SSELevel - MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or /// none supported. @@ -114,8 +114,8 @@ bool is64Bit() const { return Is64Bit; } - PICStyle::Style getPICStyle() const { return PICStyle; } - void setPICStyle(PICStyle::Style Style) { PICStyle = Style; } + PICStyles::Style getPICStyle() const { return PICStyle; } + void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } bool hasMMX() const { return X86SSELevel >= MMX; } bool hasSSE1() const { return X86SSELevel >= SSE1; } @@ -160,11 +160,11 @@ return std::string(p); } - bool isPICStyleSet() const { return PICStyle != PICStyle::None; } - bool isPICStyleGOT() const { return PICStyle == PICStyle::GOT; } - bool isPICStyleStub() const { return PICStyle == PICStyle::Stub; } - bool isPICStyleRIPRel() const { return PICStyle == PICStyle::RIPRel; } - bool isPICStyleWinPIC() const { return PICStyle == PICStyle:: WinPIC; } + bool isPICStyleSet() const { return PICStyle != PICStyles::None; } + bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } + bool isPICStyleStub() const { return PICStyle == PICStyles::Stub; } + bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } + bool isPICStyleWinPIC() const { return PICStyle == PICStyles:: WinPIC; } /// getDarwinVers - Return the darwin version number, 8 = tiger, 9 = leopard. unsigned getDarwinVers() const { return DarwinVers; } Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=60208&r1=60207&r2=60208&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Fri Nov 28 03:29:37 2008 @@ -162,17 +162,17 @@ } if (Subtarget.isTargetCygMing()) - Subtarget.setPICStyle(PICStyle::WinPIC); + Subtarget.setPICStyle(PICStyles::WinPIC); else if (Subtarget.isTargetDarwin()) { if (Subtarget.is64Bit()) - Subtarget.setPICStyle(PICStyle::RIPRel); + Subtarget.setPICStyle(PICStyles::RIPRel); else - Subtarget.setPICStyle(PICStyle::Stub); + Subtarget.setPICStyle(PICStyles::Stub); } else if (Subtarget.isTargetELF()) { if (Subtarget.is64Bit()) - Subtarget.setPICStyle(PICStyle::RIPRel); + Subtarget.setPICStyle(PICStyles::RIPRel); else - Subtarget.setPICStyle(PICStyle::GOT); + Subtarget.setPICStyle(PICStyles::GOT); } } From baldrick at free.fr Fri Nov 28 04:20:14 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 28 Nov 2008 10:20:14 -0000 Subject: [llvm-commits] [llvm] r60209 - in /llvm/trunk/lib/Target/PIC16: PIC16ISelLowering.cpp PIC16InstrInfo.cpp Message-ID: <200811281020.mASAKHwh020131@zion.cs.uiuc.edu> Author: baldrick Date: Fri Nov 28 04:20:03 2008 New Revision: 60209 URL: http://llvm.org/viewvc/llvm-project?rev=60209&view=rev Log: Add include files needed when building with gcc 4.4 (due to use of sprintf). Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=60209&r1=60208&r2=60209&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Fri Nov 28 04:20:03 2008 @@ -21,6 +21,7 @@ #include "llvm/Function.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" +#include using namespace llvm; Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=60209&r1=60208&r2=60209&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Fri Nov 28 04:20:03 2008 @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include using namespace llvm; From espindola at google.com Fri Nov 28 09:31:51 2008 From: espindola at google.com (Rafael Espindola) Date: Fri, 28 Nov 2008 15:31:51 +0000 Subject: [llvm-commits] [patch] print ".file" directives Message-ID: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> The attached patch fixes bug 3140 by printing the module name in the .file directive. This adds very minimal debug info for the simple case of a C (or C++) file compile one at a time. The only thing I am not sure about is if it is always safe to add the .file directive. I have tried on linux (GNU assembler version 2.18.0), and darwin ppc (cctools-622.9~2, GNU assembler version 1.38). Can someone with another assembler check if it is OK? Thanks, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: file.patch Type: text/x-diff Size: 775 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081128/2de67f09/attachment.bin From tilmann.scheller at googlemail.com Fri Nov 28 11:03:03 2008 From: tilmann.scheller at googlemail.com (Tilmann Scheller) Date: Fri, 28 Nov 2008 18:03:03 +0100 Subject: [llvm-commits] [Patch] Custom Lowering for TRUNCATE Message-ID: Hi, the attached patch enables custom lowering for TRUNCATE (needed in order to custom lower TRUNCATE on CellSPU) Greetings, Tilmann -------------- next part -------------- A non-text attachment was scrubbed... Name: customLowerTruncate.patch Type: text/x-patch Size: 599 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081128/ed2fab6c/attachment.bin From sabre at nondot.org Fri Nov 28 13:54:50 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 19:54:50 -0000 Subject: [llvm-commits] [llvm] r60210 - in /llvm/trunk: lib/Transforms/Scalar/CodeGenPrepare.cpp lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/2008-11-28-InfLoop.ll Message-ID: <200811281954.mASJspF8006591@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 13:54:49 2008 New Revision: 60210 URL: http://llvm.org/viewvc/llvm-project?rev=60210&view=rev Log: don't call MergeBasicBlockIntoOnlyPred on a block whose only predecessor is itself. This doesn't make sense, and this is a dead infinite loop anyway. Added: llvm/trunk/test/Transforms/JumpThreading/2008-11-28-InfLoop.ll Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=60210&r1=60209&r2=60210&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Fri Nov 28 13:54:49 2008 @@ -205,16 +205,18 @@ // If the destination block has a single pred, then this is a trivial edge, // just collapse it. if (BasicBlock *SinglePred = DestBB->getSinglePredecessor()) { - // Remember if SinglePred was the entry block of the function. If so, we - // will need to move BB back to the entry position. - bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); - MergeBasicBlockIntoOnlyPred(DestBB); + if (SinglePred != DestBB) { + // Remember if SinglePred was the entry block of the function. If so, we + // will need to move BB back to the entry position. + bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); + MergeBasicBlockIntoOnlyPred(DestBB); - if (isEntry && BB != &BB->getParent()->getEntryBlock()) - BB->moveBefore(&BB->getParent()->getEntryBlock()); - - DOUT << "AFTER:\n" << *DestBB << "\n\n\n"; - return; + if (isEntry && BB != &BB->getParent()->getEntryBlock()) + BB->moveBefore(&BB->getParent()->getEntryBlock()); + + DOUT << "AFTER:\n" << *DestBB << "\n\n\n"; + return; + } } // Otherwise, we have multiple predecessors of BB. Update the PHIs in DestBB Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60210&r1=60209&r2=60210&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Fri Nov 28 13:54:49 2008 @@ -164,7 +164,8 @@ // because now the condition in this block can be threaded through // predecessors of our predecessor block. if (BasicBlock *SinglePred = BB->getSinglePredecessor()) - if (SinglePred->getTerminator()->getNumSuccessors() == 1) { + if (SinglePred->getTerminator()->getNumSuccessors() == 1 && + SinglePred != BB) { // Remember if SinglePred was the entry block of the function. If so, we // will need to move BB back to the entry position. bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); Added: llvm/trunk/test/Transforms/JumpThreading/2008-11-28-InfLoop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/2008-11-28-InfLoop.ll?rev=60210&view=auto ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/2008-11-28-InfLoop.ll (added) +++ llvm/trunk/test/Transforms/JumpThreading/2008-11-28-InfLoop.ll Fri Nov 28 13:54:49 2008 @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -jump-threading | llvm-dis + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" + %struct.decContext = type { i32 } + %struct.decNumber = type { i32, i32 } + +define i32 @decNumberPower(%struct.decNumber* %res, %struct.decNumber* %lhs, %struct.decNumber* %rhs, %struct.decContext* %set) nounwind { +entry: + br i1 true, label %decDivideOp.exit, label %bb7.i + +bb7.i: ; preds = %bb7.i, %entry + br label %bb7.i + +decDivideOp.exit: ; preds = %entry + ret i32 undef +} From sabre at nondot.org Fri Nov 28 15:16:48 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:16:48 -0000 Subject: [llvm-commits] [llvm] r60211 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811282116.mASLGmst009097@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:16:44 2008 New Revision: 60211 URL: http://llvm.org/viewvc/llvm-project?rev=60211&view=rev Log: remove mysterious escaped newlines. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60211&r1=60210&r2=60211&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 15:16:44 2008 @@ -120,7 +120,7 @@ } else if (AllocationInst* AI = dyn_cast(QI)) { pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) - pointerSize = C->getZExtValue() * \ + pointerSize = C->getZExtValue() * TD.getABITypeSize(AI->getAllocatedType()); else pointerSize = ~0UL; @@ -398,7 +398,7 @@ } else if (AllocationInst* AI = dyn_cast(QI)) { pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) - pointerSize = C->getZExtValue() * \ + pointerSize = C->getZExtValue() * TD.getABITypeSize(AI->getAllocatedType()); else pointerSize = ~0UL; @@ -533,9 +533,9 @@ if (RI == (BasicBlock::iterator)rem) RI++; newDep = RI; - } else if ( (depGraphEntry->second.first == NonLocal || - depGraphEntry->second.first == None ) && - depGraphEntry->second.second ) { + } else if ((depGraphEntry->second.first == NonLocal || + depGraphEntry->second.first == None) && + depGraphEntry->second.second) { // If we have a confirmed non-local flag, use it newDep = depGraphEntry->second.first; } else { From sabre at nondot.org Fri Nov 28 15:29:54 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:29:54 -0000 Subject: [llvm-commits] [llvm] r60213 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200811282129.mASLTsag009561@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:29:52 2008 New Revision: 60213 URL: http://llvm.org/viewvc/llvm-project?rev=60213&view=rev Log: simplify some code, remove escaped newline. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60213&r1=60212&r2=60213&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 15:29:52 2008 @@ -87,37 +87,38 @@ bool MadeChange = false; // Do a top-down walk on the BB - for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); - BBI != BBE; ++BBI) { + for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ) { + Instruction *Inst = BBI++; + // If we find a store or a free... - if (!isa(BBI) && !isa(BBI)) + if (!isa(Inst) && !isa(Inst)) continue; Value* pointer = 0; - if (StoreInst* S = dyn_cast(BBI)) { + if (StoreInst* S = dyn_cast(Inst)) { if (S->isVolatile()) continue; pointer = S->getPointerOperand(); } else { - pointer = cast(BBI)->getPointerOperand(); + pointer = cast(Inst)->getPointerOperand(); } pointer = pointer->stripPointerCasts(); - StoreInst*& last = lastStore[pointer]; - bool deletedStore = false; - + StoreInst *&last = lastStore[pointer]; + // ... to a pointer that has been stored to before... if (last) { - Instruction* dep = MD.getDependency(BBI); - + Instruction* dep = MD.getDependency(Inst); + bool deletedStore = false; + // ... and no other memory dependencies are between them.... while (dep != MemoryDependenceAnalysis::None && dep != MemoryDependenceAnalysis::NonLocal && isa(dep)) { if (dep != last || TD.getTypeStoreSize(last->getOperand(0)->getType()) > - TD.getTypeStoreSize(BBI->getOperand(0)->getType())) { - dep = MD.getDependency(BBI, dep); + TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { + dep = MD.getDependency(Inst, dep); continue; } @@ -128,21 +129,27 @@ MadeChange = true; break; } + + // If we deleted a store, reinvestigate this instruction. + if (deletedStore) { + --BBI; + continue; + } } // Handle frees whose dependencies are non-trivial. - if (FreeInst* F = dyn_cast(BBI)) { - if (!deletedStore) - MadeChange |= handleFreeWithNonTrivialDependency(F,MD.getDependency(F)); + if (FreeInst* F = dyn_cast(Inst)) { + MadeChange |= handleFreeWithNonTrivialDependency(F, MD.getDependency(F)); - // No known stores after the free + // No known stores after the free. last = 0; } else { - StoreInst* S = cast(BBI); + StoreInst* S = cast(Inst); // If we're storing the same value back to a pointer that we just // loaded from, then the store can be removed; if (LoadInst* L = dyn_cast(S->getOperand(0))) { + // FIXME: Don't do dep query if Parents don't match and other stuff! Instruction* dep = MD.getDependency(S); DominatorTree& DT = getAnalysis(); @@ -152,9 +159,8 @@ dep == MemoryDependenceAnalysis::NonLocal || DT.dominates(dep, L))) { - // Avoid iterator invalidation. - BBI++; DeleteDeadInstruction(S); + --BBI; NumFastStores++; MadeChange = true; } else @@ -166,8 +172,8 @@ } } - // If this block ends in a return, unwind, unreachable, and eventually - // tailcall, then all allocas are dead at its end. + // If this block ends in a return, unwind, or unreachable, all allocas are + // dead at its end, which means stores to them are also dead. if (BB.getTerminator()->getNumSuccessors() == 0) MadeChange |= handleEndBlock(BB); @@ -337,7 +343,7 @@ unsigned pointerSize = ~0U; if (AllocaInst* A = dyn_cast(*I)) { if (ConstantInt* C = dyn_cast(A->getArraySize())) - pointerSize = C->getZExtValue() * \ + pointerSize = C->getZExtValue() * TD.getABITypeSize(A->getAllocatedType()); } else { const PointerType* PT = cast( From sabre at nondot.org Fri Nov 28 15:36:43 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:36:43 -0000 Subject: [llvm-commits] [llvm] r60214 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200811282136.mASLahXQ009770@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:36:43 2008 New Revision: 60214 URL: http://llvm.org/viewvc/llvm-project?rev=60214&view=rev Log: comment and indentation improvements. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60214&r1=60213&r2=60214&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 15:36:43 2008 @@ -7,10 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines an analysis that determines, for a given memory operation, -// what preceding memory operations it depends on. It builds on alias analysis -// information, and tries to provide a lazy, caching interface to a common kind -// of alias information query. +// This file defines the MemoryDependenceAnalysis analysis pass. // //===----------------------------------------------------------------------===// @@ -21,15 +18,17 @@ #include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Support/Compiler.h" namespace llvm { - -class Function; -class FunctionPass; -class Instruction; - -class MemoryDependenceAnalysis : public FunctionPass { + class Function; + class FunctionPass; + class Instruction; + + /// MemoryDependenceAnalysis - This is an analysis that determines, for a + /// given memory operation, what preceding memory operations it depends on. + /// It builds on alias analysis information, and tries to provide a lazy, + /// caching interface to a common kind of alias information query. + class MemoryDependenceAnalysis : public FunctionPass { private: // A map from instructions to their dependency, with a boolean // flags for whether this mapping is confirmed or not @@ -61,7 +60,6 @@ // Special marker indicating that the query has no dependency at all static Instruction* const None; - // Special marker indicating a dirty cache entry static Instruction* const Dirty; From sabre at nondot.org Fri Nov 28 15:42:10 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:42:10 -0000 Subject: [llvm-commits] [llvm] r60215 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811282142.mASLgAY1009943@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:42:09 2008 New Revision: 60215 URL: http://llvm.org/viewvc/llvm-project?rev=60215&view=rev Log: rename "ping" to "verifyRemoved". I don't know why 'ping' what chosen, but it doesn't make any sense at all. Also make the method const, private, and fit in 80 cols while we're at it. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60215&r1=60214&r2=60215&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 15:42:09 2008 @@ -51,8 +51,6 @@ reverseDepMapType reverseDepNonLocal; public: - void ping(Instruction* D); - // Special marker indicating that the query has no dependency // in the specified block. static Instruction* const NonLocal; @@ -104,6 +102,10 @@ void dropInstruction(Instruction* drop); private: + /// verifyRemoved - Verify that the specified instruction does not occur + /// in our internal data structures. + void verifyRemoved(Instruction *Inst) const; + Instruction* getCallSiteDependency(CallSite C, Instruction* start, BasicBlock* block); void nonLocalHelper(Instruction* query, BasicBlock* block, Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60215&r1=60214&r2=60215&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 15:42:09 2008 @@ -48,31 +48,32 @@ static RegisterPass X("memdep", "Memory Dependence Analysis", false, true); -void MemoryDependenceAnalysis::ping(Instruction *D) { - for (depMapType::iterator I = depGraphLocal.begin(), E = depGraphLocal.end(); - I != E; ++I) { +void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { + for (depMapType::const_iterator I = depGraphLocal.begin(), + E = depGraphLocal.end(); I != E; ++I) { assert(I->first != D); assert(I->second.first != D); } - for (nonLocalDepMapType::iterator I = depGraphNonLocal.begin(), E = depGraphNonLocal.end(); - I != E; ++I) { + for (nonLocalDepMapType::const_iterator I = depGraphNonLocal.begin(), + E = depGraphNonLocal.end(); I != E; ++I) { assert(I->first != D); for (DenseMap::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) assert(II->second != D); } - for (reverseDepMapType::iterator I = reverseDep.begin(), E = reverseDep.end(); - I != E; ++I) - for (SmallPtrSet::iterator II = I->second.begin(), EE = I->second.end(); - II != EE; ++II) + for (reverseDepMapType::const_iterator I = reverseDep.begin(), + E = reverseDep.end(); I != E; ++I) + for (SmallPtrSet::const_iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) assert(*II != D); - for (reverseDepMapType::iterator I = reverseDepNonLocal.begin(), E = reverseDepNonLocal.end(); + for (reverseDepMapType::const_iterator I = reverseDepNonLocal.begin(), + E = reverseDepNonLocal.end(); I != E; ++I) - for (SmallPtrSet::iterator II = I->second.begin(), EE = I->second.end(); - II != EE; ++II) + for (SmallPtrSet::const_iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) assert(*II != D); } From sabre at nondot.org Fri Nov 28 15:45:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:45:17 -0000 Subject: [llvm-commits] [llvm] r60216 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811282145.mASLjHUt010064@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:45:17 2008 New Revision: 60216 URL: http://llvm.org/viewvc/llvm-project?rev=60216&view=rev Log: Run verifyRemoved from removeInstruction when -debug is specified. This shows the root problem behind PR3141. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60216&r1=60215&r2=60216&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 15:45:17 2008 @@ -14,6 +14,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "memdep" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" @@ -21,11 +22,10 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/Statistic.h" -#define DEBUG_TYPE "memdep" - using namespace llvm; // Control the calculation of non-local dependencies by only examining the @@ -46,35 +46,37 @@ // Register this pass... static RegisterPass X("memdep", - "Memory Dependence Analysis", false, true); + "Memory Dependence Analysis", false, true); +/// verifyRemoved - Verify that the specified instruction does not occur +/// in our internal data structures. void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { for (depMapType::const_iterator I = depGraphLocal.begin(), E = depGraphLocal.end(); I != E; ++I) { - assert(I->first != D); - assert(I->second.first != D); + assert(I->first != D && "Inst occurs in data structures"); + assert(I->second.first != D && "Inst occurs in data structures"); } for (nonLocalDepMapType::const_iterator I = depGraphNonLocal.begin(), E = depGraphNonLocal.end(); I != E; ++I) { - assert(I->first != D); + assert(I->first != D && "Inst occurs in data structures"); for (DenseMap::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) - assert(II->second != D); + assert(II->second != D && "Inst occurs in data structures"); } for (reverseDepMapType::const_iterator I = reverseDep.begin(), E = reverseDep.end(); I != E; ++I) for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) - assert(*II != D); + assert(*II != D && "Inst occurs in data structures"); for (reverseDepMapType::const_iterator I = reverseDepNonLocal.begin(), E = reverseDepNonLocal.end(); I != E; ++I) for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) - assert(*II != D); + assert(*II != D && "Inst occurs in data structures"); } /// getAnalysisUsage - Does not modify anything. It uses Alias Analysis. @@ -88,7 +90,7 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, - Instruction* start, + Instruction* start, BasicBlock* block) { std::pair& cachedResult = @@ -586,4 +588,6 @@ depGraphNonLocal.erase(I); getAnalysis().deleteValue(rem); + + DEBUG(verifyRemoved(rem)); } From sabre at nondot.org Fri Nov 28 15:47:19 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 21:47:19 -0000 Subject: [llvm-commits] [llvm] r60217 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200811282147.mASLlJsG010127@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 15:47:19 2008 New Revision: 60217 URL: http://llvm.org/viewvc/llvm-project?rev=60217&view=rev Log: forward declare CallSite instead of #includ'ing it. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60217&r1=60216&r2=60217&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 15:47:19 2008 @@ -15,7 +15,6 @@ #define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H #include "llvm/Pass.h" -#include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" @@ -23,6 +22,7 @@ class Function; class FunctionPass; class Instruction; + class CallSite; /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. @@ -32,8 +32,7 @@ private: // A map from instructions to their dependency, with a boolean // flags for whether this mapping is confirmed or not - typedef DenseMap > - depMapType; + typedef DenseMap > depMapType; depMapType depGraphLocal; // A map from instructions to their non-local dependencies. @@ -43,8 +42,7 @@ // A reverse mapping form dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. - typedef DenseMap > - reverseDepMapType; + typedef DenseMap > reverseDepMapType; reverseDepMapType reverseDep; // A reverse mapping form dependencies to the non-local dependees. From sabre at nondot.org Fri Nov 28 16:04:47 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 22:04:47 -0000 Subject: [llvm-commits] [llvm] r60218 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811282204.mASM4l84010654@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 16:04:47 2008 New Revision: 60218 URL: http://llvm.org/viewvc/llvm-project?rev=60218&view=rev Log: random cleanups, no functionality change. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60218&r1=60217&r2=60218&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 16:04:47 2008 @@ -510,55 +510,57 @@ /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. -void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) { +void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { // Figure out the new dep for things that currently depend on rem Instruction* newDep = NonLocal; + // Walk through the Non-local dependencies, removing this one as the value + // for any cached queries. for (DenseMap::iterator DI = - depGraphNonLocal[rem].begin(), DE = depGraphNonLocal[rem].end(); + depGraphNonLocal[RemInst].begin(), DE = depGraphNonLocal[RemInst].end(); DI != DE; ++DI) if (DI->second != None) - reverseDepNonLocal[DI->second].erase(rem); - - depMapType::iterator depGraphEntry = depGraphLocal.find(rem); + reverseDepNonLocal[DI->second].erase(RemInst); + // If we have a cached local dependence query for this instruction, remove it. + depMapType::iterator depGraphEntry = depGraphLocal.find(RemInst); if (depGraphEntry != depGraphLocal.end()) { - reverseDep[depGraphEntry->second.first].erase(rem); + Instruction *DepInst = depGraphEntry->second.first; + bool IsConfirmed = depGraphEntry->second.second; + + reverseDep[DepInst].erase(RemInst); - if (depGraphEntry->second.first != NonLocal && - depGraphEntry->second.first != None && - depGraphEntry->second.second) { + if (DepInst != NonLocal && DepInst != None && IsConfirmed) { // If we have dep info for rem, set them to it - BasicBlock::iterator RI = depGraphEntry->second.first; + BasicBlock::iterator RI = DepInst; RI++; // If RI is rem, then we use rem's immediate successor. - if (RI == (BasicBlock::iterator)rem) RI++; + if (RI == (BasicBlock::iterator)RemInst) RI++; newDep = RI; - } else if ((depGraphEntry->second.first == NonLocal || - depGraphEntry->second.first == None) && - depGraphEntry->second.second) { + } else if ((DepInst == NonLocal || DepInst == None) && IsConfirmed) { // If we have a confirmed non-local flag, use it - newDep = depGraphEntry->second.first; + newDep = DepInst; } else { // Otherwise, use the immediate successor of rem // NOTE: This is because, when getDependence is called, it will first // check the immediate predecessor of what is in the cache. - BasicBlock::iterator RI = rem; + BasicBlock::iterator RI = RemInst; RI++; newDep = RI; } + depGraphLocal.erase(RemInst); } else { // Otherwise, use the immediate successor of rem // NOTE: This is because, when getDependence is called, it will first // check the immediate predecessor of what is in the cache. - BasicBlock::iterator RI = rem; + BasicBlock::iterator RI = RemInst; RI++; newDep = RI; } - SmallPtrSet& set = reverseDep[rem]; + SmallPtrSet& set = reverseDep[RemInst]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) { // Insert the new dependencies @@ -567,27 +569,24 @@ newDep == None)); } - depGraphLocal.erase(rem); - reverseDep.erase(rem); + reverseDep.erase(RemInst); - if (reverseDepNonLocal.count(rem)) { - SmallPtrSet& set = reverseDepNonLocal[rem]; + if (reverseDepNonLocal.count(RemInst)) { + SmallPtrSet& set = reverseDepNonLocal[RemInst]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap::iterator DI = depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); DI != DE; ++DI) - if (DI->second == rem) + if (DI->second == RemInst) DI->second = Dirty; } - reverseDepNonLocal.erase(rem); - nonLocalDepMapType::iterator I = depGraphNonLocal.find(rem); - if (I != depGraphNonLocal.end()) - depGraphNonLocal.erase(I); + reverseDepNonLocal.erase(RemInst); + depGraphNonLocal.erase(RemInst); - getAnalysis().deleteValue(rem); + getAnalysis().deleteValue(RemInst); - DEBUG(verifyRemoved(rem)); + DEBUG(verifyRemoved(RemInst)); } From sabre at nondot.org Fri Nov 28 16:28:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 22:28:27 -0000 Subject: [llvm-commits] [llvm] r60219 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811282228.mASMSRCF011431@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 16:28:27 2008 New Revision: 60219 URL: http://llvm.org/viewvc/llvm-project?rev=60219&view=rev Log: more cleanups for MemoryDependenceAnalysis::removeInstruction, no functionality change. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60219&r1=60218&r2=60219&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 16:28:27 2008 @@ -20,11 +20,12 @@ #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" -#include "llvm/ADT/Statistic.h" using namespace llvm; @@ -511,9 +512,6 @@ /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { - // Figure out the new dep for things that currently depend on rem - Instruction* newDep = NonLocal; - // Walk through the Non-local dependencies, removing this one as the value // for any cached queries. for (DenseMap::iterator DI = @@ -522,51 +520,57 @@ if (DI->second != None) reverseDepNonLocal[DI->second].erase(RemInst); + // Shortly after this, we will look for things that depend on RemInst. In + // order to update these, we'll need a new dependency to base them on. We + // could completely delete any entries that depend on this, but it is better + // to make a more accurate approximation where possible. Compute that better + // approximation if we can. + Instruction *NewDependency = 0; + bool NewDependencyConfirmed = false; + // If we have a cached local dependence query for this instruction, remove it. - depMapType::iterator depGraphEntry = depGraphLocal.find(RemInst); - if (depGraphEntry != depGraphLocal.end()) { - Instruction *DepInst = depGraphEntry->second.first; - bool IsConfirmed = depGraphEntry->second.second; - - reverseDep[DepInst].erase(RemInst); - - if (DepInst != NonLocal && DepInst != None && IsConfirmed) { - // If we have dep info for rem, set them to it - BasicBlock::iterator RI = DepInst; - RI++; - - // If RI is rem, then we use rem's immediate successor. - if (RI == (BasicBlock::iterator)RemInst) RI++; - - newDep = RI; - } else if ((DepInst == NonLocal || DepInst == None) && IsConfirmed) { - // If we have a confirmed non-local flag, use it - newDep = DepInst; - } else { - // Otherwise, use the immediate successor of rem - // NOTE: This is because, when getDependence is called, it will first - // check the immediate predecessor of what is in the cache. - BasicBlock::iterator RI = RemInst; - RI++; - newDep = RI; + // + depMapType::iterator LocalDepEntry = depGraphLocal.find(RemInst); + if (LocalDepEntry != depGraphLocal.end()) { + Instruction *LocalDepInst = LocalDepEntry->second.first; + bool IsConfirmed = LocalDepEntry->second.second; + + // Remove this local dependency info. + depGraphLocal.erase(LocalDepEntry); + + // Remove us from DepInst's reverse set now that the local dep info is gone. + reverseDep[LocalDepInst].erase(RemInst); + + // If we have unconfirmed info, don't trust it. + if (IsConfirmed) { + // If we have a confirmed non-local flag, use it. + if (LocalDepInst == NonLocal || LocalDepInst == None) { + NewDependency = LocalDepInst; + NewDependencyConfirmed = true; + } else { + // If we have dep info for RemInst, set them to it. + NewDependency = next(BasicBlock::iterator(LocalDepInst)); + + // Don't use RI for the new dependency! + if (NewDependency == RemInst) + NewDependency = 0; + } } - depGraphLocal.erase(RemInst); - } else { - // Otherwise, use the immediate successor of rem - // NOTE: This is because, when getDependence is called, it will first - // check the immediate predecessor of what is in the cache. - BasicBlock::iterator RI = RemInst; - RI++; - newDep = RI; } + // If we don't already have a local dependency answer for this instruction, + // use the immediate successor of RemInst. We use the successor because + // getDependence starts by checking the immediate predecessor of what is in + // the cache. + if (NewDependency == 0) + NewDependency = next(BasicBlock::iterator(RemInst)); + SmallPtrSet& set = reverseDep[RemInst]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) { // Insert the new dependencies // Mark it as unconfirmed as long as it is not the non-local flag - depGraphLocal[*I] = std::make_pair(newDep, (newDep == NonLocal || - newDep == None)); + depGraphLocal[*I] = std::make_pair(NewDependency, NewDependencyConfirmed); } reverseDep.erase(RemInst); From sabre at nondot.org Fri Nov 28 16:41:36 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 22:41:36 -0000 Subject: [llvm-commits] [llvm] r60220 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200811282241.mASMfbAc011823@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 16:41:36 2008 New Revision: 60220 URL: http://llvm.org/viewvc/llvm-project?rev=60220&view=rev Log: comment cleanups. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60220&r1=60219&r2=60220&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 16:41:36 2008 @@ -31,16 +31,16 @@ class MemoryDependenceAnalysis : public FunctionPass { private: // A map from instructions to their dependency, with a boolean - // flags for whether this mapping is confirmed or not + // flags for whether this mapping is confirmed or not. typedef DenseMap > depMapType; depMapType depGraphLocal; // A map from instructions to their non-local dependencies. - typedef DenseMap > - nonLocalDepMapType; + typedef DenseMap > nonLocalDepMapType; nonLocalDepMapType depGraphNonLocal; - // A reverse mapping form dependencies to the dependees. This is + // A reverse mapping from dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. typedef DenseMap > reverseDepMapType; reverseDepMapType reverseDep; From sabre at nondot.org Fri Nov 28 16:50:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 22:50:08 -0000 Subject: [llvm-commits] [llvm] r60221 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200811282250.mASMo8tx012055@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 16:50:08 2008 New Revision: 60221 URL: http://llvm.org/viewvc/llvm-project?rev=60221&view=rev Log: don't revisit instructions off the beginning of the block. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60221&r1=60220&r2=60221&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 16:50:08 2008 @@ -132,7 +132,8 @@ // If we deleted a store, reinvestigate this instruction. if (deletedStore) { - --BBI; + if (!isa(BB.begin())) + --BBI; continue; } } @@ -160,7 +161,8 @@ DT.dominates(dep, L))) { DeleteDeadInstruction(S); - --BBI; + if (!isa(BB.begin())) + --BBI; NumFastStores++; MadeChange = true; } else From sabre at nondot.org Fri Nov 28 16:51:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 22:51:08 -0000 Subject: [llvm-commits] [llvm] r60222 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll Message-ID: <200811282251.mASMp8Oh012096@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 16:51:08 2008 New Revision: 60222 URL: http://llvm.org/viewvc/llvm-project?rev=60222&view=rev Log: Fix PR3141 by ensuring that MemoryDependenceAnalysis::removeInstruction properly updates the reverse dependency map when it installs updated dependencies for instructions that depend on the removed instruction. Added: llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60222&r1=60221&r2=60222&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 16:51:08 2008 @@ -545,6 +545,7 @@ if (IsConfirmed) { // If we have a confirmed non-local flag, use it. if (LocalDepInst == NonLocal || LocalDepInst == None) { + // The only time this dependency is confirmed is if it is non-local. NewDependency = LocalDepInst; NewDependencyConfirmed = true; } else { @@ -565,18 +566,34 @@ if (NewDependency == 0) NewDependency = next(BasicBlock::iterator(RemInst)); - SmallPtrSet& set = reverseDep[RemInst]; - for (SmallPtrSet::iterator I = set.begin(), E = set.end(); - I != E; ++I) { - // Insert the new dependencies - // Mark it as unconfirmed as long as it is not the non-local flag - depGraphLocal[*I] = std::make_pair(NewDependency, NewDependencyConfirmed); + // Loop over all of the things that depend on the instruction we're removing. + // + reverseDepMapType::iterator ReverseDepIt = reverseDep.find(RemInst); + if (ReverseDepIt != reverseDep.end()) { + SmallPtrSet &ReverseDeps = ReverseDepIt->second; + for (SmallPtrSet::iterator I = ReverseDeps.begin(), + E = ReverseDeps.end(); I != E; ++I) { + Instruction *InstDependingOnRemInst = *I; + + // If we thought the instruction depended on itself (possible for + // unconfirmed dependencies) ignore the update. + if (InstDependingOnRemInst == RemInst) continue; + + // Insert the new dependencies. + depGraphLocal[InstDependingOnRemInst] = + std::make_pair(NewDependency, NewDependencyConfirmed); + + // If our NewDependency is an instruction, make sure to remember that new + // things depend on it. + if (NewDependency != NonLocal && NewDependency != None) + reverseDep[NewDependency].insert(InstDependingOnRemInst); + } + reverseDep.erase(RemInst); } - reverseDep.erase(RemInst); - - if (reverseDepNonLocal.count(RemInst)) { - SmallPtrSet& set = reverseDepNonLocal[RemInst]; + ReverseDepIt = reverseDepNonLocal.find(RemInst); + if (ReverseDepIt != reverseDepNonLocal.end()) { + SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap::iterator DI = @@ -584,10 +601,9 @@ DI != DE; ++DI) if (DI->second == RemInst) DI->second = Dirty; - + reverseDepNonLocal.erase(RemInst); } - reverseDepNonLocal.erase(RemInst); depGraphNonLocal.erase(RemInst); getAnalysis().deleteValue(RemInst); Added: llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll?rev=60222&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-28-MemDepUpdate.ll Fri Nov 28 16:51:08 2008 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -dse | llvm-dis +; PR3141 + %struct.ada__tags__dispatch_table = type { [1 x i32] } + %struct.f393a00_1__object = type { %struct.ada__tags__dispatch_table*, i8 } + %struct.f393a00_2__windmill = type { %struct.f393a00_1__object, i16 } + +define void @f393a00_2__swap(%struct.f393a00_2__windmill* %a, %struct.f393a00_2__windmill* %b) { +entry: + %t = alloca %struct.f393a00_2__windmill ; <%struct.f393a00_2__windmill*> [#uses=1] + %0 = getelementptr %struct.f393a00_2__windmill* %t, i32 0, i32 0, i32 0 ; <%struct.ada__tags__dispatch_table**> [#uses=1] + %1 = load %struct.ada__tags__dispatch_table** null, align 4 ; <%struct.ada__tags__dispatch_table*> [#uses=1] + %2 = load %struct.ada__tags__dispatch_table** %0, align 8 ; <%struct.ada__tags__dispatch_table*> [#uses=1] + store %struct.ada__tags__dispatch_table* %2, %struct.ada__tags__dispatch_table** null, align 4 + store %struct.ada__tags__dispatch_table* %1, %struct.ada__tags__dispatch_table** null, align 4 + ret void +} From sabre at nondot.org Fri Nov 28 17:31:45 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 23:31:45 -0000 Subject: [llvm-commits] [llvm] r60224 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811282331.mASNVk7w013374@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 17:31:44 2008 New Revision: 60224 URL: http://llvm.org/viewvc/llvm-project?rev=60224&view=rev Log: add a generic "bitmangled pointer" class, which allows a parameterized pointer and integer type to be used. Added: llvm/trunk/include/llvm/ADT/PointerIntPair.h Added: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60224&view=auto ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (added) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Fri Nov 28 17:31:44 2008 @@ -0,0 +1,69 @@ +//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PointerIntPair class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_POINTERINTPAIR_H +#define LLVM_ADT_POINTERINTPAIR_H + +#include + +namespace llvm { + +/// PointerIntPair - This class implements a pair of a pointer and small +/// integer. It is designed to represet this in the space required by one +/// pointer by bitmangling the integer into the low part of the pointer. This +/// can only be done for small integers: typically up to 3 bits, but it depends +/// on the alignment returned by the allocator in use. +/// +template +class PointerIntPair { + intptr_t Value; +public: + PointerIntPair() : Value(0) {} + PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { + setPointer(Ptr); + setInt(Int); + } + + PointerTy getPointer() const { + return reinterpret_cast(Value & ~((1 << IntBits)-1)); + } + + IntType getInt() const { + return (IntType)(Value & (1 << IntBits)-1); + } + + void setPointer(PointerTy Ptr) { + intptr_t PtrVal = reinterpret_cast(Ptr); + assert((PtrVal & (1 << IntBits)-1) == 0 && + "Pointer is no sufficiently aligned"); + Value = PtrVal | (intptr_t)getInt(); + } + + void setInt(IntType Int) { + assert(Int < (1 << IntBits) && "Integer too large for field"); + Value |= reinterpret_cast(getPointer()) | (intptr_t)Int; + } + + void *getOpaqueValue() const { return reinterpret_cast(Value); } + void setFromOpaqueValue(void *Val) { Value = reinterpret_cast(Val);} + + bool operator==(const PointerIntPair &RHS) const { + return Value == RHS.Value; + } + bool operator!=(const PointerIntPair &RHS) const { + return Value != RHS.Value; + } +}; + +} // end namespace llvm +#endif From sabre at nondot.org Fri Nov 28 17:36:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 23:36:15 -0000 Subject: [llvm-commits] [llvm] r60225 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811282336.mASNaG8N013514@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 17:36:15 2008 New Revision: 60225 URL: http://llvm.org/viewvc/llvm-project?rev=60225&view=rev Log: fix a bug. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60225&r1=60224&r2=60225&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Fri Nov 28 17:36:15 2008 @@ -51,7 +51,7 @@ void setInt(IntType Int) { assert(Int < (1 << IntBits) && "Integer too large for field"); - Value |= reinterpret_cast(getPointer()) | (intptr_t)Int; + Value = reinterpret_cast(getPointer()) | (intptr_t)Int; } void *getOpaqueValue() const { return reinterpret_cast(Value); } From sabre at nondot.org Fri Nov 28 17:57:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 Nov 2008 23:57:26 -0000 Subject: [llvm-commits] [llvm] r60227 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811282357.mASNvQNd014212@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 17:57:26 2008 New Revision: 60227 URL: http://llvm.org/viewvc/llvm-project?rev=60227&view=rev Log: fix comment typo Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60227&r1=60226&r2=60227&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Fri Nov 28 17:57:26 2008 @@ -19,7 +19,7 @@ namespace llvm { /// PointerIntPair - This class implements a pair of a pointer and small -/// integer. It is designed to represet this in the space required by one +/// integer. It is designed to represent this in the space required by one /// pointer by bitmangling the integer into the low part of the pointer. This /// can only be done for small integers: typically up to 3 bits, but it depends /// on the alignment returned by the allocator in use. From sabre at nondot.org Fri Nov 28 19:18:07 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 01:18:07 -0000 Subject: [llvm-commits] [llvm] r60228 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811290118.mAT1I8v9016571@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 19:18:05 2008 New Revision: 60228 URL: http://llvm.org/viewvc/llvm-project?rev=60228&view=rev Log: Fix spello, add DenseMapInfo specialization for PointerIntPair. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60228&r1=60227&r2=60228&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Fri Nov 28 19:18:05 2008 @@ -18,6 +18,9 @@ namespace llvm { +template +struct DenseMapInfo; + /// PointerIntPair - This class implements a pair of a pointer and small /// integer. It is designed to represent this in the space required by one /// pointer by bitmangling the integer into the low part of the pointer. This @@ -65,5 +68,24 @@ } }; +// Provide specialization of DenseMapInfo for PointerIntPair. +template +struct DenseMapInfo > { + typedef PointerIntPair Ty; + static Ty getEmptyKey() { + return Ty(reinterpret_cast(-1), + IntType((1 << IntBits)-1)); + } + static Ty getTombstoneKey() { + return Ty(reinterpret_cast(-2), IntType(0)); + } + static unsigned getHashValue(Ty V) { + uintptr_t IV = reinterpret_cast(V.getOpaqueValue()); + return unsigned(IV) ^ unsigned(IV >> 9); + } + static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; } + static bool isPod() { return true; } +}; + } // end namespace llvm #endif From sabre at nondot.org Fri Nov 28 19:36:16 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 01:36:16 -0000 Subject: [llvm-commits] [llvm] r60229 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811290136.mAT1aHWS017110@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 19:36:16 2008 New Revision: 60229 URL: http://llvm.org/viewvc/llvm-project?rev=60229&view=rev Log: Fix sentinels to use correctly 'aligned' pointers. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60229&r1=60228&r2=60229&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Fri Nov 28 19:36:16 2008 @@ -73,11 +73,11 @@ struct DenseMapInfo > { typedef PointerIntPair Ty; static Ty getEmptyKey() { - return Ty(reinterpret_cast(-1), + return Ty(reinterpret_cast(-1 << IntBits), IntType((1 << IntBits)-1)); } static Ty getTombstoneKey() { - return Ty(reinterpret_cast(-2), IntType(0)); + return Ty(reinterpret_cast(-2 << IntBits), IntType(0)); } static unsigned getHashValue(Ty V) { uintptr_t IV = reinterpret_cast(V.getOpaqueValue()); From sabre at nondot.org Fri Nov 28 19:43:37 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 01:43:37 -0000 Subject: [llvm-commits] [llvm] r60230 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <200811290143.mAT1hbgH017361@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 19:43:36 2008 New Revision: 60230 URL: http://llvm.org/viewvc/llvm-project?rev=60230&view=rev Log: Reimplement the internal abstraction used by MemDep in terms of a pointer/int pair instead of a manually bitmangled pointer. This forces clients to think a little more about checking the appropriate pieces and will be useful for internal implementation improvements later. I'm not particularly happy with this. After going through this I don't think that the clients of memdep should be exposed to the internal type at all. I'll fix this in a subsequent commit. This has no functionality change. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60230&r1=60229&r2=60230&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 19:43:36 2008 @@ -17,6 +17,7 @@ #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/PointerIntPair.h" namespace llvm { class Function; @@ -29,38 +30,54 @@ /// It builds on alias analysis information, and tries to provide a lazy, /// caching interface to a common kind of alias information query. class MemoryDependenceAnalysis : public FunctionPass { + public: + /// DepType - This enum is used to indicate what flavor of dependence this + /// is. If the type is Normal, there is an associated instruction pointer. + enum DepType { + /// Normal - This is a normal instruction dependence. The pointer member + /// of the DepResultTy pair holds the instruction. + Normal = 0, + + /// None - This dependence type indicates that the query does not depend + /// on any instructions, either because it scanned to the start of the + /// function or it scanned to the definition of the memory + /// (alloca/malloc). + None, + + /// NonLocal - This marker indicates that the query has no dependency in + /// the specified block. To find out more, the client should query other + /// predecessor blocks. + NonLocal, + + /// Dirty - This is an internal marker indicating that that a cache entry + /// is dirty. + Dirty + }; + typedef PointerIntPair DepResultTy; private: // A map from instructions to their dependency, with a boolean // flags for whether this mapping is confirmed or not. - typedef DenseMap > depMapType; - depMapType depGraphLocal; + typedef DenseMap > LocalDepMapType; + LocalDepMapType LocalDeps; // A map from instructions to their non-local dependencies. typedef DenseMap > nonLocalDepMapType; + DenseMap > nonLocalDepMapType; nonLocalDepMapType depGraphNonLocal; // A reverse mapping from dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. - typedef DenseMap > reverseDepMapType; + typedef DenseMap > reverseDepMapType; reverseDepMapType reverseDep; // A reverse mapping form dependencies to the non-local dependees. reverseDepMapType reverseDepNonLocal; public: - // Special marker indicating that the query has no dependency - // in the specified block. - static Instruction* const NonLocal; - - // Special marker indicating that the query has no dependency at all - static Instruction* const None; - - // Special marker indicating a dirty cache entry - static Instruction* const Dirty; - - static char ID; // Class identification, replacement for typeinfo MemoryDependenceAnalysis() : FunctionPass(&ID) {} + static char ID; /// Pass Implementation stuff. This doesn't do any analysis. /// @@ -68,7 +85,7 @@ /// Clean up memory in between runs void releaseMemory() { - depGraphLocal.clear(); + LocalDeps.clear(); depGraphNonLocal.clear(); reverseDep.clear(); reverseDepNonLocal.clear(); @@ -81,33 +98,33 @@ /// getDependency - Return the instruction on which a memory operation /// depends, starting with start. - Instruction* getDependency(Instruction* query, Instruction* start = 0, - BasicBlock* block = 0); + DepResultTy getDependency(Instruction *query, Instruction *start = 0, + BasicBlock *block = 0); /// getNonLocalDependency - Fills the passed-in map with the non-local /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. void getNonLocalDependency(Instruction* query, - DenseMap& resp); + DenseMap &resp); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. - void removeInstruction(Instruction* rem); + void removeInstruction(Instruction *InstToRemove); /// dropInstruction - Remove an instruction from the analysis, making /// absolutely conservative assumptions when updating the cache. This is /// useful, for example when an instruction is changed rather than removed. - void dropInstruction(Instruction* drop); + void dropInstruction(Instruction *InstToDrop); private: /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - Instruction* getCallSiteDependency(CallSite C, Instruction* start, - BasicBlock* block); + DepResultTy getCallSiteDependency(CallSite C, Instruction* start, + BasicBlock* block); void nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap& resp); + DenseMap& resp); }; } // End llvm namespace Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60230&r1=60229&r2=60230&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 19:43:36 2008 @@ -41,10 +41,6 @@ char MemoryDependenceAnalysis::ID = 0; -Instruction* const MemoryDependenceAnalysis::NonLocal = (Instruction*)-3; -Instruction* const MemoryDependenceAnalysis::None = (Instruction*)-4; -Instruction* const MemoryDependenceAnalysis::Dirty = (Instruction*)-5; - // Register this pass... static RegisterPass X("memdep", "Memory Dependence Analysis", false, true); @@ -52,18 +48,19 @@ /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { - for (depMapType::const_iterator I = depGraphLocal.begin(), - E = depGraphLocal.end(); I != E; ++I) { + for (LocalDepMapType::const_iterator I = LocalDeps.begin(), + E = LocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - assert(I->second.first != D && "Inst occurs in data structures"); + assert(I->second.first.getPointer() != D && + "Inst occurs in data structures"); } for (nonLocalDepMapType::const_iterator I = depGraphNonLocal.begin(), E = depGraphNonLocal.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - for (DenseMap::iterator II = I->second.begin(), + for (DenseMap::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) - assert(II->second != D && "Inst occurs in data structures"); + assert(II->second.getPointer() != D && "Inst occurs in data structures"); } for (reverseDepMapType::const_iterator I = reverseDep.begin(), @@ -90,12 +87,10 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. -Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, - Instruction* start, - BasicBlock* block) { - - std::pair& cachedResult = - depGraphLocal[C.getInstruction()]; +MemoryDependenceAnalysis::DepResultTy +MemoryDependenceAnalysis:: +getCallSiteDependency(CallSite C, Instruction *start, BasicBlock *block) { + std::pair &cachedResult = LocalDeps[C.getInstruction()]; AliasAnalysis& AA = getAnalysis(); TargetData& TD = getAnalysis(); BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin(); @@ -141,11 +136,11 @@ AA.getModRefBehavior(CallSite::get(QI)); if (result != AliasAnalysis::DoesNotAccessMemory) { if (!start && !block) { - cachedResult.first = QI; + cachedResult.first = DepResultTy(QI, Normal); cachedResult.second = true; - reverseDep[QI].insert(C.getInstruction()); + reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); } - return QI; + return DepResultTy(QI, Normal); } else { continue; } @@ -154,33 +149,33 @@ if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) { if (!start && !block) { - cachedResult.first = QI; + cachedResult.first = DepResultTy(QI, Normal); cachedResult.second = true; - reverseDep[QI].insert(C.getInstruction()); + reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); } - return QI; + return DepResultTy(QI, Normal); } } // No dependence found - cachedResult.first = NonLocal; + cachedResult.first = DepResultTy(0, NonLocal); cachedResult.second = true; - reverseDep[NonLocal].insert(C.getInstruction()); - return NonLocal; + reverseDep[DepResultTy(0, NonLocal)].insert(C.getInstruction()); + return DepResultTy(0, NonLocal); } /// nonLocalHelper - Private helper used to calculate non-local dependencies -/// by doing DFS on the predecessors of a block to find its dependencies +/// by doing DFS on the predecessors of a block to find its dependencies. void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap& resp) { + DenseMap &resp) { // Set of blocks that we've already visited in our DFS SmallPtrSet visited; // If we're updating a dirtied cache entry, we don't need to reprocess // already computed entries. - for (DenseMap::iterator I = resp.begin(), + for (DenseMap::iterator I = resp.begin(), E = resp.end(); I != E; ++I) - if (I->second != Dirty) + if (I->second.getInt() != Dirty) visited.insert(I->first); // Current stack of the DFS @@ -204,8 +199,8 @@ if (BB != block) { visited.insert(BB); - Instruction* localDep = getDependency(query, 0, BB); - if (localDep != NonLocal) { + DepResultTy localDep = getDependency(query, 0, BB); + if (localDep.getInt() != NonLocal) { resp.insert(std::make_pair(BB, localDep)); stack.pop_back(); @@ -217,8 +212,8 @@ } else if (BB == block) { visited.insert(BB); - Instruction* localDep = getDependency(query, 0, BB); - if (localDep != query) + DepResultTy localDep = getDependency(query, 0, BB); + if (localDep != DepResultTy(query, Normal)) resp.insert(std::make_pair(BB, localDep)); stack.pop_back(); @@ -246,12 +241,12 @@ // If we didn't insert because we have no predecessors, then this // query has no dependency at all. else if (!inserted && !predOnStack) { - resp.insert(std::make_pair(BB, None)); + resp.insert(std::make_pair(BB, DepResultTy(0, None))); // If we didn't insert because our predecessors are already on the stack, // then we might still have a dependency, but it will be discovered during // backtracking. } else if (!inserted && predOnStack){ - resp.insert(std::make_pair(BB, NonLocal)); + resp.insert(std::make_pair(BB, DepResultTy(0, NonLocal))); } stack.pop_back(); @@ -262,21 +257,21 @@ /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, - DenseMap& resp) { + DenseMap &resp) { if (depGraphNonLocal.count(query)) { - DenseMap& cached = depGraphNonLocal[query]; + DenseMap &cached = depGraphNonLocal[query]; NumCacheNonlocal++; SmallVector dirtied; - for (DenseMap::iterator I = cached.begin(), + for (DenseMap::iterator I = cached.begin(), E = cached.end(); I != E; ++I) - if (I->second == Dirty) + if (I->second.getInt() == Dirty) dirtied.push_back(I->first); for (SmallVector::iterator I = dirtied.begin(), E = dirtied.end(); I != E; ++I) { - Instruction* localDep = getDependency(query, 0, *I); - if (localDep != NonLocal) + DepResultTy localDep = getDependency(query, 0, *I); + if (localDep.getInt() != NonLocal) cached[*I] = localDep; else { cached.erase(*I); @@ -287,8 +282,8 @@ resp = cached; // Update the reverse non-local dependency cache - for (DenseMap::iterator I = resp.begin(), E = resp.end(); - I != E; ++I) + for (DenseMap::iterator I = resp.begin(), + E = resp.end(); I != E; ++I) reverseDepNonLocal[I->second].insert(query); return; @@ -299,8 +294,8 @@ nonLocalHelper(query, query->getParent(), resp); // Update the non-local dependency cache - for (DenseMap::iterator I = resp.begin(), E = resp.end(); - I != E; ++I) { + for (DenseMap::iterator I = resp.begin(), + E = resp.end(); I != E; ++I) { depGraphNonLocal[query].insert(*I); reverseDepNonLocal[I->second].insert(query); } @@ -309,21 +304,24 @@ /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. -Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query, - Instruction* start, - BasicBlock* block) { +MemoryDependenceAnalysis::DepResultTy +MemoryDependenceAnalysis::getDependency(Instruction *query, + Instruction *start, + BasicBlock *block) { // Start looking for dependencies with the queried inst BasicBlock::iterator QI = query; // Check for a cached result - std::pair& cachedResult = depGraphLocal[query]; + std::pair& cachedResult = LocalDeps[query]; // If we have a _confirmed_ cached entry, return it if (!block && !start) { if (cachedResult.second) return cachedResult.first; - else if (cachedResult.first && cachedResult.first != NonLocal) - // If we have an unconfirmed cached entry, we can start our search from there - QI = cachedResult.first; + else if (cachedResult.first.getInt() == Normal && + cachedResult.first.getPointer()) + // If we have an unconfirmed cached entry, we can start our search from + // it. + QI = cachedResult.first.getPointer(); } if (start) @@ -357,9 +355,9 @@ } else if (CallSite::get(query).getInstruction() != 0) return getCallSiteDependency(CallSite::get(query), start, block); else if (isa(query)) - return None; + return DepResultTy(0, None); else - return None; + return DepResultTy(0, None); BasicBlock::iterator blockBegin = block ? block->begin() : query->getParent()->begin(); @@ -375,12 +373,12 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && S->isVolatile()) { if (!start && !block) { - cachedResult.first = S; + cachedResult.first = DepResultTy(S, Normal); cachedResult.second = true; - reverseDep[S].insert(query); + reverseDep[DepResultTy(S, Normal)].insert(query); } - return S; + return DepResultTy(S, Normal); } pointer = S->getPointerOperand(); @@ -389,12 +387,12 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && L->isVolatile()) { if (!start && !block) { - cachedResult.first = L; + cachedResult.first = DepResultTy(L, Normal); cachedResult.second = true; - reverseDep[L].insert(query); + reverseDep[DepResultTy(L, Normal)].insert(query); } - return L; + return DepResultTy(L, Normal); } pointer = L->getPointerOperand(); @@ -417,7 +415,7 @@ } else if (CallSite::get(QI).getInstruction() != 0) { // Call insts need special handling. Check if they can modify our pointer AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI), - dependee, dependeeSize); + dependee, dependeeSize); if (MR != AliasAnalysis::NoModRef) { // Loads don't depend on read-only calls @@ -425,12 +423,11 @@ continue; if (!start && !block) { - cachedResult.first = QI; + cachedResult.first = DepResultTy(QI, Normal); cachedResult.second = true; - reverseDep[QI].insert(query); + reverseDep[DepResultTy(QI, Normal)].insert(query); } - - return QI; + return DepResultTy(QI, Normal); } else { continue; } @@ -448,64 +445,63 @@ continue; if (!start && !block) { - cachedResult.first = QI; + cachedResult.first = DepResultTy(QI, Normal); cachedResult.second = true; - reverseDep[QI].insert(query); + reverseDep[DepResultTy(QI, Normal)].insert(query); } - return QI; + return DepResultTy(QI, Normal); } } } // If we found nothing, return the non-local flag if (!start && !block) { - cachedResult.first = NonLocal; + cachedResult.first = DepResultTy(0, NonLocal); cachedResult.second = true; - reverseDep[NonLocal].insert(query); + reverseDep[DepResultTy(0, NonLocal)].insert(query); } - return NonLocal; + return DepResultTy(0, NonLocal); } /// dropInstruction - Remove an instruction from the analysis, making /// absolutely conservative assumptions when updating the cache. This is /// useful, for example when an instruction is changed rather than removed. void MemoryDependenceAnalysis::dropInstruction(Instruction* drop) { - depMapType::iterator depGraphEntry = depGraphLocal.find(drop); - if (depGraphEntry != depGraphLocal.end()) + LocalDepMapType::iterator depGraphEntry = LocalDeps.find(drop); + if (depGraphEntry != LocalDeps.end()) reverseDep[depGraphEntry->second.first].erase(drop); // Drop dependency information for things that depended on this instr - SmallPtrSet& set = reverseDep[drop]; + SmallPtrSet& set = reverseDep[DepResultTy(drop, Normal)]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) - depGraphLocal.erase(*I); + LocalDeps.erase(*I); - depGraphLocal.erase(drop); - reverseDep.erase(drop); + LocalDeps.erase(drop); + reverseDep.erase(DepResultTy(drop, Normal)); - for (DenseMap::iterator DI = - depGraphNonLocal[drop].begin(), DE = depGraphNonLocal[drop].end(); + for (DenseMap::iterator DI = + depGraphNonLocal[drop].begin(), DE = depGraphNonLocal[drop].end(); DI != DE; ++DI) - if (DI->second != None) + if (DI->second.getInt() != None) reverseDepNonLocal[DI->second].erase(drop); - if (reverseDepNonLocal.count(drop)) { - SmallPtrSet& set = reverseDepNonLocal[drop]; + if (reverseDepNonLocal.count(DepResultTy(drop, Normal))) { + SmallPtrSet& set = + reverseDepNonLocal[DepResultTy(drop, Normal)]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) - for (DenseMap::iterator DI = + for (DenseMap::iterator DI = depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); DI != DE; ++DI) - if (DI->second == drop) - DI->second = Dirty; + if (DI->second == DepResultTy(drop, Normal)) + DI->second = DepResultTy(0, Dirty); } - reverseDepNonLocal.erase(drop); - nonLocalDepMapType::iterator I = depGraphNonLocal.find(drop); - if (I != depGraphNonLocal.end()) - depGraphNonLocal.erase(I); + reverseDepNonLocal.erase(DepResultTy(drop, Normal)); + depGraphNonLocal.erase(drop); } /// removeInstruction - Remove an instruction from the dependence analysis, @@ -514,10 +510,10 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { // Walk through the Non-local dependencies, removing this one as the value // for any cached queries. - for (DenseMap::iterator DI = + for (DenseMap::iterator DI = depGraphNonLocal[RemInst].begin(), DE = depGraphNonLocal[RemInst].end(); DI != DE; ++DI) - if (DI->second != None) + if (DI->second.getInt() != None) reverseDepNonLocal[DI->second].erase(RemInst); // Shortly after this, we will look for things that depend on RemInst. In @@ -525,36 +521,34 @@ // could completely delete any entries that depend on this, but it is better // to make a more accurate approximation where possible. Compute that better // approximation if we can. - Instruction *NewDependency = 0; + DepResultTy NewDependency; bool NewDependencyConfirmed = false; // If we have a cached local dependence query for this instruction, remove it. // - depMapType::iterator LocalDepEntry = depGraphLocal.find(RemInst); - if (LocalDepEntry != depGraphLocal.end()) { - Instruction *LocalDepInst = LocalDepEntry->second.first; + LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); + if (LocalDepEntry != LocalDeps.end()) { + DepResultTy LocalDep = LocalDepEntry->second.first; bool IsConfirmed = LocalDepEntry->second.second; // Remove this local dependency info. - depGraphLocal.erase(LocalDepEntry); + LocalDeps.erase(LocalDepEntry); // Remove us from DepInst's reverse set now that the local dep info is gone. - reverseDep[LocalDepInst].erase(RemInst); + reverseDep[LocalDep].erase(RemInst); // If we have unconfirmed info, don't trust it. if (IsConfirmed) { // If we have a confirmed non-local flag, use it. - if (LocalDepInst == NonLocal || LocalDepInst == None) { + if (LocalDep.getInt() == NonLocal || LocalDep.getInt() == None) { // The only time this dependency is confirmed is if it is non-local. - NewDependency = LocalDepInst; + NewDependency = LocalDep; NewDependencyConfirmed = true; } else { // If we have dep info for RemInst, set them to it. - NewDependency = next(BasicBlock::iterator(LocalDepInst)); - - // Don't use RI for the new dependency! - if (NewDependency == RemInst) - NewDependency = 0; + Instruction *NDI = next(BasicBlock::iterator(LocalDep.getPointer())); + if (NDI != RemInst) // Don't use RemInst for the new dependency! + NewDependency = DepResultTy(NDI, Normal); } } } @@ -563,12 +557,13 @@ // use the immediate successor of RemInst. We use the successor because // getDependence starts by checking the immediate predecessor of what is in // the cache. - if (NewDependency == 0) - NewDependency = next(BasicBlock::iterator(RemInst)); + if (NewDependency == DepResultTy(0, Normal)) + NewDependency = DepResultTy(next(BasicBlock::iterator(RemInst)), Normal); // Loop over all of the things that depend on the instruction we're removing. // - reverseDepMapType::iterator ReverseDepIt = reverseDep.find(RemInst); + reverseDepMapType::iterator ReverseDepIt = + reverseDep.find(DepResultTy(RemInst, Normal)); if (ReverseDepIt != reverseDep.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; for (SmallPtrSet::iterator I = ReverseDeps.begin(), @@ -580,28 +575,29 @@ if (InstDependingOnRemInst == RemInst) continue; // Insert the new dependencies. - depGraphLocal[InstDependingOnRemInst] = + LocalDeps[InstDependingOnRemInst] = std::make_pair(NewDependency, NewDependencyConfirmed); // If our NewDependency is an instruction, make sure to remember that new // things depend on it. - if (NewDependency != NonLocal && NewDependency != None) + // FIXME: Just insert all deps! + if (NewDependency.getInt() != NonLocal && NewDependency.getInt() != None) reverseDep[NewDependency].insert(InstDependingOnRemInst); } - reverseDep.erase(RemInst); + reverseDep.erase(DepResultTy(RemInst, Normal)); } - ReverseDepIt = reverseDepNonLocal.find(RemInst); + ReverseDepIt = reverseDepNonLocal.find(DepResultTy(RemInst, Normal)); if (ReverseDepIt != reverseDepNonLocal.end()) { SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) - for (DenseMap::iterator DI = + for (DenseMap::iterator DI = depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); DI != DE; ++DI) - if (DI->second == RemInst) - DI->second = Dirty; - reverseDepNonLocal.erase(RemInst); + if (DI->second == DepResultTy(RemInst, Normal)) + DI->second = DepResultTy(0, Dirty); + reverseDepNonLocal.erase(ReverseDepIt); } depGraphNonLocal.erase(RemInst); Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60230&r1=60229&r2=60230&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 19:43:36 2008 @@ -46,9 +46,11 @@ Changed |= runOnBasicBlock(*I); return Changed; } + + typedef MemoryDependenceAnalysis::DepResultTy DepResultTy; bool runOnBasicBlock(BasicBlock &BB); - bool handleFreeWithNonTrivialDependency(FreeInst *F, Instruction *Dep); + bool handleFreeWithNonTrivialDependency(FreeInst *F, DepResultTy Dep); bool handleEndBlock(BasicBlock &BB); bool RemoveUndeadPointers(Value* pointer, uint64_t killPointerSize, BasicBlock::iterator& BBI, @@ -108,17 +110,16 @@ // ... to a pointer that has been stored to before... if (last) { - Instruction* dep = MD.getDependency(Inst); + DepResultTy dep = MD.getDependency(Inst); bool deletedStore = false; // ... and no other memory dependencies are between them.... - while (dep != MemoryDependenceAnalysis::None && - dep != MemoryDependenceAnalysis::NonLocal && - isa(dep)) { - if (dep != last || + while (dep.getInt() == MemoryDependenceAnalysis::Normal && + isa(dep.getPointer())) { + if (dep.getPointer() != last || TD.getTypeStoreSize(last->getOperand(0)->getType()) > TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { - dep = MD.getDependency(Inst, dep); + dep = MD.getDependency(Inst, dep.getPointer()); continue; } @@ -151,14 +152,14 @@ // loaded from, then the store can be removed; if (LoadInst* L = dyn_cast(S->getOperand(0))) { // FIXME: Don't do dep query if Parents don't match and other stuff! - Instruction* dep = MD.getDependency(S); + DepResultTy dep = MD.getDependency(S); DominatorTree& DT = getAnalysis(); if (!S->isVolatile() && S->getParent() == L->getParent() && S->getPointerOperand() == L->getPointerOperand() && - (dep == MemoryDependenceAnalysis::None || - dep == MemoryDependenceAnalysis::NonLocal || - DT.dominates(dep, L))) { + (dep.getInt() == MemoryDependenceAnalysis::None || + dep.getInt() == MemoryDependenceAnalysis::NonLocal || + DT.dominates(dep.getPointer(), L))) { DeleteDeadInstruction(S); if (!isa(BB.begin())) @@ -184,15 +185,15 @@ /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose /// dependency is a store to a field of that structure. -bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, Instruction* dep) { +bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, DepResultTy dep) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); - if (dep == MemoryDependenceAnalysis::None || - dep == MemoryDependenceAnalysis::NonLocal) + if (dep.getInt() == MemoryDependenceAnalysis::None || + dep.getInt() == MemoryDependenceAnalysis::NonLocal) return false; - StoreInst* dependency = dyn_cast(dep); + StoreInst* dependency = dyn_cast(dep.getPointer()); if (!dependency) return false; else if (dependency->isVolatile()) Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60230&r1=60229&r2=60230&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Nov 28 19:43:36 2008 @@ -456,19 +456,21 @@ return nextValueNumber++; } - Instruction* local_dep = MD->getDependency(C); + MemoryDependenceAnalysis::DepResultTy local_dep = MD->getDependency(C); - if (local_dep == MemoryDependenceAnalysis::None) { + if (local_dep.getInt() == MemoryDependenceAnalysis::None) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (local_dep != MemoryDependenceAnalysis::NonLocal) { - if (!isa(local_dep)) { + } else if (local_dep.getInt() != MemoryDependenceAnalysis::NonLocal) { + // FIXME: INDENT PROPERLY! + if (!isa(local_dep.getPointer())) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; } - CallInst* local_cdep = cast(local_dep); + CallInst* local_cdep = cast(local_dep.getPointer()); + // FIXME: INDENT PROPERLY. if (local_cdep->getCalledFunction() != C->getCalledFunction() || local_cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); @@ -493,19 +495,20 @@ } - DenseMap deps; + DenseMap deps; MD->getNonLocalDependency(C, deps); CallInst* cdep = 0; - for (DenseMap::iterator I = deps.begin(), - E = deps.end(); I != E; ++I) { - if (I->second == MemoryDependenceAnalysis::None) { + for (DenseMap + ::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { + if (I->second.getInt() == MemoryDependenceAnalysis::None) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (I->second != MemoryDependenceAnalysis::NonLocal) { + } else if (I->second.getInt() != MemoryDependenceAnalysis::NonLocal) { + // FIXME: INDENT PROPERLY if (DT->properlyDominates(I->first, C->getParent())) { - if (CallInst* CD = dyn_cast(I->second)) + if (CallInst* CD = dyn_cast(I->second.getPointer())) cdep = CD; else { valueNumbering.insert(std::make_pair(V, nextValueNumber)); @@ -718,6 +721,8 @@ AU.addPreserved(); } + typedef MemoryDependenceAnalysis::DepResultTy DepResultTy; + // Helper fuctions // FIXME: eliminate or document these better bool processLoad(LoadInst* L, @@ -861,7 +866,7 @@ MemoryDependenceAnalysis& MD = getAnalysis(); // Find the non-local dependencies of the load - DenseMap deps; + DenseMap deps; MD.getNonLocalDependency(L, deps); // If we had to process more than one hundred blocks to find the @@ -873,19 +878,19 @@ DenseMap repl; // Filter out useless results (non-locals, etc) - for (DenseMap::iterator I = deps.begin(), E = deps.end(); - I != E; ++I) { - if (I->second == MemoryDependenceAnalysis::None) + for (DenseMap::iterator I = deps.begin(), + E = deps.end(); I != E; ++I) { + if (I->second.getInt() == MemoryDependenceAnalysis::None) return false; - if (I->second == MemoryDependenceAnalysis::NonLocal) + if (I->second.getInt() == MemoryDependenceAnalysis::NonLocal) continue; - if (StoreInst* S = dyn_cast(I->second)) { + if (StoreInst* S = dyn_cast(I->second.getPointer())) { if (S->getPointerOperand() != L->getPointerOperand()) return false; repl[I->first] = S->getOperand(0); - } else if (LoadInst* LD = dyn_cast(I->second)) { + } else if (LoadInst* LD = dyn_cast(I->second.getPointer())) { if (LD->getPointerOperand() != L->getPointerOperand()) return false; repl[I->first] = LD; @@ -936,8 +941,8 @@ // ... to a pointer that has been loaded from before... MemoryDependenceAnalysis& MD = getAnalysis(); bool removedNonLocal = false; - Instruction* dep = MD.getDependency(L); - if (dep == MemoryDependenceAnalysis::NonLocal && + DepResultTy dep = MD.getDependency(L); + if (dep.getInt() == MemoryDependenceAnalysis::NonLocal && L->getParent() != &L->getParent()->getParent()->getEntryBlock()) { removedNonLocal = processNonLocalLoad(L, toErase); @@ -952,11 +957,10 @@ // Walk up the dependency chain until we either find // a dependency we can use, or we can't walk any further - while (dep != MemoryDependenceAnalysis::None && - dep != MemoryDependenceAnalysis::NonLocal && - (isa(dep) || isa(dep))) { + while (dep.getInt() == MemoryDependenceAnalysis::Normal && + (isa(dep.getPointer()) || isa(dep.getPointer()))){ // ... that depends on a store ... - if (StoreInst* S = dyn_cast(dep)) { + if (StoreInst* S = dyn_cast(dep.getPointer())) { if (S->getPointerOperand() == pointer) { // Remove it! MD.removeInstruction(L); @@ -974,7 +978,7 @@ // If we don't depend on a store, and we haven't // been loaded before, bail. break; - } else if (dep == last) { + } else if (dep.getPointer() == last) { // Remove it! MD.removeInstruction(L); @@ -985,16 +989,15 @@ break; } else { - dep = MD.getDependency(L, dep); + dep = MD.getDependency(L, dep.getPointer()); } } - if (dep != MemoryDependenceAnalysis::None && - dep != MemoryDependenceAnalysis::NonLocal && - isa(dep)) { + if (dep.getInt() == MemoryDependenceAnalysis::Normal && + isa(dep.getPointer())) { // Check that this load is actually from the // allocation we found - if (L->getOperand(0)->getUnderlyingObject() == dep) { + if (L->getOperand(0)->getUnderlyingObject() == dep.getPointer()) { // If this load depends directly on an allocation, there isn't // anything stored there; therefore, we can optimize this load // to undef. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=60230&r1=60229&r2=60230&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Nov 28 19:43:36 2008 @@ -629,18 +629,18 @@ // The are two possible optimizations we can do for memcpy: // a) memcpy-memcpy xform which exposes redundance for DSE // b) call-memcpy xform for return slot optimization - Instruction* dep = MD.getDependency(M); - if (dep == MemoryDependenceAnalysis::None || - dep == MemoryDependenceAnalysis::NonLocal) + MemoryDependenceAnalysis::DepResultTy dep = MD.getDependency(M); + if (dep.getInt() == MemoryDependenceAnalysis::None || + dep.getInt() == MemoryDependenceAnalysis::NonLocal) return false; - else if (!isa(dep)) { - if (CallInst* C = dyn_cast(dep)) + else if (!isa(dep.getPointer())) { + if (CallInst* C = dyn_cast(dep.getPointer())) return performCallSlotOptzn(M, C); else return false; } - MemCpyInst* MDep = cast(dep); + MemCpyInst* MDep = cast(dep.getPointer()); // We can only transforms memcpy's where the dest of one is the source of the // other @@ -691,7 +691,7 @@ // If C and M don't interfere, then this is a valid transformation. If they // did, this would mean that the two sources overlap, which would be bad. - if (MD.getDependency(C) == MDep) { + if (MD.getDependency(C) == dep) { MD.dropInstruction(M); M->eraseFromParent(); From sabre at nondot.org Fri Nov 28 20:29:28 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 02:29:28 -0000 Subject: [llvm-commits] [llvm] r60231 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <200811290229.mAT2TSWW018578@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 20:29:27 2008 New Revision: 60231 URL: http://llvm.org/viewvc/llvm-project?rev=60231&view=rev Log: Introduce and use a new MemDepResult class to hold the results of a memdep query. This makes it crystal clear what cases can escape from MemDep that the clients have to handle. This also gives the clients a nice simplified interface to it that is easy to poke at. This patch also makes DepResultTy and MemoryDependenceAnalysis::DepType private, yay. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60231&r1=60230&r2=60231&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 20:29:27 2008 @@ -24,13 +24,62 @@ class FunctionPass; class Instruction; class CallSite; + + /// MemDepResult - A memory dependence query can return one of three different + /// answers: + /// Normal : The query is dependent on a specific instruction. + /// NonLocal: The query does not depend on anything inside this block, but + /// we haven't scanned beyond the block to find out what. + /// None : The query does not depend on anything: we found the entry + /// block or the allocation site of the memory. + class MemDepResult { + enum DepType { + Invalid = 0, Normal, NonLocal, None + }; + typedef PointerIntPair PairTy; + PairTy Value; + explicit MemDepResult(PairTy V) : Value(V) {} + public: + MemDepResult() : Value(0, Invalid) {} + + /// get methods: These are static ctor methods for creating various + /// MemDepResult kinds. + static MemDepResult get(Instruction *Inst) { + return MemDepResult(PairTy(Inst, Normal)); + } + static MemDepResult getNonLocal() { + return MemDepResult(PairTy(0, NonLocal)); + } + static MemDepResult getNone() { + return MemDepResult(PairTy(0, None)); + } + + /// isNormal - Return true if this MemDepResult represents a query that is + /// a normal instruction dependency. + bool isNormal() const { return Value.getInt() == Normal; } + + /// isNonLocal - Return true if this MemDepResult represents an query that + /// is transparent to the start of the block, but where a non-local hasn't + /// been done. + bool isNonLocal() const { return Value.getInt() == NonLocal; } + + /// isNone - Return true if this MemDepResult represents a query that + /// doesn't depend on any instruction. + bool isNone() const { return Value.getInt() == None; } + + /// getInst() - If this is a normal dependency, return the instruction that + /// is depended on. Otherwise, return null. + Instruction *getInst() const { return isNormal() ? Value.getPointer() : 0; } + + bool operator==(const MemDepResult &M) { return M.Value == Value; } + bool operator!=(const MemDepResult &M) { return M.Value != Value; } + }; /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, /// caching interface to a common kind of alias information query. class MemoryDependenceAnalysis : public FunctionPass { - public: /// DepType - This enum is used to indicate what flavor of dependence this /// is. If the type is Normal, there is an associated instruction pointer. enum DepType { @@ -54,7 +103,7 @@ Dirty }; typedef PointerIntPair DepResultTy; - private: + // A map from instructions to their dependency, with a boolean // flags for whether this mapping is confirmed or not. typedef DenseMap > nonLocalDepMapType; nonLocalDepMapType depGraphNonLocal; @@ -98,14 +148,14 @@ /// getDependency - Return the instruction on which a memory operation /// depends, starting with start. - DepResultTy getDependency(Instruction *query, Instruction *start = 0, - BasicBlock *block = 0); + MemDepResult getDependency(Instruction *query, Instruction *start = 0, + BasicBlock *block = 0); /// getNonLocalDependency - Fills the passed-in map with the non-local /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. void getNonLocalDependency(Instruction* query, - DenseMap &resp); + DenseMap &resp); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. @@ -117,14 +167,33 @@ void dropInstruction(Instruction *InstToDrop); private: + DepResultTy ConvFromResult(MemDepResult R) { + if (Instruction *I = R.getInst()) + return DepResultTy(I, Normal); + if (R.isNonLocal()) + return DepResultTy(0, NonLocal); + assert(R.isNone() && "Unknown MemDepResult!"); + return DepResultTy(0, None); + } + + MemDepResult ConvToResult(DepResultTy R) { + if (R.getInt() == Normal) + return MemDepResult::get(R.getPointer()); + if (R.getInt() == NonLocal) + return MemDepResult::getNonLocal(); + assert(R.getInt() == None && "Unknown MemDepResult!"); + return MemDepResult::getNone(); + } + + /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - DepResultTy getCallSiteDependency(CallSite C, Instruction* start, - BasicBlock* block); + MemDepResult getCallSiteDependency(CallSite C, Instruction* start, + BasicBlock* block); void nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap& resp); + DenseMap &resp); }; } // End llvm namespace Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60231&r1=60230&r2=60231&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 20:29:27 2008 @@ -87,8 +87,7 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. -MemoryDependenceAnalysis::DepResultTy -MemoryDependenceAnalysis:: +MemDepResult MemoryDependenceAnalysis:: getCallSiteDependency(CallSite C, Instruction *start, BasicBlock *block) { std::pair &cachedResult = LocalDeps[C.getInstruction()]; AliasAnalysis& AA = getAnalysis(); @@ -140,7 +139,7 @@ cachedResult.second = true; reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); } - return DepResultTy(QI, Normal); + return MemDepResult::get(QI); } else { continue; } @@ -153,7 +152,7 @@ cachedResult.second = true; reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); } - return DepResultTy(QI, Normal); + return MemDepResult::get(QI); } } @@ -161,7 +160,7 @@ cachedResult.first = DepResultTy(0, NonLocal); cachedResult.second = true; reverseDep[DepResultTy(0, NonLocal)].insert(C.getInstruction()); - return DepResultTy(0, NonLocal); + return MemDepResult::getNonLocal(); } /// nonLocalHelper - Private helper used to calculate non-local dependencies @@ -199,11 +198,10 @@ if (BB != block) { visited.insert(BB); - DepResultTy localDep = getDependency(query, 0, BB); - if (localDep.getInt() != NonLocal) { - resp.insert(std::make_pair(BB, localDep)); + MemDepResult localDep = getDependency(query, 0, BB); + if (!localDep.isNonLocal()) { + resp.insert(std::make_pair(BB, ConvFromResult(localDep))); stack.pop_back(); - continue; } // If we re-encounter the starting block, we still need to search it @@ -212,12 +210,11 @@ } else if (BB == block) { visited.insert(BB); - DepResultTy localDep = getDependency(query, 0, BB); - if (localDep != DepResultTy(query, Normal)) - resp.insert(std::make_pair(BB, localDep)); + MemDepResult localDep = getDependency(query, 0, BB); + if (localDep.getInst() != query) + resp.insert(std::make_pair(BB, ConvFromResult(localDep))); stack.pop_back(); - continue; } @@ -257,7 +254,7 @@ /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, - DenseMap &resp) { + DenseMap &resp) { if (depGraphNonLocal.count(query)) { DenseMap &cached = depGraphNonLocal[query]; NumCacheNonlocal++; @@ -270,44 +267,46 @@ for (SmallVector::iterator I = dirtied.begin(), E = dirtied.end(); I != E; ++I) { - DepResultTy localDep = getDependency(query, 0, *I); - if (localDep.getInt() != NonLocal) - cached[*I] = localDep; + MemDepResult localDep = getDependency(query, 0, *I); + if (!localDep.isNonLocal()) + cached[*I] = ConvFromResult(localDep); else { cached.erase(*I); nonLocalHelper(query, *I, cached); } } - resp = cached; - - // Update the reverse non-local dependency cache - for (DenseMap::iterator I = resp.begin(), - E = resp.end(); I != E; ++I) + // Update the reverse non-local dependency cache. + for (DenseMap::iterator I = cached.begin(), + E = cached.end(); I != E; ++I) { reverseDepNonLocal[I->second].insert(query); + resp[I->first] = ConvToResult(I->second); + } return; - } else - NumUncacheNonlocal++; + } - // If not, go ahead and search for non-local deps. - nonLocalHelper(query, query->getParent(), resp); + NumUncacheNonlocal++; + // If not, go ahead and search for non-local deps. + DenseMap &cached = depGraphNonLocal[query]; + nonLocalHelper(query, query->getParent(), cached); + // Update the non-local dependency cache - for (DenseMap::iterator I = resp.begin(), - E = resp.end(); I != E; ++I) { - depGraphNonLocal[query].insert(*I); + for (DenseMap::iterator I = cached.begin(), + E = cached.end(); I != E; ++I) { + // FIXME: Merge with the code above! reverseDepNonLocal[I->second].insert(query); + resp[I->first] = ConvToResult(I->second); } } /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. -MemoryDependenceAnalysis::DepResultTy -MemoryDependenceAnalysis::getDependency(Instruction *query, - Instruction *start, - BasicBlock *block) { +MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *query, + Instruction *start, + BasicBlock *block) { // Start looking for dependencies with the queried inst BasicBlock::iterator QI = query; @@ -316,7 +315,7 @@ // If we have a _confirmed_ cached entry, return it if (!block && !start) { if (cachedResult.second) - return cachedResult.first; + return ConvToResult(cachedResult.first); else if (cachedResult.first.getInt() == Normal && cachedResult.first.getPointer()) // If we have an unconfirmed cached entry, we can start our search from @@ -355,9 +354,9 @@ } else if (CallSite::get(query).getInstruction() != 0) return getCallSiteDependency(CallSite::get(query), start, block); else if (isa(query)) - return DepResultTy(0, None); + return MemDepResult::getNone(); else - return DepResultTy(0, None); + return MemDepResult::getNone(); BasicBlock::iterator blockBegin = block ? block->begin() : query->getParent()->begin(); @@ -378,7 +377,7 @@ reverseDep[DepResultTy(S, Normal)].insert(query); } - return DepResultTy(S, Normal); + return MemDepResult::get(S); } pointer = S->getPointerOperand(); @@ -392,7 +391,7 @@ reverseDep[DepResultTy(L, Normal)].insert(query); } - return DepResultTy(L, Normal); + return MemDepResult::get(L); } pointer = L->getPointerOperand(); @@ -427,7 +426,7 @@ cachedResult.second = true; reverseDep[DepResultTy(QI, Normal)].insert(query); } - return DepResultTy(QI, Normal); + return MemDepResult::get(QI); } else { continue; } @@ -450,7 +449,7 @@ reverseDep[DepResultTy(QI, Normal)].insert(query); } - return DepResultTy(QI, Normal); + return MemDepResult::get(QI); } } } @@ -462,7 +461,7 @@ reverseDep[DepResultTy(0, NonLocal)].insert(query); } - return DepResultTy(0, NonLocal); + return MemDepResult::getNonLocal(); } /// dropInstruction - Remove an instruction from the analysis, making Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60231&r1=60230&r2=60231&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 20:29:27 2008 @@ -47,10 +47,8 @@ return Changed; } - typedef MemoryDependenceAnalysis::DepResultTy DepResultTy; - bool runOnBasicBlock(BasicBlock &BB); - bool handleFreeWithNonTrivialDependency(FreeInst *F, DepResultTy Dep); + bool handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep); bool handleEndBlock(BasicBlock &BB); bool RemoveUndeadPointers(Value* pointer, uint64_t killPointerSize, BasicBlock::iterator& BBI, @@ -110,16 +108,15 @@ // ... to a pointer that has been stored to before... if (last) { - DepResultTy dep = MD.getDependency(Inst); + MemDepResult dep = MD.getDependency(Inst); bool deletedStore = false; // ... and no other memory dependencies are between them.... - while (dep.getInt() == MemoryDependenceAnalysis::Normal && - isa(dep.getPointer())) { - if (dep.getPointer() != last || - TD.getTypeStoreSize(last->getOperand(0)->getType()) > - TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { - dep = MD.getDependency(Inst, dep.getPointer()); + while (StoreInst *DepStore = dyn_cast_or_null(dep.getInst())) { + if (DepStore != last || + TD.getTypeStoreSize(last->getOperand(0)->getType()) > + TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { + dep = MD.getDependency(Inst, DepStore); continue; } @@ -152,14 +149,12 @@ // loaded from, then the store can be removed; if (LoadInst* L = dyn_cast(S->getOperand(0))) { // FIXME: Don't do dep query if Parents don't match and other stuff! - DepResultTy dep = MD.getDependency(S); + MemDepResult dep = MD.getDependency(S); DominatorTree& DT = getAnalysis(); if (!S->isVolatile() && S->getParent() == L->getParent() && S->getPointerOperand() == L->getPointerOperand() && - (dep.getInt() == MemoryDependenceAnalysis::None || - dep.getInt() == MemoryDependenceAnalysis::NonLocal || - DT.dominates(dep.getPointer(), L))) { + (!dep.isNormal() || DT.dominates(dep.getInst(), L))) { DeleteDeadInstruction(S); if (!isa(BB.begin())) @@ -185,15 +180,11 @@ /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose /// dependency is a store to a field of that structure. -bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, DepResultTy dep) { +bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, MemDepResult dep) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); - if (dep.getInt() == MemoryDependenceAnalysis::None || - dep.getInt() == MemoryDependenceAnalysis::NonLocal) - return false; - - StoreInst* dependency = dyn_cast(dep.getPointer()); + StoreInst* dependency = dyn_cast_or_null(dep.getInst()); if (!dependency) return false; else if (dependency->isVolatile()) Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60231&r1=60230&r2=60231&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Nov 28 20:29:27 2008 @@ -456,19 +456,19 @@ return nextValueNumber++; } - MemoryDependenceAnalysis::DepResultTy local_dep = MD->getDependency(C); + MemDepResult local_dep = MD->getDependency(C); - if (local_dep.getInt() == MemoryDependenceAnalysis::None) { + if (local_dep.isNone()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (local_dep.getInt() != MemoryDependenceAnalysis::NonLocal) { + } else if (Instruction *LocalDepInst = local_dep.getInst()) { // FIXME: INDENT PROPERLY! - if (!isa(local_dep.getPointer())) { + if (!isa(LocalDepInst)) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; } - CallInst* local_cdep = cast(local_dep.getPointer()); + CallInst* local_cdep = cast(LocalDepInst); // FIXME: INDENT PROPERLY. if (local_cdep->getCalledFunction() != C->getCalledFunction() || @@ -495,20 +495,21 @@ } - DenseMap deps; + DenseMap deps; MD->getNonLocalDependency(C, deps); CallInst* cdep = 0; - for (DenseMap + for (DenseMap ::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { - if (I->second.getInt() == MemoryDependenceAnalysis::None) { + if (I->second.isNone()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (I->second.getInt() != MemoryDependenceAnalysis::NonLocal) { + } else if (Instruction *NonLocalDepInst = I->second.getInst()) { // FIXME: INDENT PROPERLY + // FIXME: All duplicated with non-local case. if (DT->properlyDominates(I->first, C->getParent())) { - if (CallInst* CD = dyn_cast(I->second.getPointer())) + if (CallInst* CD = dyn_cast(NonLocalDepInst)) cdep = CD; else { valueNumbering.insert(std::make_pair(V, nextValueNumber)); @@ -721,8 +722,6 @@ AU.addPreserved(); } - typedef MemoryDependenceAnalysis::DepResultTy DepResultTy; - // Helper fuctions // FIXME: eliminate or document these better bool processLoad(LoadInst* L, @@ -866,7 +865,7 @@ MemoryDependenceAnalysis& MD = getAnalysis(); // Find the non-local dependencies of the load - DenseMap deps; + DenseMap deps; MD.getNonLocalDependency(L, deps); // If we had to process more than one hundred blocks to find the @@ -878,19 +877,19 @@ DenseMap repl; // Filter out useless results (non-locals, etc) - for (DenseMap::iterator I = deps.begin(), + for (DenseMap::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { - if (I->second.getInt() == MemoryDependenceAnalysis::None) + if (I->second.isNone()) return false; - if (I->second.getInt() == MemoryDependenceAnalysis::NonLocal) + if (I->second.isNonLocal()) continue; - if (StoreInst* S = dyn_cast(I->second.getPointer())) { + if (StoreInst* S = dyn_cast(I->second.getInst())) { if (S->getPointerOperand() != L->getPointerOperand()) return false; repl[I->first] = S->getOperand(0); - } else if (LoadInst* LD = dyn_cast(I->second.getPointer())) { + } else if (LoadInst* LD = dyn_cast(I->second.getInst())) { if (LD->getPointerOperand() != L->getPointerOperand()) return false; repl[I->first] = LD; @@ -941,8 +940,8 @@ // ... to a pointer that has been loaded from before... MemoryDependenceAnalysis& MD = getAnalysis(); bool removedNonLocal = false; - DepResultTy dep = MD.getDependency(L); - if (dep.getInt() == MemoryDependenceAnalysis::NonLocal && + MemDepResult dep = MD.getDependency(L); + if (dep.isNonLocal() && L->getParent() != &L->getParent()->getParent()->getEntryBlock()) { removedNonLocal = processNonLocalLoad(L, toErase); @@ -957,10 +956,9 @@ // Walk up the dependency chain until we either find // a dependency we can use, or we can't walk any further - while (dep.getInt() == MemoryDependenceAnalysis::Normal && - (isa(dep.getPointer()) || isa(dep.getPointer()))){ + while (Instruction *DepInst = dep.getInst()) { // ... that depends on a store ... - if (StoreInst* S = dyn_cast(dep.getPointer())) { + if (StoreInst* S = dyn_cast(DepInst)) { if (S->getPointerOperand() == pointer) { // Remove it! MD.removeInstruction(L); @@ -974,11 +972,14 @@ // Whether we removed it or not, we can't // go any further break; + } else if (!isa(DepInst)) { + // Only want to handle loads below. + break; } else if (!last) { // If we don't depend on a store, and we haven't // been loaded before, bail. break; - } else if (dep.getPointer() == last) { + } else if (DepInst == last) { // Remove it! MD.removeInstruction(L); @@ -989,15 +990,14 @@ break; } else { - dep = MD.getDependency(L, dep.getPointer()); + dep = MD.getDependency(L, DepInst); } } - if (dep.getInt() == MemoryDependenceAnalysis::Normal && - isa(dep.getPointer())) { + if (AllocationInst *DepAI = dyn_cast_or_null(dep.getInst())) { // Check that this load is actually from the // allocation we found - if (L->getOperand(0)->getUnderlyingObject() == dep.getPointer()) { + if (L->getOperand(0)->getUnderlyingObject() == DepAI) { // If this load depends directly on an allocation, there isn't // anything stored there; therefore, we can optimize this load // to undef. Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=60231&r1=60230&r2=60231&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Nov 28 20:29:27 2008 @@ -629,18 +629,17 @@ // The are two possible optimizations we can do for memcpy: // a) memcpy-memcpy xform which exposes redundance for DSE // b) call-memcpy xform for return slot optimization - MemoryDependenceAnalysis::DepResultTy dep = MD.getDependency(M); - if (dep.getInt() == MemoryDependenceAnalysis::None || - dep.getInt() == MemoryDependenceAnalysis::NonLocal) + MemDepResult dep = MD.getDependency(M); + if (!dep.isNormal()) return false; - else if (!isa(dep.getPointer())) { - if (CallInst* C = dyn_cast(dep.getPointer())) + else if (!isa(dep.getInst())) { + if (CallInst* C = dyn_cast(dep.getInst())) return performCallSlotOptzn(M, C); else return false; } - MemCpyInst* MDep = cast(dep.getPointer()); + MemCpyInst* MDep = cast(dep.getInst()); // We can only transforms memcpy's where the dest of one is the source of the // other From sabre at nondot.org Fri Nov 28 21:22:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 03:22:12 -0000 Subject: [llvm-commits] [llvm] r60232 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811290322.mAT3MDXM020156@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 21:22:12 2008 New Revision: 60232 URL: http://llvm.org/viewvc/llvm-project?rev=60232&view=rev Log: Now that DepType is private, we can start cleaning up some of its uses: Document the Dirty value more precisely, use it for the uninitialized DepResultTy value. Change reverse mappings to be from an instruction* instead of DepResultTy, and stop tracking other forms. This makes it more clear that we only care about the instruction cases. Eliminate a DepResultTy,bool pair by using Dirty in the local case as well, shrinking the map and simplifying the code. This speeds up GVN by ~3% on 403.gcc. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60232&r1=60231&r2=60232&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 21:22:12 2008 @@ -83,9 +83,24 @@ /// DepType - This enum is used to indicate what flavor of dependence this /// is. If the type is Normal, there is an associated instruction pointer. enum DepType { + /// Dirty - Entries with this marker may come in two forms, depending on + /// whether they are in a LocalDeps map or NonLocalDeps map. In either + /// case, this marker indicates that the cached value has been invalidated + /// by a removeInstruction call. + /// + /// If in the LocalDeps map, the Instruction field will indicate the place + /// in the current block to start scanning. If in the non-localdeps map, + /// the instruction will be null. + /// + /// In a default-constructed DepResultTy object, the type will be Dirty + /// and the instruction pointer will be null. + /// + /// FIXME: Why not add a scanning point for the non-local deps map??? + Dirty = 0, + /// Normal - This is a normal instruction dependence. The pointer member /// of the DepResultTy pair holds the instruction. - Normal = 0, + Normal, /// None - This dependence type indicates that the query does not depend /// on any instructions, either because it scanned to the start of the @@ -96,18 +111,12 @@ /// NonLocal - This marker indicates that the query has no dependency in /// the specified block. To find out more, the client should query other /// predecessor blocks. - NonLocal, - - /// Dirty - This is an internal marker indicating that that a cache entry - /// is dirty. - Dirty + NonLocal }; typedef PointerIntPair DepResultTy; - // A map from instructions to their dependency, with a boolean - // flags for whether this mapping is confirmed or not. - typedef DenseMap > LocalDepMapType; + // A map from instructions to their dependency. + typedef DenseMap LocalDepMapType; LocalDepMapType LocalDeps; // A map from instructions to their non-local dependencies. @@ -118,7 +127,7 @@ // A reverse mapping from dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. - typedef DenseMap > reverseDepMapType; reverseDepMapType reverseDep; Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60232&r1=60231&r2=60232&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 21:22:12 2008 @@ -26,7 +26,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" - using namespace llvm; // Control the calculation of non-local dependencies by only examining the @@ -51,7 +50,7 @@ for (LocalDepMapType::const_iterator I = LocalDeps.begin(), E = LocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - assert(I->second.first.getPointer() != D && + assert(I->second.getPointer() != D && "Inst occurs in data structures"); } @@ -89,9 +88,9 @@ /// of a call site. MemDepResult MemoryDependenceAnalysis:: getCallSiteDependency(CallSite C, Instruction *start, BasicBlock *block) { - std::pair &cachedResult = LocalDeps[C.getInstruction()]; - AliasAnalysis& AA = getAnalysis(); - TargetData& TD = getAnalysis(); + DepResultTy &cachedResult = LocalDeps[C.getInstruction()]; + AliasAnalysis &AA = getAnalysis(); + TargetData &TD = getAnalysis(); BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin(); BasicBlock::iterator QI = C.getInstruction(); @@ -135,9 +134,8 @@ AA.getModRefBehavior(CallSite::get(QI)); if (result != AliasAnalysis::DoesNotAccessMemory) { if (!start && !block) { - cachedResult.first = DepResultTy(QI, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); + cachedResult = DepResultTy(QI, Normal); + reverseDep[QI].insert(C.getInstruction()); } return MemDepResult::get(QI); } else { @@ -148,18 +146,15 @@ if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) { if (!start && !block) { - cachedResult.first = DepResultTy(QI, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(QI, Normal)].insert(C.getInstruction()); + cachedResult = DepResultTy(QI, Normal); + reverseDep[QI].insert(C.getInstruction()); } return MemDepResult::get(QI); } } // No dependence found - cachedResult.first = DepResultTy(0, NonLocal); - cachedResult.second = true; - reverseDep[DepResultTy(0, NonLocal)].insert(C.getInstruction()); + cachedResult = DepResultTy(0, NonLocal); return MemDepResult::getNonLocal(); } @@ -279,7 +274,8 @@ // Update the reverse non-local dependency cache. for (DenseMap::iterator I = cached.begin(), E = cached.end(); I != E; ++I) { - reverseDepNonLocal[I->second].insert(query); + if (Instruction *Inst = I->second.getPointer()) + reverseDepNonLocal[Inst].insert(query); resp[I->first] = ConvToResult(I->second); } @@ -296,7 +292,8 @@ for (DenseMap::iterator I = cached.begin(), E = cached.end(); I != E; ++I) { // FIXME: Merge with the code above! - reverseDepNonLocal[I->second].insert(query); + if (Instruction *Inst = I->second.getPointer()) + reverseDepNonLocal[Inst].insert(query); resp[I->first] = ConvToResult(I->second); } } @@ -304,6 +301,8 @@ /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. +/// FIXME: ELIMINATE START/BLOCK and make the caching happen in a higher level +/// METHOD. MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *query, Instruction *start, BasicBlock *block) { @@ -311,22 +310,20 @@ BasicBlock::iterator QI = query; // Check for a cached result - std::pair& cachedResult = LocalDeps[query]; - // If we have a _confirmed_ cached entry, return it - if (!block && !start) { - if (cachedResult.second) - return ConvToResult(cachedResult.first); - else if (cachedResult.first.getInt() == Normal && - cachedResult.first.getPointer()) - // If we have an unconfirmed cached entry, we can start our search from - // it. - QI = cachedResult.first.getPointer(); - } + // FIXME: why do this when Block or Start is specified?? + DepResultTy &cachedResult = LocalDeps[query]; if (start) QI = start; - else if (!start && block) + else if (block) QI = block->end(); + else if (cachedResult.getInt() != Dirty) { + // If we have a _confirmed_ cached entry, return it. + return ConvToResult(cachedResult); + } else if (Instruction *Inst = cachedResult.getPointer()) { + // If we have an unconfirmed cached entry, we can start our search from it. + QI = Inst; + } AliasAnalysis& AA = getAnalysis(); TargetData& TD = getAnalysis(); @@ -372,9 +369,8 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && S->isVolatile()) { if (!start && !block) { - cachedResult.first = DepResultTy(S, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(S, Normal)].insert(query); + cachedResult = DepResultTy(S, Normal); + reverseDep[S].insert(query); } return MemDepResult::get(S); @@ -386,9 +382,8 @@ // All volatile loads/stores depend on each other if (queryIsVolatile && L->isVolatile()) { if (!start && !block) { - cachedResult.first = DepResultTy(L, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(L, Normal)].insert(query); + cachedResult = DepResultTy(L, Normal); + reverseDep[L].insert(query); } return MemDepResult::get(L); @@ -422,9 +417,8 @@ continue; if (!start && !block) { - cachedResult.first = DepResultTy(QI, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(QI, Normal)].insert(query); + cachedResult = DepResultTy(QI, Normal); + reverseDep[QI].insert(query); } return MemDepResult::get(QI); } else { @@ -444,9 +438,8 @@ continue; if (!start && !block) { - cachedResult.first = DepResultTy(QI, Normal); - cachedResult.second = true; - reverseDep[DepResultTy(QI, Normal)].insert(query); + cachedResult = DepResultTy(QI, Normal); + reverseDep[QI].insert(query); } return MemDepResult::get(QI); @@ -455,11 +448,8 @@ } // If we found nothing, return the non-local flag - if (!start && !block) { - cachedResult.first = DepResultTy(0, NonLocal); - cachedResult.second = true; - reverseDep[DepResultTy(0, NonLocal)].insert(query); - } + if (!start && !block) + cachedResult = DepResultTy(0, NonLocal); return MemDepResult::getNonLocal(); } @@ -470,36 +460,38 @@ void MemoryDependenceAnalysis::dropInstruction(Instruction* drop) { LocalDepMapType::iterator depGraphEntry = LocalDeps.find(drop); if (depGraphEntry != LocalDeps.end()) - reverseDep[depGraphEntry->second.first].erase(drop); + if (Instruction *Inst = depGraphEntry->second.getPointer()) + reverseDep[Inst].erase(drop); // Drop dependency information for things that depended on this instr - SmallPtrSet& set = reverseDep[DepResultTy(drop, Normal)]; + SmallPtrSet& set = reverseDep[drop]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) LocalDeps.erase(*I); LocalDeps.erase(drop); - reverseDep.erase(DepResultTy(drop, Normal)); + reverseDep.erase(drop); for (DenseMap::iterator DI = depGraphNonLocal[drop].begin(), DE = depGraphNonLocal[drop].end(); DI != DE; ++DI) - if (DI->second.getInt() != None) - reverseDepNonLocal[DI->second].erase(drop); + if (Instruction *Inst = DI->second.getPointer()) + reverseDepNonLocal[Inst].erase(drop); - if (reverseDepNonLocal.count(DepResultTy(drop, Normal))) { + if (reverseDepNonLocal.count(drop)) { SmallPtrSet& set = - reverseDepNonLocal[DepResultTy(drop, Normal)]; + reverseDepNonLocal[drop]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap::iterator DI = depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); DI != DE; ++DI) if (DI->second == DepResultTy(drop, Normal)) + // FIXME: Why not remember the old insertion point?? DI->second = DepResultTy(0, Dirty); } - reverseDepNonLocal.erase(DepResultTy(drop, Normal)); + reverseDepNonLocal.erase(drop); depGraphNonLocal.erase(drop); } @@ -512,8 +504,8 @@ for (DenseMap::iterator DI = depGraphNonLocal[RemInst].begin(), DE = depGraphNonLocal[RemInst].end(); DI != DE; ++DI) - if (DI->second.getInt() != None) - reverseDepNonLocal[DI->second].erase(RemInst); + if (Instruction *Inst = DI->second.getPointer()) + reverseDepNonLocal[Inst].erase(RemInst); // Shortly after this, we will look for things that depend on RemInst. In // order to update these, we'll need a new dependency to base them on. We @@ -521,33 +513,31 @@ // to make a more accurate approximation where possible. Compute that better // approximation if we can. DepResultTy NewDependency; - bool NewDependencyConfirmed = false; // If we have a cached local dependence query for this instruction, remove it. // LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); if (LocalDepEntry != LocalDeps.end()) { - DepResultTy LocalDep = LocalDepEntry->second.first; - bool IsConfirmed = LocalDepEntry->second.second; + DepResultTy LocalDep = LocalDepEntry->second; // Remove this local dependency info. LocalDeps.erase(LocalDepEntry); // Remove us from DepInst's reverse set now that the local dep info is gone. - reverseDep[LocalDep].erase(RemInst); + if (Instruction *Inst = LocalDep.getPointer()) + reverseDep[Inst].erase(RemInst); // If we have unconfirmed info, don't trust it. - if (IsConfirmed) { + if (LocalDep.getInt() != Dirty) { // If we have a confirmed non-local flag, use it. if (LocalDep.getInt() == NonLocal || LocalDep.getInt() == None) { // The only time this dependency is confirmed is if it is non-local. NewDependency = LocalDep; - NewDependencyConfirmed = true; } else { // If we have dep info for RemInst, set them to it. Instruction *NDI = next(BasicBlock::iterator(LocalDep.getPointer())); if (NDI != RemInst) // Don't use RemInst for the new dependency! - NewDependency = DepResultTy(NDI, Normal); + NewDependency = DepResultTy(NDI, Dirty); } } } @@ -556,13 +546,12 @@ // use the immediate successor of RemInst. We use the successor because // getDependence starts by checking the immediate predecessor of what is in // the cache. - if (NewDependency == DepResultTy(0, Normal)) - NewDependency = DepResultTy(next(BasicBlock::iterator(RemInst)), Normal); + if (NewDependency == DepResultTy(0, Dirty)) + NewDependency = DepResultTy(next(BasicBlock::iterator(RemInst)), Dirty); // Loop over all of the things that depend on the instruction we're removing. // - reverseDepMapType::iterator ReverseDepIt = - reverseDep.find(DepResultTy(RemInst, Normal)); + reverseDepMapType::iterator ReverseDepIt = reverseDep.find(RemInst); if (ReverseDepIt != reverseDep.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; for (SmallPtrSet::iterator I = ReverseDeps.begin(), @@ -574,19 +563,17 @@ if (InstDependingOnRemInst == RemInst) continue; // Insert the new dependencies. - LocalDeps[InstDependingOnRemInst] = - std::make_pair(NewDependency, NewDependencyConfirmed); + LocalDeps[InstDependingOnRemInst] = NewDependency; // If our NewDependency is an instruction, make sure to remember that new // things depend on it. - // FIXME: Just insert all deps! - if (NewDependency.getInt() != NonLocal && NewDependency.getInt() != None) - reverseDep[NewDependency].insert(InstDependingOnRemInst); + if (Instruction *Inst = NewDependency.getPointer()) + reverseDep[Inst].insert(InstDependingOnRemInst); } - reverseDep.erase(DepResultTy(RemInst, Normal)); + reverseDep.erase(RemInst); } - ReverseDepIt = reverseDepNonLocal.find(DepResultTy(RemInst, Normal)); + ReverseDepIt = reverseDepNonLocal.find(RemInst); if (ReverseDepIt != reverseDepNonLocal.end()) { SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); @@ -595,6 +582,7 @@ depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); DI != DE; ++DI) if (DI->second == DepResultTy(RemInst, Normal)) + // FIXME: Why not remember the old insertion point?? DI->second = DepResultTy(0, Dirty); reverseDepNonLocal.erase(ReverseDepIt); } From isanbard at gmail.com Fri Nov 28 21:43:04 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 29 Nov 2008 03:43:04 -0000 Subject: [llvm-commits] [llvm] r60233 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200811290343.mAT3h4Ge020940@zion.cs.uiuc.edu> Author: void Date: Fri Nov 28 21:43:04 2008 New Revision: 60233 URL: http://llvm.org/viewvc/llvm-project?rev=60233&view=rev Log: Temporarily revert r60195. It's causing an optimized bootstrap of llvm-gcc to fail. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60233&r1=60232&r2=60233&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Nov 28 21:43:04 2008 @@ -240,30 +240,31 @@ /// their operands subsequently dead. void LoopStrengthReduce:: DeleteTriviallyDeadInstructions(SetVector &Insts) { - SmallVector DeadInsts; - while (!Insts.empty()) { Instruction *I = Insts.back(); Insts.pop_back(); - - // If I is dead, delete it and all the things that it recursively uses - // that become dead. - RecursivelyDeleteTriviallyDeadInstructions(I, &DeadInsts); - - if (DeadInsts.empty()) continue; - Changed = true; - while (!DeadInsts.empty()) { - Instruction *DeadInst = DeadInsts.back(); - DeadInsts.pop_back(); - - // Make sure ScalarEvolutions knows this instruction is gone. - SE->deleteValueFromRecords(DeadInst); - - // Make sure that this instruction is removed from DeadInsts if it was - // recursively removed. - if (DeadInst != I) - Insts.remove(DeadInst); + if (PHINode *PN = dyn_cast(I)) { + // If all incoming values to the Phi are the same, we can replace the Phi + // with that value. + if (Value *PNV = PN->hasConstantValue()) { + if (Instruction *U = dyn_cast(PNV)) + Insts.insert(U); + SE->deleteValueFromRecords(PN); + PN->replaceAllUsesWith(PNV); + PN->eraseFromParent(); + Changed = true; + continue; + } + } + + if (isInstructionTriviallyDead(I)) { + for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) + if (Instruction *U = dyn_cast(*i)) + Insts.insert(U); + SE->deleteValueFromRecords(I); + I->eraseFromParent(); + Changed = true; } } } From sabre at nondot.org Fri Nov 28 21:47:00 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 03:47:00 -0000 Subject: [llvm-commits] [llvm] r60234 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200811290347.mAT3l0P6021049@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 28 21:47:00 2008 New Revision: 60234 URL: http://llvm.org/viewvc/llvm-project?rev=60234&view=rev Log: Split getDependency into getDependency and getDependencyFrom, the former does caching, the later doesn't. This dramatically simplifies the logic in getDependency and getDependencyFrom. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60234&r1=60233&r2=60234&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Nov 28 21:47:00 2008 @@ -14,6 +14,7 @@ #ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H #define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H +#include "llvm/BasicBlock.h" #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" @@ -156,9 +157,15 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const; /// getDependency - Return the instruction on which a memory operation - /// depends, starting with start. - MemDepResult getDependency(Instruction *query, Instruction *start = 0, - BasicBlock *block = 0); + /// depends. + MemDepResult getDependency(Instruction *QueryInst); + + /// getDependencyFrom - Return the instruction on which the memory operation + /// 'QueryInst' depends. This starts scanning from the instruction before + /// the position indicated by ScanIt. + MemDepResult getDependencyFrom(Instruction *QueryInst, + BasicBlock::iterator ScanIt, BasicBlock *BB); + /// getNonLocalDependency - Fills the passed-in map with the non-local /// dependencies of the queries. The map will contain NonLocal for @@ -199,8 +206,8 @@ /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - MemDepResult getCallSiteDependency(CallSite C, Instruction* start, - BasicBlock* block); + MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, + BasicBlock *BB); void nonLocalHelper(Instruction* query, BasicBlock* block, DenseMap &resp); }; Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60234&r1=60233&r2=60234&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Nov 28 21:47:00 2008 @@ -87,74 +87,49 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. MemDepResult MemoryDependenceAnalysis:: -getCallSiteDependency(CallSite C, Instruction *start, BasicBlock *block) { - DepResultTy &cachedResult = LocalDeps[C.getInstruction()]; +getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, + BasicBlock *BB) { AliasAnalysis &AA = getAnalysis(); TargetData &TD = getAnalysis(); - BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin(); - BasicBlock::iterator QI = C.getInstruction(); - - // If the starting point was specified, use it - if (start) { - QI = start; - blockBegin = start->getParent()->begin(); - // If the starting point wasn't specified, but the block was, use it - } else if (!start && block) { - QI = block->end(); - blockBegin = block->begin(); - } // Walk backwards through the block, looking for dependencies - while (QI != blockBegin) { - --QI; + while (ScanIt != BB->begin()) { + Instruction *Inst = --ScanIt; // If this inst is a memory op, get the pointer it accessed Value* pointer = 0; uint64_t pointerSize = 0; - if (StoreInst* S = dyn_cast(QI)) { + if (StoreInst* S = dyn_cast(Inst)) { pointer = S->getPointerOperand(); pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (AllocationInst* AI = dyn_cast(QI)) { + } else if (AllocationInst* AI = dyn_cast(Inst)) { pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) pointerSize = C->getZExtValue() * TD.getABITypeSize(AI->getAllocatedType()); else pointerSize = ~0UL; - } else if (VAArgInst* V = dyn_cast(QI)) { + } else if (VAArgInst* V = dyn_cast(Inst)) { pointer = V->getOperand(0); pointerSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst* F = dyn_cast(QI)) { + } else if (FreeInst* F = dyn_cast(Inst)) { pointer = F->getPointerOperand(); // FreeInsts erase the entire structure pointerSize = ~0UL; - } else if (CallSite::get(QI).getInstruction() != 0) { - AliasAnalysis::ModRefBehavior result = - AA.getModRefBehavior(CallSite::get(QI)); - if (result != AliasAnalysis::DoesNotAccessMemory) { - if (!start && !block) { - cachedResult = DepResultTy(QI, Normal); - reverseDep[QI].insert(C.getInstruction()); - } - return MemDepResult::get(QI); - } else { - continue; - } + } else if (CallSite::get(Inst).getInstruction() != 0) { + if (AA.getModRefBehavior(CallSite::get(Inst)) != + AliasAnalysis::DoesNotAccessMemory) + return MemDepResult::get(Inst); + continue; } else continue; - if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) { - if (!start && !block) { - cachedResult = DepResultTy(QI, Normal); - reverseDep[QI].insert(C.getInstruction()); - } - return MemDepResult::get(QI); - } + if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) + return MemDepResult::get(Inst); } - // No dependence found - cachedResult = DepResultTy(0, NonLocal); + // No dependence found. return MemDepResult::getNonLocal(); } @@ -193,7 +168,7 @@ if (BB != block) { visited.insert(BB); - MemDepResult localDep = getDependency(query, 0, BB); + MemDepResult localDep = getDependencyFrom(query, BB->end(), BB); if (!localDep.isNonLocal()) { resp.insert(std::make_pair(BB, ConvFromResult(localDep))); stack.pop_back(); @@ -205,7 +180,7 @@ } else if (BB == block) { visited.insert(BB); - MemDepResult localDep = getDependency(query, 0, BB); + MemDepResult localDep = getDependencyFrom(query, BB->end(), BB); if (localDep.getInst() != query) resp.insert(std::make_pair(BB, ConvFromResult(localDep))); @@ -262,7 +237,7 @@ for (SmallVector::iterator I = dirtied.begin(), E = dirtied.end(); I != E; ++I) { - MemDepResult localDep = getDependency(query, 0, *I); + MemDepResult localDep = getDependencyFrom(query, (*I)->end(), *I); if (!localDep.isNonLocal()) cached[*I] = ConvFromResult(localDep); else { @@ -303,127 +278,86 @@ /// evaluate dependencies within the same basic block. /// FIXME: ELIMINATE START/BLOCK and make the caching happen in a higher level /// METHOD. -MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *query, - Instruction *start, - BasicBlock *block) { - // Start looking for dependencies with the queried inst - BasicBlock::iterator QI = query; - - // Check for a cached result - // FIXME: why do this when Block or Start is specified?? - DepResultTy &cachedResult = LocalDeps[query]; - - if (start) - QI = start; - else if (block) - QI = block->end(); - else if (cachedResult.getInt() != Dirty) { - // If we have a _confirmed_ cached entry, return it. - return ConvToResult(cachedResult); - } else if (Instruction *Inst = cachedResult.getPointer()) { - // If we have an unconfirmed cached entry, we can start our search from it. - QI = Inst; - } - - AliasAnalysis& AA = getAnalysis(); - TargetData& TD = getAnalysis(); +MemDepResult MemoryDependenceAnalysis:: +getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, + BasicBlock *BB) { + AliasAnalysis &AA = getAnalysis(); + TargetData &TD = getAnalysis(); // Get the pointer value for which dependence will be determined Value* dependee = 0; uint64_t dependeeSize = 0; bool queryIsVolatile = false; - if (StoreInst* S = dyn_cast(query)) { + + if (StoreInst* S = dyn_cast(QueryInst)) { dependee = S->getPointerOperand(); dependeeSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); queryIsVolatile = S->isVolatile(); - } else if (LoadInst* L = dyn_cast(query)) { + } else if (LoadInst* L = dyn_cast(QueryInst)) { dependee = L->getPointerOperand(); dependeeSize = TD.getTypeStoreSize(L->getType()); queryIsVolatile = L->isVolatile(); - } else if (VAArgInst* V = dyn_cast(query)) { + } else if (VAArgInst* V = dyn_cast(QueryInst)) { dependee = V->getOperand(0); dependeeSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst* F = dyn_cast(query)) { + } else if (FreeInst* F = dyn_cast(QueryInst)) { dependee = F->getPointerOperand(); - // FreeInsts erase the entire structure, not just a field dependeeSize = ~0UL; - } else if (CallSite::get(query).getInstruction() != 0) - return getCallSiteDependency(CallSite::get(query), start, block); - else if (isa(query)) - return MemDepResult::getNone(); + } else if (CallSite::get(QueryInst).getInstruction() != 0) + return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); else return MemDepResult::getNone(); - BasicBlock::iterator blockBegin = block ? block->begin() - : query->getParent()->begin(); - // Walk backwards through the basic block, looking for dependencies - while (QI != blockBegin) { - --QI; + while (ScanIt != BB->begin()) { + Instruction *Inst = --ScanIt; // If this inst is a memory op, get the pointer it accessed Value* pointer = 0; uint64_t pointerSize = 0; - if (StoreInst* S = dyn_cast(QI)) { + if (StoreInst* S = dyn_cast(Inst)) { // All volatile loads/stores depend on each other - if (queryIsVolatile && S->isVolatile()) { - if (!start && !block) { - cachedResult = DepResultTy(S, Normal); - reverseDep[S].insert(query); - } - + if (queryIsVolatile && S->isVolatile()) return MemDepResult::get(S); - } pointer = S->getPointerOperand(); pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (LoadInst* L = dyn_cast(QI)) { + } else if (LoadInst* L = dyn_cast(Inst)) { // All volatile loads/stores depend on each other - if (queryIsVolatile && L->isVolatile()) { - if (!start && !block) { - cachedResult = DepResultTy(L, Normal); - reverseDep[L].insert(query); - } - + if (queryIsVolatile && L->isVolatile()) return MemDepResult::get(L); - } pointer = L->getPointerOperand(); pointerSize = TD.getTypeStoreSize(L->getType()); - } else if (AllocationInst* AI = dyn_cast(QI)) { + } else if (AllocationInst* AI = dyn_cast(Inst)) { pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) pointerSize = C->getZExtValue() * TD.getABITypeSize(AI->getAllocatedType()); else pointerSize = ~0UL; - } else if (VAArgInst* V = dyn_cast(QI)) { + } else if (VAArgInst* V = dyn_cast(Inst)) { pointer = V->getOperand(0); pointerSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst* F = dyn_cast(QI)) { + } else if (FreeInst* F = dyn_cast(Inst)) { pointer = F->getPointerOperand(); // FreeInsts erase the entire structure pointerSize = ~0UL; - } else if (CallSite::get(QI).getInstruction() != 0) { + } else if (isa(Inst) || isa(Inst)) { // Call insts need special handling. Check if they can modify our pointer - AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI), + AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(Inst), dependee, dependeeSize); if (MR != AliasAnalysis::NoModRef) { // Loads don't depend on read-only calls - if (isa(query) && MR == AliasAnalysis::Ref) + if (isa(QueryInst) && MR == AliasAnalysis::Ref) continue; - - if (!start && !block) { - cachedResult = DepResultTy(QI, Normal); - reverseDep[QI].insert(query); - } - return MemDepResult::get(QI); - } else { - continue; + return MemDepResult::get(Inst); } + + continue; } // If we found a pointer, check if it could be the same as our pointer @@ -433,27 +367,49 @@ if (R != AliasAnalysis::NoAlias) { // May-alias loads don't depend on each other - if (isa(query) && isa(QI) && + if (isa(QueryInst) && isa(Inst) && R == AliasAnalysis::MayAlias) continue; - - if (!start && !block) { - cachedResult = DepResultTy(QI, Normal); - reverseDep[QI].insert(query); - } - - return MemDepResult::get(QI); + return MemDepResult::get(Inst); } } } - // If we found nothing, return the non-local flag - if (!start && !block) - cachedResult = DepResultTy(0, NonLocal); - + // If we found nothing, return the non-local flag. return MemDepResult::getNonLocal(); } +/// getDependency - Return the instruction on which a memory operation +/// depends. +MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { + Instruction *ScanPos = QueryInst; + + // Check for a cached result + DepResultTy &LocalCache = LocalDeps[QueryInst]; + + // If the cached entry is non-dirty, just return it. + if (LocalCache.getInt() != Dirty) + return ConvToResult(LocalCache); + + // Otherwise, if we have a dirty entry, we know we can start the scan at that + // instruction, which may save us some work. + if (Instruction *Inst = LocalCache.getPointer()) + ScanPos = Inst; + + // Do the scan. + MemDepResult Res = + getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); + + // Remember the result! + // FIXME: Don't convert back and forth! Make a shared helper function. + LocalCache = ConvFromResult(Res); + if (Instruction *I = Res.getInst()) + reverseDep[I].insert(QueryInst); + + return Res; +} + + /// dropInstruction - Remove an instruction from the analysis, making /// absolutely conservative assumptions when updating the cache. This is /// useful, for example when an instruction is changed rather than removed. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60234&r1=60233&r2=60234&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Nov 28 21:47:00 2008 @@ -116,7 +116,7 @@ if (DepStore != last || TD.getTypeStoreSize(last->getOperand(0)->getType()) > TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { - dep = MD.getDependency(Inst, DepStore); + dep = MD.getDependencyFrom(Inst, DepStore, DepStore->getParent()); continue; } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60234&r1=60233&r2=60234&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Nov 28 21:47:00 2008 @@ -990,7 +990,7 @@ break; } else { - dep = MD.getDependency(L, DepInst); + dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent()); } } From baldrick at free.fr Sat Nov 29 02:03:42 2008 From: baldrick at free.fr (Duncan Sands) Date: Sat, 29 Nov 2008 08:03:42 -0000 Subject: [llvm-commits] [llvm] r60236 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811290803.mAT83gRd028740@zion.cs.uiuc.edu> Author: baldrick Date: Sat Nov 29 02:03:35 2008 New Revision: 60236 URL: http://llvm.org/viewvc/llvm-project?rev=60236&view=rev Log: Typo fix. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60236&r1=60235&r2=60236&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Sat Nov 29 02:03:35 2008 @@ -48,7 +48,7 @@ void setPointer(PointerTy Ptr) { intptr_t PtrVal = reinterpret_cast(Ptr); assert((PtrVal & (1 << IntBits)-1) == 0 && - "Pointer is no sufficiently aligned"); + "Pointer is not sufficiently aligned"); Value = PtrVal | (intptr_t)getInt(); } From sabre at nondot.org Sat Nov 29 02:36:41 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 08:36:41 -0000 Subject: [llvm-commits] [llvm] r60237 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811290836.mAT8afn5030249@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 02:36:39 2008 New Revision: 60237 URL: http://llvm.org/viewvc/llvm-project?rev=60237&view=rev Log: apparently GCC doesn't believe that I understand C precedence rules. Pacify it. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60237&r1=60236&r2=60237&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Sat Nov 29 02:36:39 2008 @@ -42,12 +42,12 @@ } IntType getInt() const { - return (IntType)(Value & (1 << IntBits)-1); + return (IntType)(Value & ((1 << IntBits)-1)); } void setPointer(PointerTy Ptr) { intptr_t PtrVal = reinterpret_cast(Ptr); - assert((PtrVal & (1 << IntBits)-1) == 0 && + assert((PtrVal & ((1 << IntBits)-1)) == 0 && "Pointer is not sufficiently aligned"); Value = PtrVal | (intptr_t)getInt(); } From sabre at nondot.org Sat Nov 29 02:51:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 08:51:17 -0000 Subject: [llvm-commits] [llvm] r60238 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811290851.mAT8pHPk002320@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 02:51:16 2008 New Revision: 60238 URL: http://llvm.org/viewvc/llvm-project?rev=60238&view=rev Log: simplify some code and rename some variables. Reduce nesting. Use getTypeStoreSize instead of ABITypeSize for in-memory size in a couple places. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60238&r1=60237&r2=60238&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 02:51:16 2008 @@ -106,7 +106,7 @@ pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) pointerSize = C->getZExtValue() * - TD.getABITypeSize(AI->getAllocatedType()); + TD.getTypeStoreSize(AI->getAllocatedType()); else pointerSize = ~0UL; } else if (VAArgInst* V = dyn_cast(Inst)) { @@ -276,8 +276,6 @@ /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. -/// FIXME: ELIMINATE START/BLOCK and make the caching happen in a higher level -/// METHOD. MemDepResult MemoryDependenceAnalysis:: getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, BasicBlock *BB) { @@ -285,28 +283,28 @@ TargetData &TD = getAnalysis(); // Get the pointer value for which dependence will be determined - Value* dependee = 0; - uint64_t dependeeSize = 0; - bool queryIsVolatile = false; + Value *MemPtr = 0; + uint64_t MemSize = 0; + bool MemVolatile = false; if (StoreInst* S = dyn_cast(QueryInst)) { - dependee = S->getPointerOperand(); - dependeeSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - queryIsVolatile = S->isVolatile(); + MemPtr = S->getPointerOperand(); + MemSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); + MemVolatile = S->isVolatile(); } else if (LoadInst* L = dyn_cast(QueryInst)) { - dependee = L->getPointerOperand(); - dependeeSize = TD.getTypeStoreSize(L->getType()); - queryIsVolatile = L->isVolatile(); + MemPtr = L->getPointerOperand(); + MemSize = TD.getTypeStoreSize(L->getType()); + MemVolatile = L->isVolatile(); } else if (VAArgInst* V = dyn_cast(QueryInst)) { - dependee = V->getOperand(0); - dependeeSize = TD.getTypeStoreSize(V->getType()); + MemPtr = V->getOperand(0); + MemSize = TD.getTypeStoreSize(V->getType()); } else if (FreeInst* F = dyn_cast(QueryInst)) { - dependee = F->getPointerOperand(); - // FreeInsts erase the entire structure, not just a field - dependeeSize = ~0UL; - } else if (CallSite::get(QueryInst).getInstruction() != 0) + MemPtr = F->getPointerOperand(); + // FreeInsts erase the entire structure, not just a field. + MemSize = ~0UL; + } else if (isa(QueryInst) || isa(QueryInst)) return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); - else + else // Non-memory instructions depend on nothing. return MemDepResult::getNone(); // Walk backwards through the basic block, looking for dependencies @@ -314,65 +312,67 @@ Instruction *Inst = --ScanIt; // If this inst is a memory op, get the pointer it accessed - Value* pointer = 0; - uint64_t pointerSize = 0; - if (StoreInst* S = dyn_cast(Inst)) { - // All volatile loads/stores depend on each other - if (queryIsVolatile && S->isVolatile()) + Value *Pointer = 0; + uint64_t PointerSize = 0; + if (StoreInst *S = dyn_cast(Inst)) { + // All volatile loads/stores depend on each other. + if (MemVolatile && S->isVolatile()) return MemDepResult::get(S); - pointer = S->getPointerOperand(); - pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (LoadInst* L = dyn_cast(Inst)) { + Pointer = S->getPointerOperand(); + PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); + } else if (LoadInst *L = dyn_cast(Inst)) { // All volatile loads/stores depend on each other - if (queryIsVolatile && L->isVolatile()) + if (MemVolatile && L->isVolatile()) return MemDepResult::get(L); - pointer = L->getPointerOperand(); - pointerSize = TD.getTypeStoreSize(L->getType()); - } else if (AllocationInst* AI = dyn_cast(Inst)) { - pointer = AI; - if (ConstantInt* C = dyn_cast(AI->getArraySize())) - pointerSize = C->getZExtValue() * - TD.getABITypeSize(AI->getAllocatedType()); + Pointer = L->getPointerOperand(); + PointerSize = TD.getTypeStoreSize(L->getType()); + } else if (AllocationInst *AI = dyn_cast(Inst)) { + Pointer = AI; + if (ConstantInt *C = dyn_cast(AI->getArraySize())) + PointerSize = C->getZExtValue() * + TD.getTypeStoreSize(AI->getAllocatedType()); else - pointerSize = ~0UL; - } else if (VAArgInst* V = dyn_cast(Inst)) { - pointer = V->getOperand(0); - pointerSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst* F = dyn_cast(Inst)) { - pointer = F->getPointerOperand(); + PointerSize = ~0UL; + } else if (VAArgInst *V = dyn_cast(Inst)) { + Pointer = V->getOperand(0); + PointerSize = TD.getTypeStoreSize(V->getType()); + } else if (FreeInst *F = dyn_cast(Inst)) { + Pointer = F->getPointerOperand(); - // FreeInsts erase the entire structure - pointerSize = ~0UL; + // FreeInsts erase the entire structure. + PointerSize = ~0UL; } else if (isa(Inst) || isa(Inst)) { - // Call insts need special handling. Check if they can modify our pointer - AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(Inst), - dependee, dependeeSize); - - if (MR != AliasAnalysis::NoModRef) { - // Loads don't depend on read-only calls - if (isa(QueryInst) && MR == AliasAnalysis::Ref) - continue; - return MemDepResult::get(Inst); - } - + // Calls need special handling. Check if they can modify our pointer. + AliasAnalysis::ModRefResult MR = + AA.getModRefInfo(CallSite::get(Inst), MemPtr, MemSize); + + if (MR == AliasAnalysis::NoModRef) + continue; + + // Loads don't depend on read-only calls + if (isa(QueryInst) && MR == AliasAnalysis::Ref) + continue; + + return MemDepResult::get(Inst); + } else { + // Non memory instruction, move to the next one. continue; } // If we found a pointer, check if it could be the same as our pointer - if (pointer) { - AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize, - dependee, dependeeSize); - - if (R != AliasAnalysis::NoAlias) { - // May-alias loads don't depend on each other - if (isa(QueryInst) && isa(Inst) && - R == AliasAnalysis::MayAlias) - continue; - return MemDepResult::get(Inst); - } - } + AliasAnalysis::AliasResult R = + AA.alias(Pointer, PointerSize, MemPtr, MemSize); + + if (R == AliasAnalysis::NoAlias) + continue; + + // May-alias loads don't depend on each other without a dependence. + if (isa(QueryInst) && isa(Inst) && + R == AliasAnalysis::MayAlias) + continue; + return MemDepResult::get(Inst); } // If we found nothing, return the non-local flag. From edwintorok at gmail.com Sat Nov 29 02:52:45 2008 From: edwintorok at gmail.com (Torok Edwin) Date: Sat, 29 Nov 2008 08:52:45 -0000 Subject: [llvm-commits] [llvm] r60239 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811290852.mAT8qkLq002735@zion.cs.uiuc.edu> Author: edwin Date: Sat Nov 29 02:52:45 2008 New Revision: 60239 URL: http://llvm.org/viewvc/llvm-project?rev=60239&view=rev Log: protect against negative values that would exceed allowed bit width Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60239&r1=60238&r2=60239&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Sat Nov 29 02:52:45 2008 @@ -53,7 +53,7 @@ } void setInt(IntType Int) { - assert(Int < (1 << IntBits) && "Integer too large for field"); + assert(unsigned(Int) < (1 << IntBits) && "Integer too large for field"); Value = reinterpret_cast(getPointer()) | (intptr_t)Int; } From sabre at nondot.org Sat Nov 29 03:09:49 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 09:09:49 -0000 Subject: [llvm-commits] [llvm] r60240 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811290909.mAT99nR2007516@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 03:09:48 2008 New Revision: 60240 URL: http://llvm.org/viewvc/llvm-project?rev=60240&view=rev Log: eliminate a bunch of code in favor of using AliasAnalysis::getModRefInfo. Put a some code back to handle buggy behavior that GVN expects: it wants loads to depend on each other, and accesses to depend on their allocations. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60240&r1=60239&r2=60240&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 03:09:48 2008 @@ -310,68 +310,66 @@ // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; + + // If the access is volatile and this is a volatile load/store, return a + // dependence. + if (MemVolatile && + ((isa(Inst) && cast(Inst)->isVolatile()) || + (isa(Inst) && cast(Inst)->isVolatile()))) + return MemDepResult::get(Inst); + + // MemDep is broken w.r.t. loads: it says that two loads of the same pointer + // depend on each other. :( + // FIXME: ELIMINATE THIS! + if (LoadInst *L = dyn_cast(Inst)) { + Value *Pointer = L->getPointerOperand(); + uint64_t PointerSize = TD.getTypeStoreSize(L->getType()); + + // If we found a pointer, check if it could be the same as our pointer + AliasAnalysis::AliasResult R = + AA.alias(Pointer, PointerSize, MemPtr, MemSize); + + if (R == AliasAnalysis::NoAlias) + continue; + + // May-alias loads don't depend on each other without a dependence. + if (isa(QueryInst) && R == AliasAnalysis::MayAlias) + continue; + return MemDepResult::get(Inst); + } - // If this inst is a memory op, get the pointer it accessed - Value *Pointer = 0; - uint64_t PointerSize = 0; - if (StoreInst *S = dyn_cast(Inst)) { - // All volatile loads/stores depend on each other. - if (MemVolatile && S->isVolatile()) - return MemDepResult::get(S); - - Pointer = S->getPointerOperand(); - PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (LoadInst *L = dyn_cast(Inst)) { - // All volatile loads/stores depend on each other - if (MemVolatile && L->isVolatile()) - return MemDepResult::get(L); - - Pointer = L->getPointerOperand(); - PointerSize = TD.getTypeStoreSize(L->getType()); - } else if (AllocationInst *AI = dyn_cast(Inst)) { - Pointer = AI; + // FIXME: This claims that an access depends on the allocation. This may + // make sense, but is dubious at best. It would be better to fix GVN to + // handle a 'None' Query. + if (AllocationInst *AI = dyn_cast(Inst)) { + Value *Pointer = AI; + uint64_t PointerSize; if (ConstantInt *C = dyn_cast(AI->getArraySize())) PointerSize = C->getZExtValue() * - TD.getTypeStoreSize(AI->getAllocatedType()); + TD.getTypeStoreSize(AI->getAllocatedType()); else PointerSize = ~0UL; - } else if (VAArgInst *V = dyn_cast(Inst)) { - Pointer = V->getOperand(0); - PointerSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst *F = dyn_cast(Inst)) { - Pointer = F->getPointerOperand(); - - // FreeInsts erase the entire structure. - PointerSize = ~0UL; - } else if (isa(Inst) || isa(Inst)) { - // Calls need special handling. Check if they can modify our pointer. - AliasAnalysis::ModRefResult MR = - AA.getModRefInfo(CallSite::get(Inst), MemPtr, MemSize); - if (MR == AliasAnalysis::NoModRef) - continue; + AliasAnalysis::AliasResult R = + AA.alias(Pointer, PointerSize, MemPtr, MemSize); - // Loads don't depend on read-only calls - if (isa(QueryInst) && MR == AliasAnalysis::Ref) + if (R == AliasAnalysis::NoAlias) continue; - return MemDepResult::get(Inst); - } else { - // Non memory instruction, move to the next one. - continue; } - - // If we found a pointer, check if it could be the same as our pointer - AliasAnalysis::AliasResult R = - AA.alias(Pointer, PointerSize, MemPtr, MemSize); - if (R == AliasAnalysis::NoAlias) + + // See if this instruction mod/ref's the pointer. + AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize); + + if (MRR == AliasAnalysis::NoModRef) continue; - // May-alias loads don't depend on each other without a dependence. - if (isa(QueryInst) && isa(Inst) && - R == AliasAnalysis::MayAlias) + // Loads don't depend on read-only instructions. + if (isa(QueryInst) && MRR == AliasAnalysis::Ref) continue; + + // Otherwise, there is a dependence. return MemDepResult::get(Inst); } From sabre at nondot.org Sat Nov 29 03:15:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 09:15:21 -0000 Subject: [llvm-commits] [llvm] r60241 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811290915.mAT9FLbC008152@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 03:15:21 2008 New Revision: 60241 URL: http://llvm.org/viewvc/llvm-project?rev=60241&view=rev Log: rename some variables. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60241&r1=60240&r2=60241&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 03:15:21 2008 @@ -97,35 +97,35 @@ Instruction *Inst = --ScanIt; // If this inst is a memory op, get the pointer it accessed - Value* pointer = 0; - uint64_t pointerSize = 0; - if (StoreInst* S = dyn_cast(Inst)) { - pointer = S->getPointerOperand(); - pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (AllocationInst* AI = dyn_cast(Inst)) { - pointer = AI; - if (ConstantInt* C = dyn_cast(AI->getArraySize())) - pointerSize = C->getZExtValue() * + Value *Pointer = 0; + uint64_t PointerSize = 0; + if (StoreInst *S = dyn_cast(Inst)) { + Pointer = S->getPointerOperand(); + PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); + } else if (AllocationInst *AI = dyn_cast(Inst)) { + Pointer = AI; + if (ConstantInt *C = dyn_cast(AI->getArraySize())) + PointerSize = C->getZExtValue() * TD.getTypeStoreSize(AI->getAllocatedType()); else - pointerSize = ~0UL; - } else if (VAArgInst* V = dyn_cast(Inst)) { - pointer = V->getOperand(0); - pointerSize = TD.getTypeStoreSize(V->getType()); - } else if (FreeInst* F = dyn_cast(Inst)) { - pointer = F->getPointerOperand(); + PointerSize = ~0UL; + } else if (VAArgInst *V = dyn_cast(Inst)) { + Pointer = V->getOperand(0); + PointerSize = TD.getTypeStoreSize(V->getType()); + } else if (FreeInst *F = dyn_cast(Inst)) { + Pointer = F->getPointerOperand(); // FreeInsts erase the entire structure - pointerSize = ~0UL; - } else if (CallSite::get(Inst).getInstruction() != 0) { - if (AA.getModRefBehavior(CallSite::get(Inst)) != + PointerSize = ~0UL; + } else if (isa(Inst) || isa(Inst)) { + if (AA.getModRefBehavior(CallSite::get(Inst)) == AliasAnalysis::DoesNotAccessMemory) - return MemDepResult::get(Inst); - continue; + continue; + return MemDepResult::get(Inst); } else continue; - if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) + if (AA.getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) return MemDepResult::get(Inst); } From sabre at nondot.org Sat Nov 29 03:20:16 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 09:20:16 -0000 Subject: [llvm-commits] [llvm] r60242 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811290920.mAT9KG63008297@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 03:20:15 2008 New Revision: 60242 URL: http://llvm.org/viewvc/llvm-project?rev=60242&view=rev Log: rename some maps. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60242&r1=60241&r2=60242&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 03:20:15 2008 @@ -123,17 +123,17 @@ // A map from instructions to their non-local dependencies. // FIXME: DENSEMAP of DENSEMAP not a great idea. typedef DenseMap > nonLocalDepMapType; - nonLocalDepMapType depGraphNonLocal; + DenseMap > NonLocalDepMapType; + NonLocalDepMapType NonLocalDeps; // A reverse mapping from dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. typedef DenseMap > reverseDepMapType; - reverseDepMapType reverseDep; + SmallPtrSet > ReverseDepMapType; + ReverseDepMapType ReverseLocalDeps; // A reverse mapping form dependencies to the non-local dependees. - reverseDepMapType reverseDepNonLocal; + ReverseDepMapType ReverseNonLocalDeps; public: MemoryDependenceAnalysis() : FunctionPass(&ID) {} @@ -146,9 +146,9 @@ /// Clean up memory in between runs void releaseMemory() { LocalDeps.clear(); - depGraphNonLocal.clear(); - reverseDep.clear(); - reverseDepNonLocal.clear(); + NonLocalDeps.clear(); + ReverseLocalDeps.clear(); + ReverseNonLocalDeps.clear(); } /// getAnalysisUsage - Does not modify anything. It uses Value Numbering Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60242&r1=60241&r2=60242&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 03:20:15 2008 @@ -54,22 +54,22 @@ "Inst occurs in data structures"); } - for (nonLocalDepMapType::const_iterator I = depGraphNonLocal.begin(), - E = depGraphNonLocal.end(); I != E; ++I) { + for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), + E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); for (DenseMap::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) assert(II->second.getPointer() != D && "Inst occurs in data structures"); } - for (reverseDepMapType::const_iterator I = reverseDep.begin(), - E = reverseDep.end(); I != E; ++I) + for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), + E = ReverseLocalDeps.end(); I != E; ++I) for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) assert(*II != D && "Inst occurs in data structures"); - for (reverseDepMapType::const_iterator I = reverseDepNonLocal.begin(), - E = reverseDepNonLocal.end(); + for (ReverseDepMapType::const_iterator I = ReverseNonLocalDeps.begin(), + E = ReverseNonLocalDeps.end(); I != E; ++I) for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) @@ -225,8 +225,8 @@ /// blocks between the query and its dependencies. void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, DenseMap &resp) { - if (depGraphNonLocal.count(query)) { - DenseMap &cached = depGraphNonLocal[query]; + if (NonLocalDeps.count(query)) { + DenseMap &cached = NonLocalDeps[query]; NumCacheNonlocal++; SmallVector dirtied; @@ -250,7 +250,7 @@ for (DenseMap::iterator I = cached.begin(), E = cached.end(); I != E; ++I) { if (Instruction *Inst = I->second.getPointer()) - reverseDepNonLocal[Inst].insert(query); + ReverseNonLocalDeps[Inst].insert(query); resp[I->first] = ConvToResult(I->second); } @@ -260,7 +260,7 @@ NumUncacheNonlocal++; // If not, go ahead and search for non-local deps. - DenseMap &cached = depGraphNonLocal[query]; + DenseMap &cached = NonLocalDeps[query]; nonLocalHelper(query, query->getParent(), cached); // Update the non-local dependency cache @@ -268,7 +268,7 @@ E = cached.end(); I != E; ++I) { // FIXME: Merge with the code above! if (Instruction *Inst = I->second.getPointer()) - reverseDepNonLocal[Inst].insert(query); + ReverseNonLocalDeps[Inst].insert(query); resp[I->first] = ConvToResult(I->second); } } @@ -402,7 +402,7 @@ // FIXME: Don't convert back and forth! Make a shared helper function. LocalCache = ConvFromResult(Res); if (Instruction *I = Res.getInst()) - reverseDep[I].insert(QueryInst); + ReverseLocalDeps[I].insert(QueryInst); return Res; } @@ -415,38 +415,38 @@ LocalDepMapType::iterator depGraphEntry = LocalDeps.find(drop); if (depGraphEntry != LocalDeps.end()) if (Instruction *Inst = depGraphEntry->second.getPointer()) - reverseDep[Inst].erase(drop); + ReverseLocalDeps[Inst].erase(drop); // Drop dependency information for things that depended on this instr - SmallPtrSet& set = reverseDep[drop]; + SmallPtrSet& set = ReverseLocalDeps[drop]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) LocalDeps.erase(*I); LocalDeps.erase(drop); - reverseDep.erase(drop); + ReverseLocalDeps.erase(drop); for (DenseMap::iterator DI = - depGraphNonLocal[drop].begin(), DE = depGraphNonLocal[drop].end(); + NonLocalDeps[drop].begin(), DE = NonLocalDeps[drop].end(); DI != DE; ++DI) if (Instruction *Inst = DI->second.getPointer()) - reverseDepNonLocal[Inst].erase(drop); + ReverseNonLocalDeps[Inst].erase(drop); - if (reverseDepNonLocal.count(drop)) { + if (ReverseNonLocalDeps.count(drop)) { SmallPtrSet& set = - reverseDepNonLocal[drop]; + ReverseNonLocalDeps[drop]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap::iterator DI = - depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); + NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); DI != DE; ++DI) if (DI->second == DepResultTy(drop, Normal)) // FIXME: Why not remember the old insertion point?? DI->second = DepResultTy(0, Dirty); } - reverseDepNonLocal.erase(drop); - depGraphNonLocal.erase(drop); + ReverseNonLocalDeps.erase(drop); + NonLocalDeps.erase(drop); } /// removeInstruction - Remove an instruction from the dependence analysis, @@ -456,10 +456,10 @@ // Walk through the Non-local dependencies, removing this one as the value // for any cached queries. for (DenseMap::iterator DI = - depGraphNonLocal[RemInst].begin(), DE = depGraphNonLocal[RemInst].end(); + NonLocalDeps[RemInst].begin(), DE = NonLocalDeps[RemInst].end(); DI != DE; ++DI) if (Instruction *Inst = DI->second.getPointer()) - reverseDepNonLocal[Inst].erase(RemInst); + ReverseNonLocalDeps[Inst].erase(RemInst); // Shortly after this, we will look for things that depend on RemInst. In // order to update these, we'll need a new dependency to base them on. We @@ -479,7 +479,7 @@ // Remove us from DepInst's reverse set now that the local dep info is gone. if (Instruction *Inst = LocalDep.getPointer()) - reverseDep[Inst].erase(RemInst); + ReverseLocalDeps[Inst].erase(RemInst); // If we have unconfirmed info, don't trust it. if (LocalDep.getInt() != Dirty) { @@ -505,8 +505,8 @@ // Loop over all of the things that depend on the instruction we're removing. // - reverseDepMapType::iterator ReverseDepIt = reverseDep.find(RemInst); - if (ReverseDepIt != reverseDep.end()) { + ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); + if (ReverseDepIt != ReverseLocalDeps.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; for (SmallPtrSet::iterator I = ReverseDeps.begin(), E = ReverseDeps.end(); I != E; ++I) { @@ -522,26 +522,26 @@ // If our NewDependency is an instruction, make sure to remember that new // things depend on it. if (Instruction *Inst = NewDependency.getPointer()) - reverseDep[Inst].insert(InstDependingOnRemInst); + ReverseLocalDeps[Inst].insert(InstDependingOnRemInst); } - reverseDep.erase(RemInst); + ReverseLocalDeps.erase(RemInst); } - ReverseDepIt = reverseDepNonLocal.find(RemInst); - if (ReverseDepIt != reverseDepNonLocal.end()) { + ReverseDepIt = ReverseNonLocalDeps.find(RemInst); + if (ReverseDepIt != ReverseNonLocalDeps.end()) { SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) - for (DenseMap::iterator DI = - depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end(); + for (DenseMap::iterator + DI = NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); DI != DE; ++DI) if (DI->second == DepResultTy(RemInst, Normal)) // FIXME: Why not remember the old insertion point?? DI->second = DepResultTy(0, Dirty); - reverseDepNonLocal.erase(ReverseDepIt); + ReverseNonLocalDeps.erase(ReverseDepIt); } - depGraphNonLocal.erase(RemInst); + NonLocalDeps.erase(RemInst); getAnalysis().deleteValue(RemInst); From sabre at nondot.org Sat Nov 29 03:22:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 09:22:14 -0000 Subject: [llvm-commits] [llvm] r60243 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200811290922.mAT9MEoZ008357@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 03:22:14 2008 New Revision: 60243 URL: http://llvm.org/viewvc/llvm-project?rev=60243&view=rev Log: tidy up some variable names. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60243&r1=60242&r2=60243&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 03:22:14 2008 @@ -170,8 +170,8 @@ /// getNonLocalDependency - Fills the passed-in map with the non-local /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. - void getNonLocalDependency(Instruction* query, - DenseMap &resp); + void getNonLocalDependency(Instruction *QueryInst, + DenseMap &Result); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. @@ -201,15 +201,14 @@ return MemDepResult::getNone(); } - /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB); - void nonLocalHelper(Instruction* query, BasicBlock* block, - DenseMap &resp); + void nonLocalHelper(Instruction *Query, BasicBlock *BB, + DenseMap &Result); }; } // End llvm namespace From baldrick at free.fr Sat Nov 29 07:25:09 2008 From: baldrick at free.fr (Duncan Sands) Date: Sat, 29 Nov 2008 14:25:09 +0100 Subject: [llvm-commits] [llvm] r60238 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp In-Reply-To: <200811290851.mAT8pHPk002320@zion.cs.uiuc.edu> References: <200811290851.mAT8pHPk002320@zion.cs.uiuc.edu> Message-ID: <200811291425.10270.baldrick@free.fr> Hi Chris, > if (ConstantInt* C = dyn_cast(AI->getArraySize())) > pointerSize = C->getZExtValue() * > - TD.getABITypeSize(AI->getAllocatedType()); > + TD.getTypeStoreSize(AI->getAllocatedType()); this looks wrong: when alloca'ing multiple elements, the elements are spaced by the ABI size, not the store size, so I think this change is wrong when C > 1. That said, if C >= 1, then doing (C-1)*ABISize + StoreSize should be correct. > + } else if (AllocationInst *AI = dyn_cast(Inst)) { > + Pointer = AI; > + if (ConstantInt *C = dyn_cast(AI->getArraySize())) > + PointerSize = C->getZExtValue() * > + TD.getTypeStoreSize(AI->getAllocatedType()); Likewise. Ciao, Duncan. From nicholas at mxc.ca Sat Nov 29 14:13:25 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 29 Nov 2008 20:13:25 -0000 Subject: [llvm-commits] [llvm] r60250 - /llvm/trunk/docs/CodingStandards.html Message-ID: <200811292013.mATKDPuH026871@zion.cs.uiuc.edu> Author: nicholas Date: Sat Nov 29 14:13:25 2008 New Revision: 60250 URL: http://llvm.org/viewvc/llvm-project?rev=60250&view=rev Log: Fix spelling mistake. Modified: llvm/trunk/docs/CodingStandards.html Modified: llvm/trunk/docs/CodingStandards.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodingStandards.html?rev=60250&r1=60249&r2=60250&view=diff ============================================================================== --- llvm/trunk/docs/CodingStandards.html (original) +++ llvm/trunk/docs/CodingStandards.html Sat Nov 29 14:13:25 2008 @@ -238,7 +238,7 @@
  • System #includes
  • -

    ... and each catagory should be sorted by name.

    +

    ... and each category should be sorted by name.

    The "Main Module Header" file applies to .cpp file which implement an interface defined by a .h file. This #include From sabre at nondot.org Sat Nov 29 14:29:04 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 20:29:04 -0000 Subject: [llvm-commits] [llvm] r60251 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll Message-ID: <200811292029.mATKT4kM027332@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 14:29:04 2008 New Revision: 60251 URL: http://llvm.org/viewvc/llvm-project?rev=60251&view=rev Log: Fix a thinko that manifested as a crash on clamav last night. Added: llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60251&r1=60250&r2=60251&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sat Nov 29 14:29:04 2008 @@ -130,7 +130,7 @@ // If we deleted a store, reinvestigate this instruction. if (deletedStore) { - if (!isa(BB.begin())) + if (BBI != BB.begin()) --BBI; continue; } @@ -157,7 +157,7 @@ (!dep.isNormal() || DT.dominates(dep.getInst(), L))) { DeleteDeadInstruction(S); - if (!isa(BB.begin())) + if (BBI != BB.begin()) --BBI; NumFastStores++; MadeChange = true; Added: llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll?rev=60251&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/2008-11-29-OffEndOfBlock.ll Sat Nov 29 14:29:04 2008 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | opt -dse | llvm-dis + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + %struct.cab_archive = type { i32, i16, i16, i16, i16, i8, %struct.cab_folder*, %struct.cab_file* } + %struct.cab_file = type { i32, i16, i64, i8*, i32, i32, i32, %struct.cab_folder*, %struct.cab_file*, %struct.cab_archive*, %struct.cab_state* } + %struct.cab_folder = type { i16, i16, %struct.cab_archive*, i64, %struct.cab_folder* } + %struct.cab_state = type { i8*, i8*, [38912 x i8], i16, i16, i8*, i16 } + %struct.lzx_stream = type { i32, i32, i8, i64, i64, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8, i8, i32, i8*, i8*, i8*, i8*, i8*, i32, i32, i32, [84 x i8], [720 x i8], [314 x i8], [72 x i8], [104 x i16], [5408 x i16], [4596 x i16], [144 x i16], [51 x i32], [51 x i8], [32768 x i8], %struct.cab_file*, i32 (%struct.cab_file*, i8*, i32)* } + +declare fastcc i32 @lzx_read_lens(%struct.lzx_stream*, i8*, i32, i32) nounwind + +define i32 @lzx_decompress(%struct.lzx_stream* %lzx, i64 %out_bytes) nounwind { +bb13: ; preds = %entry + %0 = getelementptr %struct.lzx_stream* %lzx, i32 0, i32 25 ; [#uses=2] + %1 = getelementptr %struct.lzx_stream* %lzx, i32 0, i32 26 ; [#uses=2] + %2 = getelementptr %struct.lzx_stream* %lzx, i32 0, i32 29 ; [#uses=0] + br label %bb14 + +bb14: ; preds = %bb13 + %3 = load i8** %0, align 4 ; [#uses=1] + %4 = load i8** %1, align 4 ; [#uses=1] + store i8* %3, i8** %0, align 4 + store i8* %4, i8** %1, align 4 + %5 = call fastcc i32 @lzx_read_lens(%struct.lzx_stream* %lzx, i8* null, i32 256, i32 0) nounwind ; [#uses=0] + unreachable +} From sabre at nondot.org Sat Nov 29 15:21:55 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 21:21:55 -0000 Subject: [llvm-commits] [llvm] r60252 - /llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll Message-ID: <200811292121.mATLLtvI028843@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 15:21:48 2008 New Revision: 60252 URL: http://llvm.org/viewvc/llvm-project?rev=60252&view=rev Log: don't require GVN to work on dead values, just make the test return the loaded value. Modified: llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll Modified: llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll?rev=60252&r1=60251&r2=60252&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll (original) +++ llvm/trunk/test/Transforms/GVN/2008-07-02-Unreachable.ll Sat Nov 29 15:21:48 2008 @@ -1,10 +1,9 @@ ; RUN: llvm-as < %s | opt -gvn | llvm-dis | grep undef ; PR2503 -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin9.3.0" + @g_3 = external global i8 ; [#uses=2] -define i32 @func_1() nounwind { +define i8 @func_1() nounwind { entry: br i1 false, label %ifelse, label %ifthen @@ -29,8 +28,8 @@ afterfor: ; preds = %forcond, %forcond.thread %tmp10 = load i8* @g_3 ; [#uses=0] - br label %ifend + ret i8 %tmp10 ifend: ; preds = %afterfor, %ifthen - ret i32 0 + ret i8 0 } From sabre at nondot.org Sat Nov 29 15:22:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 21:22:42 -0000 Subject: [llvm-commits] [llvm] r60253 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200811292122.mATLMgZS028878@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 15:22:42 2008 New Revision: 60253 URL: http://llvm.org/viewvc/llvm-project?rev=60253&view=rev Log: reimplement getNonLocalDependency with a simpler worklist formulation that is faster and doesn't require nonLazyHelper. Much less code. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60253&r1=60252&r2=60253&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 15:22:42 2008 @@ -57,16 +57,16 @@ /// isNormal - Return true if this MemDepResult represents a query that is /// a normal instruction dependency. - bool isNormal() const { return Value.getInt() == Normal; } + bool isNormal() const { return Value.getInt() == Normal; } /// isNonLocal - Return true if this MemDepResult represents an query that /// is transparent to the start of the block, but where a non-local hasn't /// been done. - bool isNonLocal() const { return Value.getInt() == NonLocal; } + bool isNonLocal() const { return Value.getInt() == NonLocal; } /// isNone - Return true if this MemDepResult represents a query that /// doesn't depend on any instruction. - bool isNone() const { return Value.getInt() == None; } + bool isNone() const { return Value.getInt() == None; } /// getInst() - If this is a normal dependency, return the instruction that /// is depended on. Otherwise, return null. @@ -167,9 +167,13 @@ BasicBlock::iterator ScanIt, BasicBlock *BB); - /// getNonLocalDependency - Fills the passed-in map with the non-local - /// dependencies of the queries. The map will contain NonLocal for - /// blocks between the query and its dependencies. + /// getNonLocalDependency - Perform a full dependency query for the + /// specified instruction, returning the set of blocks that the value is + /// potentially live across. The returned set of results will include a + /// "NonLocal" result for all blocks where the value is live across. + /// + /// This method assumes the instruction returns a "nonlocal" dependency + /// within its own block. void getNonLocalDependency(Instruction *QueryInst, DenseMap &Result); @@ -207,8 +211,6 @@ MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB); - void nonLocalHelper(Instruction *Query, BasicBlock *BB, - DenseMap &Result); }; } // End llvm namespace Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60253&r1=60252&r2=60253&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 15:22:42 2008 @@ -28,13 +28,6 @@ #include "llvm/Target/TargetData.h" using namespace llvm; -// Control the calculation of non-local dependencies by only examining the -// predecessors if the basic block has less than X amount (50 by default). -static cl::opt -PredLimit("nonlocaldep-threshold", cl::Hidden, cl::init(50), - cl::desc("Control the calculation of non-local" - "dependencies (default = 50)")); - STATISTIC(NumCacheNonlocal, "Number of cached non-local responses"); STATISTIC(NumUncacheNonlocal, "Number of uncached non-local responses"); @@ -105,8 +98,10 @@ } else if (AllocationInst *AI = dyn_cast(Inst)) { Pointer = AI; if (ConstantInt *C = dyn_cast(AI->getArraySize())) + // Use ABI size (size between elements), not store size (size of one + // element without padding). PointerSize = C->getZExtValue() * - TD.getTypeStoreSize(AI->getAllocatedType()); + TD.getABITypeSize(AI->getAllocatedType()); else PointerSize = ~0UL; } else if (VAArgInst *V = dyn_cast(Inst)) { @@ -133,144 +128,84 @@ return MemDepResult::getNonLocal(); } -/// nonLocalHelper - Private helper used to calculate non-local dependencies -/// by doing DFS on the predecessors of a block to find its dependencies. -void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query, - BasicBlock* block, - DenseMap &resp) { - // Set of blocks that we've already visited in our DFS - SmallPtrSet visited; - // If we're updating a dirtied cache entry, we don't need to reprocess - // already computed entries. - for (DenseMap::iterator I = resp.begin(), - E = resp.end(); I != E; ++I) - if (I->second.getInt() != Dirty) - visited.insert(I->first); - - // Current stack of the DFS - SmallVector stack; - for (pred_iterator PI = pred_begin(block), PE = pred_end(block); - PI != PE; ++PI) - stack.push_back(*PI); - - // Do a basic DFS - while (!stack.empty()) { - BasicBlock* BB = stack.back(); - - // If we've already visited this block, no need to revist - if (visited.count(BB)) { - stack.pop_back(); - continue; - } - - // If we find a new block with a local dependency for query, - // then we insert the new dependency and backtrack. - if (BB != block) { - visited.insert(BB); - - MemDepResult localDep = getDependencyFrom(query, BB->end(), BB); - if (!localDep.isNonLocal()) { - resp.insert(std::make_pair(BB, ConvFromResult(localDep))); - stack.pop_back(); - continue; - } - // If we re-encounter the starting block, we still need to search it - // because there might be a dependency in the starting block AFTER - // the position of the query. This is necessary to get loops right. - } else if (BB == block) { - visited.insert(BB); - - MemDepResult localDep = getDependencyFrom(query, BB->end(), BB); - if (localDep.getInst() != query) - resp.insert(std::make_pair(BB, ConvFromResult(localDep))); - - stack.pop_back(); - continue; - } - - // If we didn't find anything, recurse on the precessors of this block - // Only do this for blocks with a small number of predecessors. - bool predOnStack = false; - bool inserted = false; - if (std::distance(pred_begin(BB), pred_end(BB)) <= PredLimit) { - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); - PI != PE; ++PI) - if (!visited.count(*PI)) { - stack.push_back(*PI); - inserted = true; - } else - predOnStack = true; - } - - // If we inserted a new predecessor, then we'll come back to this block - if (inserted) - continue; - // If we didn't insert because we have no predecessors, then this - // query has no dependency at all. - else if (!inserted && !predOnStack) { - resp.insert(std::make_pair(BB, DepResultTy(0, None))); - // If we didn't insert because our predecessors are already on the stack, - // then we might still have a dependency, but it will be discovered during - // backtracking. - } else if (!inserted && predOnStack){ - resp.insert(std::make_pair(BB, DepResultTy(0, NonLocal))); - } - - stack.pop_back(); - } -} - -/// getNonLocalDependency - Fills the passed-in map with the non-local -/// dependencies of the queries. The map will contain NonLocal for -/// blocks between the query and its dependencies. -void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, - DenseMap &resp) { - if (NonLocalDeps.count(query)) { - DenseMap &cached = NonLocalDeps[query]; - NumCacheNonlocal++; - - SmallVector dirtied; - for (DenseMap::iterator I = cached.begin(), - E = cached.end(); I != E; ++I) +/// getNonLocalDependency - Perform a full dependency query for the +/// specified instruction, returning the set of blocks that the value is +/// potentially live across. The returned set of results will include a +/// "NonLocal" result for all blocks where the value is live across. +/// +/// This method assumes the instruction returns a "nonlocal" dependency +/// within its own block. +/// +void MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst, + DenseMap &Result) { + assert(getDependency(QueryInst).isNonLocal() && + "getNonLocalDependency should only be used on insts with non-local deps!"); + DenseMap &Cache = NonLocalDeps[QueryInst]; + + /// DirtyBlocks - This is the set of blocks that need to be recomputed. This + /// can happen due to instructions being deleted etc. + SmallVector DirtyBlocks; + + if (!Cache.empty()) { + // If we already have a partially computed set of results, scan them to + // determine what is dirty, seeding our initial DirtyBlocks worklist. + // FIXME: In the "don't need to be updated" case, this is expensive, why not + // have a per-"cache" flag saying it is undirty? + for (DenseMap::iterator I = Cache.begin(), + E = Cache.end(); I != E; ++I) if (I->second.getInt() == Dirty) - dirtied.push_back(I->first); + DirtyBlocks.push_back(I->first); - for (SmallVector::iterator I = dirtied.begin(), - E = dirtied.end(); I != E; ++I) { - MemDepResult localDep = getDependencyFrom(query, (*I)->end(), *I); - if (!localDep.isNonLocal()) - cached[*I] = ConvFromResult(localDep); - else { - cached.erase(*I); - nonLocalHelper(query, *I, cached); - } - } - - // Update the reverse non-local dependency cache. - for (DenseMap::iterator I = cached.begin(), - E = cached.end(); I != E; ++I) { - if (Instruction *Inst = I->second.getPointer()) - ReverseNonLocalDeps[Inst].insert(query); - resp[I->first] = ConvToResult(I->second); + NumCacheNonlocal++; + } else { + // Seed DirtyBlocks with each of the preds of QueryInst's block. + BasicBlock *QueryBB = QueryInst->getParent(); + // FIXME: use range insertion/append. + for (pred_iterator PI = pred_begin(QueryBB), E = pred_end(QueryBB); + PI != E; ++PI) + DirtyBlocks.push_back(*PI); + NumUncacheNonlocal++; + } + + // Iterate while we still have blocks to update. + while (!DirtyBlocks.empty()) { + BasicBlock *DirtyBB = DirtyBlocks.back(); + DirtyBlocks.pop_back(); + + // Get the entry for this block. Note that this relies on DepResultTy + // default initializing to Dirty. + DepResultTy &DirtyBBEntry = Cache[DirtyBB]; + + // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. + if (DirtyBBEntry.getInt() != Dirty) continue; + + // Find out if this block has a local dependency for QueryInst. + // FIXME: If the dirty entry has an instruction pointer, scan from it! + // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. + DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, DirtyBB->end(), + DirtyBB)); + + // If the block has a dependency (i.e. it isn't completely transparent to + // the value), remember it! + if (DirtyBBEntry.getInt() != NonLocal) { + // Keep the ReverseNonLocalDeps map up to date so we can efficiently + // update this when we remove instructions. + if (Instruction *Inst = DirtyBBEntry.getPointer()) + ReverseNonLocalDeps[Inst].insert(QueryInst); + continue; } - return; + // If the block *is* completely transparent to the load, we need to check + // the predecessors of this block. Add them to our worklist. + for (pred_iterator I = pred_begin(DirtyBB), E = pred_end(DirtyBB); + I != E; ++I) + DirtyBlocks.push_back(*I); } - NumUncacheNonlocal++; - - // If not, go ahead and search for non-local deps. - DenseMap &cached = NonLocalDeps[query]; - nonLocalHelper(query, query->getParent(), cached); - - // Update the non-local dependency cache - for (DenseMap::iterator I = cached.begin(), - E = cached.end(); I != E; ++I) { - // FIXME: Merge with the code above! - if (Instruction *Inst = I->second.getPointer()) - ReverseNonLocalDeps[Inst].insert(query); - resp[I->first] = ConvToResult(I->second); - } + // Copy the result into the output set. + for (DenseMap::iterator I = Cache.begin(), + E = Cache.end(); I != E; ++I) + Result[I->first] = ConvToResult(I->second); } /// getDependency - Return the instruction on which a memory operation @@ -345,8 +280,10 @@ Value *Pointer = AI; uint64_t PointerSize; if (ConstantInt *C = dyn_cast(AI->getArraySize())) + // Use ABI size (size between elements), not store size (size of one + // element without padding). PointerSize = C->getZExtValue() * - TD.getTypeStoreSize(AI->getAllocatedType()); + TD.getABITypeSize(AI->getAllocatedType()); else PointerSize = ~0UL; Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60253&r1=60252&r2=60253&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sat Nov 29 15:22:42 2008 @@ -508,7 +508,7 @@ } else if (Instruction *NonLocalDepInst = I->second.getInst()) { // FIXME: INDENT PROPERLY // FIXME: All duplicated with non-local case. - if (DT->properlyDominates(I->first, C->getParent())) { + if (cdep == 0 && DT->properlyDominates(I->first, C->getParent())) { if (CallInst* CD = dyn_cast(NonLocalDepInst)) cdep = CD; else { @@ -527,6 +527,12 @@ return nextValueNumber++; } + // FIXME: THIS ISN'T SAFE: CONSIDER: + // X = strlen(str) + // if (C) + // str[0] = 1; + // Y = strlen(str) + // This doesn't guarantee all-paths availability! if (cdep->getCalledFunction() != C->getCalledFunction() || cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); @@ -874,16 +880,27 @@ if (deps.size() > 100) return false; + BasicBlock *EntryBlock = &L->getParent()->getParent()->getEntryBlock(); + DenseMap repl; // Filter out useless results (non-locals, etc) for (DenseMap::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { - if (I->second.isNone()) - return false; + if (I->second.isNone()) { + repl[I->first] = UndefValue::get(L->getType()); + continue; + } - if (I->second.isNonLocal()) + if (I->second.isNonLocal()) { + // If this is a non-local dependency in the entry block, then we depend on + // the value live-in at the start of the function. We could insert a load + // in the entry block to get this, but for now we'll just bail out. + // FIXME: Consider emitting a load in the entry block to catch this case! + if (I->first == EntryBlock) + return false; continue; + } if (StoreInst* S = dyn_cast(I->second.getInst())) { if (S->getPointerOperand() != L->getPointerOperand()) From sabre at nondot.org Sat Nov 29 15:23:01 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 13:23:01 -0800 Subject: [llvm-commits] [llvm] r60238 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp In-Reply-To: <200811291425.10270.baldrick@free.fr> References: <200811290851.mAT8pHPk002320@zion.cs.uiuc.edu> <200811291425.10270.baldrick@free.fr> Message-ID: <8BEEDCA8-5639-4563-884E-4E128E6F5944@nondot.org> On Nov 29, 2008, at 5:25 AM, Duncan Sands wrote: > Hi Chris, > >> if (ConstantInt* C = dyn_cast(AI->getArraySize())) >> pointerSize = C->getZExtValue() * >> - TD.getABITypeSize(AI->getAllocatedType()); >> + TD.getTypeStoreSize(AI->getAllocatedType()); > > this looks wrong: when alloca'ing multiple elements, the elements > are spaced > by the ABI size, not the store size, so I think this change is wrong > when C > 1. > That said, if C >= 1, then doing (C-1)*ABISize + StoreSize should be > correct. > >> + } else if (AllocationInst *AI = >> dyn_cast(Inst)) { >> + Pointer = AI; >> + if (ConstantInt *C = dyn_cast(AI- >> >getArraySize())) >> + PointerSize = C->getZExtValue() * >> + TD.getTypeStoreSize(AI->getAllocatedType()); Fixed, thanks! -Chris From sabre at nondot.org Sat Nov 29 15:25:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 21:25:11 -0000 Subject: [llvm-commits] [llvm] r60254 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811292125.mATLPBFZ028948@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 15:25:10 2008 New Revision: 60254 URL: http://llvm.org/viewvc/llvm-project?rev=60254&view=rev Log: move MemoryDependenceAnalysis::verifyRemoved to the end of the file, no functionality/code change. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60254&r1=60253&r2=60254&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 15:25:10 2008 @@ -37,38 +37,6 @@ static RegisterPass X("memdep", "Memory Dependence Analysis", false, true); -/// verifyRemoved - Verify that the specified instruction does not occur -/// in our internal data structures. -void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { - for (LocalDepMapType::const_iterator I = LocalDeps.begin(), - E = LocalDeps.end(); I != E; ++I) { - assert(I->first != D && "Inst occurs in data structures"); - assert(I->second.getPointer() != D && - "Inst occurs in data structures"); - } - - for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), - E = NonLocalDeps.end(); I != E; ++I) { - assert(I->first != D && "Inst occurs in data structures"); - for (DenseMap::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) - assert(II->second.getPointer() != D && "Inst occurs in data structures"); - } - - for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), - E = ReverseLocalDeps.end(); I != E; ++I) - for (SmallPtrSet::const_iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) - assert(*II != D && "Inst occurs in data structures"); - - for (ReverseDepMapType::const_iterator I = ReverseNonLocalDeps.begin(), - E = ReverseNonLocalDeps.end(); - I != E; ++I) - for (SmallPtrSet::const_iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) - assert(*II != D && "Inst occurs in data structures"); -} - /// getAnalysisUsage - Does not modify anything. It uses Alias Analysis. /// void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { @@ -484,3 +452,35 @@ DEBUG(verifyRemoved(RemInst)); } + +/// verifyRemoved - Verify that the specified instruction does not occur +/// in our internal data structures. +void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { + for (LocalDepMapType::const_iterator I = LocalDeps.begin(), + E = LocalDeps.end(); I != E; ++I) { + assert(I->first != D && "Inst occurs in data structures"); + assert(I->second.getPointer() != D && + "Inst occurs in data structures"); + } + + for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), + E = NonLocalDeps.end(); I != E; ++I) { + assert(I->first != D && "Inst occurs in data structures"); + for (DenseMap::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) + assert(II->second.getPointer() != D && "Inst occurs in data structures"); + } + + for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), + E = ReverseLocalDeps.end(); I != E; ++I) + for (SmallPtrSet::const_iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) + assert(*II != D && "Inst occurs in data structures"); + + for (ReverseDepMapType::const_iterator I = ReverseNonLocalDeps.begin(), + E = ReverseNonLocalDeps.end(); + I != E; ++I) + for (SmallPtrSet::const_iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) + assert(*II != D && "Inst occurs in data structures"); +} From sabre at nondot.org Sat Nov 29 15:33:22 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 21:33:22 -0000 Subject: [llvm-commits] [llvm] r60255 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200811292133.mATLXMrs029181@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 15:33:22 2008 New Revision: 60255 URL: http://llvm.org/viewvc/llvm-project?rev=60255&view=rev Log: Change MemDep::getNonLocalDependency to return its results as a smallvector instead of a DenseMap. This speeds up GVN by 5% on 403.gcc. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60255&r1=60254&r2=60255&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 15:33:22 2008 @@ -175,7 +175,8 @@ /// This method assumes the instruction returns a "nonlocal" dependency /// within its own block. void getNonLocalDependency(Instruction *QueryInst, - DenseMap &Result); + SmallVectorImpl > &Result); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60255&r1=60254&r2=60255&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 15:33:22 2008 @@ -104,8 +104,10 @@ /// This method assumes the instruction returns a "nonlocal" dependency /// within its own block. /// -void MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst, - DenseMap &Result) { +void MemoryDependenceAnalysis:: +getNonLocalDependency(Instruction *QueryInst, + SmallVectorImpl > &Result) { assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); DenseMap &Cache = NonLocalDeps[QueryInst]; @@ -128,10 +130,7 @@ } else { // Seed DirtyBlocks with each of the preds of QueryInst's block. BasicBlock *QueryBB = QueryInst->getParent(); - // FIXME: use range insertion/append. - for (pred_iterator PI = pred_begin(QueryBB), E = pred_end(QueryBB); - PI != E; ++PI) - DirtyBlocks.push_back(*PI); + DirtyBlocks.append(pred_begin(QueryBB), pred_end(QueryBB)); NumUncacheNonlocal++; } @@ -173,7 +172,7 @@ // Copy the result into the output set. for (DenseMap::iterator I = Cache.begin(), E = Cache.end(); I != E; ++I) - Result[I->first] = ConvToResult(I->second); + Result.push_back(std::make_pair(I->first, ConvToResult(I->second))); } /// getDependency - Return the instruction on which a memory operation Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60255&r1=60254&r2=60255&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sat Nov 29 15:33:22 2008 @@ -495,11 +495,11 @@ } - DenseMap deps; + SmallVector, 32> deps; MD->getNonLocalDependency(C, deps); CallInst* cdep = 0; - for (DenseMap + for (SmallVector, 32> ::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { if (I->second.isNone()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); @@ -871,7 +871,7 @@ MemoryDependenceAnalysis& MD = getAnalysis(); // Find the non-local dependencies of the load - DenseMap deps; + SmallVector, 32> deps; MD.getNonLocalDependency(L, deps); // If we had to process more than one hundred blocks to find the @@ -885,8 +885,8 @@ DenseMap repl; // Filter out useless results (non-locals, etc) - for (DenseMap::iterator I = deps.begin(), - E = deps.end(); I != E; ++I) { + for (SmallVector, 32>::iterator + I = deps.begin(), E = deps.end(); I != E; ++I) { if (I->second.isNone()) { repl[I->first] = UndefValue::get(L->getType()); continue; From sabre at nondot.org Sat Nov 29 16:02:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 22:02:15 -0000 Subject: [llvm-commits] [llvm] r60256 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811292202.mATM2FKr030002@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 16:02:15 2008 New Revision: 60256 URL: http://llvm.org/viewvc/llvm-project?rev=60256&view=rev Log: implement some fixme's: when deleting an instruction with an entry in the nonlocal deps map, don't reset entries referencing that instruction to [dirty, null], instead, set them to [dirty,next] where next is the instruction after the deleted one. Use this information in the non-local deps code to avoid rescanning entire blocks. This speeds up GVN slightly by avoiding pointless work. On 403.gcc this makes GVN 1.5% faster. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60256&r1=60255&r2=60256&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 16:02:15 2008 @@ -84,19 +84,15 @@ /// DepType - This enum is used to indicate what flavor of dependence this /// is. If the type is Normal, there is an associated instruction pointer. enum DepType { - /// Dirty - Entries with this marker may come in two forms, depending on - /// whether they are in a LocalDeps map or NonLocalDeps map. In either - /// case, this marker indicates that the cached value has been invalidated - /// by a removeInstruction call. - /// - /// If in the LocalDeps map, the Instruction field will indicate the place - /// in the current block to start scanning. If in the non-localdeps map, - /// the instruction will be null. + /// Dirty - Entries with this marker occur in a LocalDeps map or + /// NonLocalDeps map when the instruction they previously referenced was + /// removed from MemDep. In either case, the entry may include an + /// instruction pointer. If so, the pointer is an instruction in the + /// block where scanning can start from, saving some work. /// /// In a default-constructed DepResultTy object, the type will be Dirty /// and the instruction pointer will be null. /// - /// FIXME: Why not add a scanning point for the non-local deps map??? Dirty = 0, /// Normal - This is a normal instruction dependence. The pointer member Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60256&r1=60255&r2=60256&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 16:02:15 2008 @@ -28,8 +28,8 @@ #include "llvm/Target/TargetData.h" using namespace llvm; -STATISTIC(NumCacheNonlocal, "Number of cached non-local responses"); -STATISTIC(NumUncacheNonlocal, "Number of uncached non-local responses"); +STATISTIC(NumCacheNonLocal, "Number of cached non-local responses"); +STATISTIC(NumUncacheNonLocal, "Number of uncached non-local responses"); char MemoryDependenceAnalysis::ID = 0; @@ -112,8 +112,10 @@ "getNonLocalDependency should only be used on insts with non-local deps!"); DenseMap &Cache = NonLocalDeps[QueryInst]; - /// DirtyBlocks - This is the set of blocks that need to be recomputed. This - /// can happen due to instructions being deleted etc. + /// DirtyBlocks - This is the set of blocks that need to be recomputed. In + /// the cached case, this can happen due to instructions being deleted etc. In + /// the uncached case, this starts out as the set of predecessors we care + /// about. SmallVector DirtyBlocks; if (!Cache.empty()) { @@ -126,12 +128,15 @@ if (I->second.getInt() == Dirty) DirtyBlocks.push_back(I->first); - NumCacheNonlocal++; + NumCacheNonLocal++; + + //cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " + // << Cache.size() << " cached: " << *QueryInst; } else { // Seed DirtyBlocks with each of the preds of QueryInst's block. BasicBlock *QueryBB = QueryInst->getParent(); DirtyBlocks.append(pred_begin(QueryBB), pred_end(QueryBB)); - NumUncacheNonlocal++; + NumUncacheNonLocal++; } // Iterate while we still have blocks to update. @@ -149,7 +154,14 @@ // Find out if this block has a local dependency for QueryInst. // FIXME: If the dirty entry has an instruction pointer, scan from it! // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. - DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, DirtyBB->end(), + + // If the dirty entry has a pointer, start scanning from it so we don't have + // to rescan the entire block. + BasicBlock::iterator ScanPos = DirtyBB->end(); + if (Instruction *Inst = DirtyBBEntry.getPointer()) + ScanPos = Inst; + + DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, ScanPos, DirtyBB)); // If the block has a dependency (i.e. it isn't completely transparent to @@ -289,7 +301,8 @@ // Check for a cached result DepResultTy &LocalCache = LocalDeps[QueryInst]; - // If the cached entry is non-dirty, just return it. + // If the cached entry is non-dirty, just return it. Note that this depends + // on DepResultTy's default constructing to 'dirty'. if (LocalCache.getInt() != Dirty) return ConvToResult(LocalCache); @@ -337,6 +350,8 @@ ReverseNonLocalDeps[Inst].erase(drop); if (ReverseNonLocalDeps.count(drop)) { + SmallVector, 8> ReverseDepsToAdd; + SmallPtrSet& set = ReverseNonLocalDeps[drop]; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); @@ -344,9 +359,24 @@ for (DenseMap::iterator DI = NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); DI != DE; ++DI) - if (DI->second == DepResultTy(drop, Normal)) - // FIXME: Why not remember the old insertion point?? - DI->second = DepResultTy(0, Dirty); + if (DI->second.getPointer() == drop) { + // Convert to a dirty entry for the subsequent instruction. + DI->second.setInt(Dirty); + if (drop->isTerminator()) + DI->second.setPointer(0); + else { + Instruction *NextI = next(BasicBlock::iterator(drop)); + DI->second.setPointer(NextI); + ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); + } + } + + // Add new reverse deps after scanning the set, to avoid invalidating 'Set' + while (!ReverseDepsToAdd.empty()) { + ReverseNonLocalDeps[ReverseDepsToAdd.back().first] + .insert(ReverseDepsToAdd.back().second); + ReverseDepsToAdd.pop_back(); + } } ReverseNonLocalDeps.erase(drop); @@ -433,15 +463,33 @@ ReverseDepIt = ReverseNonLocalDeps.find(RemInst); if (ReverseDepIt != ReverseNonLocalDeps.end()) { + SmallVector, 8> ReverseDepsToAdd; + SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) for (DenseMap::iterator DI = NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); DI != DE; ++DI) - if (DI->second == DepResultTy(RemInst, Normal)) - // FIXME: Why not remember the old insertion point?? - DI->second = DepResultTy(0, Dirty); + if (DI->second.getPointer() == RemInst) { + // Convert to a dirty entry for the subsequent instruction. + DI->second.setInt(Dirty); + if (RemInst->isTerminator()) + DI->second.setPointer(0); + else { + Instruction *NextI = next(BasicBlock::iterator(RemInst)); + DI->second.setPointer(NextI); + ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); + } + } + + // Add new reverse deps after scanning the set, to avoid invalidating 'Set' + while (!ReverseDepsToAdd.empty()) { + ReverseNonLocalDeps[ReverseDepsToAdd.back().first] + .insert(ReverseDepsToAdd.back().second); + ReverseDepsToAdd.pop_back(); + } + ReverseNonLocalDeps.erase(ReverseDepIt); } From nicholas at mxc.ca Sat Nov 29 16:49:59 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 29 Nov 2008 22:49:59 -0000 Subject: [llvm-commits] [llvm] r60257 - in /llvm/trunk: include/llvm-c/lto.h tools/lto/LTOModule.cpp Message-ID: <200811292249.mATMnxvl031311@zion.cs.uiuc.edu> Author: nicholas Date: Sat Nov 29 16:49:59 2008 New Revision: 60257 URL: http://llvm.org/viewvc/llvm-project?rev=60257&view=rev Log: Add protected visibility to libLTO. Modified: llvm/trunk/include/llvm-c/lto.h llvm/trunk/tools/lto/LTOModule.cpp Modified: llvm/trunk/include/llvm-c/lto.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=60257&r1=60256&r2=60257&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/lto.h (original) +++ llvm/trunk/include/llvm-c/lto.h Sat Nov 29 16:49:59 2008 @@ -30,9 +30,10 @@ LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200, LTO_SYMBOL_DEFINITION_WEAK = 0x00000300, LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400, - LTO_SYMBOL_SCOPE_MASK = 0x00001800, + LTO_SYMBOL_SCOPE_MASK = 0x00003800, LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800, LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000, + LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000, LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800 } lto_symbol_attributes; Modified: llvm/trunk/tools/lto/LTOModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=60257&r1=60256&r2=60257&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.cpp (original) +++ llvm/trunk/tools/lto/LTOModule.cpp Sat Nov 29 16:49:59 2008 @@ -224,6 +224,8 @@ // set scope part if ( def->hasHiddenVisibility() ) attr |= LTO_SYMBOL_SCOPE_HIDDEN; + else if ( def->hasProtectedVisibility() ) + attr |= LTO_SYMBOL_SCOPE_PROTECTED; else if ( def->hasExternalLinkage() || def->hasWeakLinkage() || def->hasLinkOnceLinkage() || def->hasCommonLinkage() ) attr |= LTO_SYMBOL_SCOPE_DEFAULT; From sabre at nondot.org Sat Nov 29 17:30:39 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 29 Nov 2008 23:30:39 -0000 Subject: [llvm-commits] [llvm] r60258 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <200811292330.mATNUd66032628@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 17:30:39 2008 New Revision: 60258 URL: http://llvm.org/viewvc/llvm-project?rev=60258&view=rev Log: Eliminate the dropInstruction method, which is not needed any more. Fix a subtle iterator invalidation bug I introduced in the last commit. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60258&r1=60257&r2=60258&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 17:30:39 2008 @@ -178,11 +178,6 @@ /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); - /// dropInstruction - Remove an instruction from the analysis, making - /// absolutely conservative assumptions when updating the cache. This is - /// useful, for example when an instruction is changed rather than removed. - void dropInstruction(Instruction *InstToDrop); - private: DepResultTy ConvFromResult(MemDepResult R) { if (Instruction *I = R.getInst()) Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60258&r1=60257&r2=60258&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 17:30:39 2008 @@ -138,7 +138,8 @@ DirtyBlocks.append(pred_begin(QueryBB), pred_end(QueryBB)); NumUncacheNonLocal++; } - + + // Iterate while we still have blocks to update. while (!DirtyBlocks.empty()) { BasicBlock *DirtyBB = DirtyBlocks.back(); @@ -147,10 +148,10 @@ // Get the entry for this block. Note that this relies on DepResultTy // default initializing to Dirty. DepResultTy &DirtyBBEntry = Cache[DirtyBB]; - + // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. if (DirtyBBEntry.getInt() != Dirty) continue; - + // Find out if this block has a local dependency for QueryInst. // FIXME: If the dirty entry has an instruction pointer, scan from it! // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. @@ -163,12 +164,12 @@ DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, ScanPos, DirtyBB)); - + // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember it! if (DirtyBBEntry.getInt() != NonLocal) { // Keep the ReverseNonLocalDeps map up to date so we can efficiently - // update this when we remove instructions. + // update this when we remove instructions. if (Instruction *Inst = DirtyBBEntry.getPointer()) ReverseNonLocalDeps[Inst].insert(QueryInst); continue; @@ -176,11 +177,10 @@ // If the block *is* completely transparent to the load, we need to check // the predecessors of this block. Add them to our worklist. - for (pred_iterator I = pred_begin(DirtyBB), E = pred_end(DirtyBB); - I != E; ++I) - DirtyBlocks.push_back(*I); + DirtyBlocks.append(pred_begin(DirtyBB), pred_end(DirtyBB)); } + // Copy the result into the output set. for (DenseMap::iterator I = Cache.begin(), E = Cache.end(); I != E; ++I) @@ -324,65 +324,6 @@ return Res; } - -/// dropInstruction - Remove an instruction from the analysis, making -/// absolutely conservative assumptions when updating the cache. This is -/// useful, for example when an instruction is changed rather than removed. -void MemoryDependenceAnalysis::dropInstruction(Instruction* drop) { - LocalDepMapType::iterator depGraphEntry = LocalDeps.find(drop); - if (depGraphEntry != LocalDeps.end()) - if (Instruction *Inst = depGraphEntry->second.getPointer()) - ReverseLocalDeps[Inst].erase(drop); - - // Drop dependency information for things that depended on this instr - SmallPtrSet& set = ReverseLocalDeps[drop]; - for (SmallPtrSet::iterator I = set.begin(), E = set.end(); - I != E; ++I) - LocalDeps.erase(*I); - - LocalDeps.erase(drop); - ReverseLocalDeps.erase(drop); - - for (DenseMap::iterator DI = - NonLocalDeps[drop].begin(), DE = NonLocalDeps[drop].end(); - DI != DE; ++DI) - if (Instruction *Inst = DI->second.getPointer()) - ReverseNonLocalDeps[Inst].erase(drop); - - if (ReverseNonLocalDeps.count(drop)) { - SmallVector, 8> ReverseDepsToAdd; - - SmallPtrSet& set = - ReverseNonLocalDeps[drop]; - for (SmallPtrSet::iterator I = set.begin(), E = set.end(); - I != E; ++I) - for (DenseMap::iterator DI = - NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); - DI != DE; ++DI) - if (DI->second.getPointer() == drop) { - // Convert to a dirty entry for the subsequent instruction. - DI->second.setInt(Dirty); - if (drop->isTerminator()) - DI->second.setPointer(0); - else { - Instruction *NextI = next(BasicBlock::iterator(drop)); - DI->second.setPointer(NextI); - ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); - } - } - - // Add new reverse deps after scanning the set, to avoid invalidating 'Set' - while (!ReverseDepsToAdd.empty()) { - ReverseNonLocalDeps[ReverseDepsToAdd.back().first] - .insert(ReverseDepsToAdd.back().second); - ReverseDepsToAdd.pop_back(); - } - } - - ReverseNonLocalDeps.erase(drop); - NonLocalDeps.erase(drop); -} - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. @@ -439,6 +380,8 @@ // Loop over all of the things that depend on the instruction we're removing. // + SmallVector, 8> ReverseDepsToAdd; + ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); if (ReverseDepIt != ReverseLocalDeps.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; @@ -451,20 +394,34 @@ if (InstDependingOnRemInst == RemInst) continue; // Insert the new dependencies. + // FIXME: DEPENDENCIES ARE NOT TRANSITIVE! + //cerr << "FOO:\n"; + //RemInst->dump(); + //InstDependingOnRemInst->dump(); LocalDeps[InstDependingOnRemInst] = NewDependency; // If our NewDependency is an instruction, make sure to remember that new // things depend on it. - if (Instruction *Inst = NewDependency.getPointer()) - ReverseLocalDeps[Inst].insert(InstDependingOnRemInst); + if (Instruction *Inst = NewDependency.getPointer()) { + assert(Inst != RemInst); + ReverseDepsToAdd.push_back(std::make_pair(Inst, + InstDependingOnRemInst)); + } + } + + ReverseLocalDeps.erase(ReverseDepIt); + + // Add new reverse deps after scanning the set, to avoid invalidating the + // 'ReverseDeps' reference. + while (!ReverseDepsToAdd.empty()) { + ReverseLocalDeps[ReverseDepsToAdd.back().first] + .insert(ReverseDepsToAdd.back().second); + ReverseDepsToAdd.pop_back(); } - ReverseLocalDeps.erase(RemInst); } ReverseDepIt = ReverseNonLocalDeps.find(RemInst); if (ReverseDepIt != ReverseNonLocalDeps.end()) { - SmallVector, 8> ReverseDepsToAdd; - SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) @@ -479,24 +436,23 @@ else { Instruction *NextI = next(BasicBlock::iterator(RemInst)); DI->second.setPointer(NextI); + assert(NextI != RemInst); ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); } } - + + ReverseNonLocalDeps.erase(ReverseDepIt); + // Add new reverse deps after scanning the set, to avoid invalidating 'Set' while (!ReverseDepsToAdd.empty()) { ReverseNonLocalDeps[ReverseDepsToAdd.back().first] .insert(ReverseDepsToAdd.back().second); ReverseDepsToAdd.pop_back(); } - - ReverseNonLocalDeps.erase(ReverseDepIt); } NonLocalDeps.erase(RemInst); - getAnalysis().deleteValue(RemInst); - DEBUG(verifyRemoved(RemInst)); } Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=60258&r1=60257&r2=60258&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Sat Nov 29 17:30:39 2008 @@ -609,7 +609,7 @@ // Drop any cached information about the call, because we may have changed // its dependence information by changing its parameter. MemoryDependenceAnalysis& MD = getAnalysis(); - MD.dropInstruction(C); + MD.removeInstruction(C); // Remove the memcpy MD.removeInstruction(cpy); @@ -691,11 +691,9 @@ // If C and M don't interfere, then this is a valid transformation. If they // did, this would mean that the two sources overlap, which would be bad. if (MD.getDependency(C) == dep) { - MD.dropInstruction(M); + MD.removeInstruction(M); M->eraseFromParent(); - NumMemCpyInstr++; - return true; } @@ -703,7 +701,6 @@ // inserted and act like nothing happened. MD.removeInstruction(C); C->eraseFromParent(); - return false; } From isanbard at gmail.com Sat Nov 29 17:54:54 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 29 Nov 2008 23:54:54 -0000 Subject: [llvm-commits] [llvm] r60259 - /llvm/tags/Apple/llvmCore-2084/ Message-ID: <200811292354.mATNstD1000855@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 17:54:54 2008 New Revision: 60259 URL: http://llvm.org/viewvc/llvm-project?rev=60259&view=rev Log: Creating llvmCore-2084 branch Added: llvm/tags/Apple/llvmCore-2084/ - copied from r60258, llvm/trunk/ From isanbard at gmail.com Sat Nov 29 17:55:01 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 29 Nov 2008 23:55:01 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60260 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2084/ Message-ID: <200811292355.mATNt1oa000869@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 17:55:01 2008 New Revision: 60260 URL: http://llvm.org/viewvc/llvm-project?rev=60260&view=rev Log: Creating llvmgcc42-2084 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2084/ - copied from r60259, llvm-gcc-4.2/trunk/ From nicholas at mxc.ca Sat Nov 29 18:36:34 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 30 Nov 2008 00:36:34 -0000 Subject: [llvm-commits] [llvm] r60261 - /llvm/trunk/tools/lto/LTOCodeGenerator.h Message-ID: <200811300036.mAU0aYcW002263@zion.cs.uiuc.edu> Author: nicholas Date: Sat Nov 29 18:36:34 2008 New Revision: 60261 URL: http://llvm.org/viewvc/llvm-project?rev=60261&view=rev Log: Remove warning about declaration does not declare anything. This class was already declared in the other headers. Modified: llvm/trunk/tools/lto/LTOCodeGenerator.h Modified: llvm/trunk/tools/lto/LTOCodeGenerator.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOCodeGenerator.h?rev=60261&r1=60260&r2=60261&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOCodeGenerator.h (original) +++ llvm/trunk/tools/lto/LTOCodeGenerator.h Sat Nov 29 18:36:34 2008 @@ -26,7 +26,6 @@ // C++ class which implements the opaque lto_code_gen_t // -class llvm::raw_ostream; class LTOCodeGenerator { public: static const char* getVersionString(); From sabre at nondot.org Sat Nov 29 18:50:20 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 00:50:20 -0000 Subject: [llvm-commits] [llvm] r60262 - /llvm/trunk/include/llvm/ADT/DenseMap.h Message-ID: <200811300050.mAU0oK15002881@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 18:50:20 2008 New Revision: 60262 URL: http://llvm.org/viewvc/llvm-project?rev=60262&view=rev Log: fix indentation. std::pair is "isPod" if the first/second are both isPod. Modified: llvm/trunk/include/llvm/ADT/DenseMap.h Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=60262&r1=60261&r2=60262&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Sat Nov 29 18:50:20 2008 @@ -67,22 +67,23 @@ } static inline Pair getTombstoneKey() { return std::make_pair(FirstInfo::getTombstoneKey(), - SecondInfo::getEmptyKey()); } - static unsigned getHashValue(const Pair& PairVal) { - uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 - | (uint64_t)SecondInfo::getHashValue(PairVal.second); - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return (unsigned)key; - } - static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } - static bool isPod() { return false; } + SecondInfo::getEmptyKey()); + } + static unsigned getHashValue(const Pair& PairVal) { + uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 + | (uint64_t)SecondInfo::getHashValue(PairVal.second); + key += ~(key << 32); + key ^= (key >> 22); + key += ~(key << 13); + key ^= (key >> 8); + key += (key << 3); + key ^= (key >> 15); + key += ~(key << 27); + key ^= (key >> 31); + return (unsigned)key; + } + static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } + static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); } }; template Author: lattner Date: Sat Nov 29 19:09:30 2008 New Revision: 60263 URL: http://llvm.org/viewvc/llvm-project?rev=60263&view=rev Log: remove a bit of incorrect code that tried to be tricky about speeding up dependencies. The basic situation was this: consider if we had: store1 ... store2 ... store3 Where memdep thinks that store3 depends on store2 and store2 depends on store1. The problem happens when we delete store2: The code in question was updating dep info for store3 to be store1. This is a spiffy optimization, but is not safe at all, because aliasing isn't transitive. This bug isn't exposed today with DSE because DSE will only zap store2 if it is identifical to store 3, and in this case, it is safe to update it to depend on store1. However, memcpyopt is not so fortunate, which is presumably why the "dropInstruction" code used to exist. Since this doesn't actually provide a speedup in practice, just rip the code out. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60263&r1=60262&r2=60263&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:09:30 2008 @@ -336,47 +336,21 @@ if (Instruction *Inst = DI->second.getPointer()) ReverseNonLocalDeps[Inst].erase(RemInst); - // Shortly after this, we will look for things that depend on RemInst. In - // order to update these, we'll need a new dependency to base them on. We - // could completely delete any entries that depend on this, but it is better - // to make a more accurate approximation where possible. Compute that better - // approximation if we can. - DepResultTy NewDependency; - // If we have a cached local dependence query for this instruction, remove it. // LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); if (LocalDepEntry != LocalDeps.end()) { - DepResultTy LocalDep = LocalDepEntry->second; - - // Remove this local dependency info. - LocalDeps.erase(LocalDepEntry); - // Remove us from DepInst's reverse set now that the local dep info is gone. - if (Instruction *Inst = LocalDep.getPointer()) - ReverseLocalDeps[Inst].erase(RemInst); - - // If we have unconfirmed info, don't trust it. - if (LocalDep.getInt() != Dirty) { - // If we have a confirmed non-local flag, use it. - if (LocalDep.getInt() == NonLocal || LocalDep.getInt() == None) { - // The only time this dependency is confirmed is if it is non-local. - NewDependency = LocalDep; - } else { - // If we have dep info for RemInst, set them to it. - Instruction *NDI = next(BasicBlock::iterator(LocalDep.getPointer())); - if (NDI != RemInst) // Don't use RemInst for the new dependency! - NewDependency = DepResultTy(NDI, Dirty); - } + if (Instruction *Inst = LocalDepEntry->second.getPointer()) { + SmallPtrSet &RLD = ReverseLocalDeps[Inst]; + RLD.erase(RemInst); + if (RLD.empty()) + ReverseLocalDeps.erase(Inst); } - } - - // If we don't already have a local dependency answer for this instruction, - // use the immediate successor of RemInst. We use the successor because - // getDependence starts by checking the immediate predecessor of what is in - // the cache. - if (NewDependency == DepResultTy(0, Dirty)) - NewDependency = DepResultTy(next(BasicBlock::iterator(RemInst)), Dirty); + + // Remove this local dependency info. + LocalDeps.erase(LocalDepEntry); + } // Loop over all of the things that depend on the instruction we're removing. // @@ -385,6 +359,16 @@ ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); if (ReverseDepIt != ReverseLocalDeps.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; + // RemInst can't be the terminator if it has stuff depending on it. + assert(!ReverseDeps.empty() && !isa(RemInst) && + "Nothing can locally depend on a terminator"); + + // Anything that was locally dependent on RemInst is now going to be + // dependent on the instruction after RemInst. It will have the dirty flag + // set so it will rescan. This saves having to scan the entire block to get + // to this point. + Instruction *NewDepInst = next(BasicBlock::iterator(RemInst)); + for (SmallPtrSet::iterator I = ReverseDeps.begin(), E = ReverseDeps.end(); I != E; ++I) { Instruction *InstDependingOnRemInst = *I; @@ -392,21 +376,12 @@ // If we thought the instruction depended on itself (possible for // unconfirmed dependencies) ignore the update. if (InstDependingOnRemInst == RemInst) continue; + + LocalDeps[InstDependingOnRemInst] = DepResultTy(NewDepInst, Dirty); - // Insert the new dependencies. - // FIXME: DEPENDENCIES ARE NOT TRANSITIVE! - //cerr << "FOO:\n"; - //RemInst->dump(); - //InstDependingOnRemInst->dump(); - LocalDeps[InstDependingOnRemInst] = NewDependency; - - // If our NewDependency is an instruction, make sure to remember that new - // things depend on it. - if (Instruction *Inst = NewDependency.getPointer()) { - assert(Inst != RemInst); - ReverseDepsToAdd.push_back(std::make_pair(Inst, - InstDependingOnRemInst)); - } + // Make sure to remember that new things depend on NewDepInst. + ReverseDepsToAdd.push_back(std::make_pair(NewDepInst, + InstDependingOnRemInst)); } ReverseLocalDeps.erase(ReverseDepIt); From sabre at nondot.org Sat Nov 29 19:17:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 01:17:08 -0000 Subject: [llvm-commits] [llvm] r60264 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300117.mAU1H8HI003595@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 19:17:08 2008 New Revision: 60264 URL: http://llvm.org/viewvc/llvm-project?rev=60264&view=rev Log: REmove an old fixme, resolve another fixme by adding liberal comments about what this class does. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60264&r1=60263&r2=60264&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 19:17:08 2008 @@ -80,6 +80,17 @@ /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, /// caching interface to a common kind of alias information query. + /// + /// The dependency information returned is somewhat unusual, but is pragmatic. + /// If queried about a store or call that might modify memory, the analysis + /// will return the instruction[s] that may either load from that memory or + /// store to it. If queried with a load or call that can never modify memory, + /// the analysis will return calls and stores that might modify the pointer, + /// but generally does not return loads unless a) they are volatile, or + /// b) they load from *must-aliased* pointers. Returning a dependence on + /// must-alias'd pointers instead of all pointers interacts well with the + /// internal caching mechanism. + /// class MemoryDependenceAnalysis : public FunctionPass { /// DepType - This enum is used to indicate what flavor of dependence this /// is. If the type is Normal, there is an associated instruction pointer. @@ -153,7 +164,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const; /// getDependency - Return the instruction on which a memory operation - /// depends. + /// depends. See the class comment for more details. MemDepResult getDependency(Instruction *QueryInst); /// getDependencyFrom - Return the instruction on which the memory operation Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60264&r1=60263&r2=60264&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:17:08 2008 @@ -153,7 +153,6 @@ if (DirtyBBEntry.getInt() != Dirty) continue; // Find out if this block has a local dependency for QueryInst. - // FIXME: If the dirty entry has an instruction pointer, scan from it! // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. // If the dirty entry has a pointer, start scanning from it so we don't have @@ -234,7 +233,6 @@ // MemDep is broken w.r.t. loads: it says that two loads of the same pointer // depend on each other. :( - // FIXME: ELIMINATE THIS! if (LoadInst *L = dyn_cast(Inst)) { Value *Pointer = L->getPointerOperand(); uint64_t PointerSize = TD.getTypeStoreSize(L->getType()); From sabre at nondot.org Sat Nov 29 19:18:28 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 01:18:28 -0000 Subject: [llvm-commits] [llvm] r60265 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300118.mAU1IS2F003640@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 19:18:27 2008 New Revision: 60265 URL: http://llvm.org/viewvc/llvm-project?rev=60265&view=rev Log: Move the getNonLocalDependency method to a more logical place in the file, no functionality change. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60265&r1=60264&r2=60265&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:18:27 2008 @@ -96,96 +96,6 @@ return MemDepResult::getNonLocal(); } -/// getNonLocalDependency - Perform a full dependency query for the -/// specified instruction, returning the set of blocks that the value is -/// potentially live across. The returned set of results will include a -/// "NonLocal" result for all blocks where the value is live across. -/// -/// This method assumes the instruction returns a "nonlocal" dependency -/// within its own block. -/// -void MemoryDependenceAnalysis:: -getNonLocalDependency(Instruction *QueryInst, - SmallVectorImpl > &Result) { - assert(getDependency(QueryInst).isNonLocal() && - "getNonLocalDependency should only be used on insts with non-local deps!"); - DenseMap &Cache = NonLocalDeps[QueryInst]; - - /// DirtyBlocks - This is the set of blocks that need to be recomputed. In - /// the cached case, this can happen due to instructions being deleted etc. In - /// the uncached case, this starts out as the set of predecessors we care - /// about. - SmallVector DirtyBlocks; - - if (!Cache.empty()) { - // If we already have a partially computed set of results, scan them to - // determine what is dirty, seeding our initial DirtyBlocks worklist. - // FIXME: In the "don't need to be updated" case, this is expensive, why not - // have a per-"cache" flag saying it is undirty? - for (DenseMap::iterator I = Cache.begin(), - E = Cache.end(); I != E; ++I) - if (I->second.getInt() == Dirty) - DirtyBlocks.push_back(I->first); - - NumCacheNonLocal++; - - //cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " - // << Cache.size() << " cached: " << *QueryInst; - } else { - // Seed DirtyBlocks with each of the preds of QueryInst's block. - BasicBlock *QueryBB = QueryInst->getParent(); - DirtyBlocks.append(pred_begin(QueryBB), pred_end(QueryBB)); - NumUncacheNonLocal++; - } - - - // Iterate while we still have blocks to update. - while (!DirtyBlocks.empty()) { - BasicBlock *DirtyBB = DirtyBlocks.back(); - DirtyBlocks.pop_back(); - - // Get the entry for this block. Note that this relies on DepResultTy - // default initializing to Dirty. - DepResultTy &DirtyBBEntry = Cache[DirtyBB]; - - // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. - if (DirtyBBEntry.getInt() != Dirty) continue; - - // Find out if this block has a local dependency for QueryInst. - // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. - - // If the dirty entry has a pointer, start scanning from it so we don't have - // to rescan the entire block. - BasicBlock::iterator ScanPos = DirtyBB->end(); - if (Instruction *Inst = DirtyBBEntry.getPointer()) - ScanPos = Inst; - - DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, ScanPos, - DirtyBB)); - - // If the block has a dependency (i.e. it isn't completely transparent to - // the value), remember it! - if (DirtyBBEntry.getInt() != NonLocal) { - // Keep the ReverseNonLocalDeps map up to date so we can efficiently - // update this when we remove instructions. - if (Instruction *Inst = DirtyBBEntry.getPointer()) - ReverseNonLocalDeps[Inst].insert(QueryInst); - continue; - } - - // If the block *is* completely transparent to the load, we need to check - // the predecessors of this block. Add them to our worklist. - DirtyBlocks.append(pred_begin(DirtyBB), pred_end(DirtyBB)); - } - - - // Copy the result into the output set. - for (DenseMap::iterator I = Cache.begin(), - E = Cache.end(); I != E; ++I) - Result.push_back(std::make_pair(I->first, ConvToResult(I->second))); -} - /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. @@ -322,6 +232,95 @@ return Res; } +/// getNonLocalDependency - Perform a full dependency query for the +/// specified instruction, returning the set of blocks that the value is +/// potentially live across. The returned set of results will include a +/// "NonLocal" result for all blocks where the value is live across. +/// +/// This method assumes the instruction returns a "nonlocal" dependency +/// within its own block. +/// +void MemoryDependenceAnalysis:: +getNonLocalDependency(Instruction *QueryInst, + SmallVectorImpl > &Result) { + assert(getDependency(QueryInst).isNonLocal() && + "getNonLocalDependency should only be used on insts with non-local deps!"); + DenseMap &Cache = NonLocalDeps[QueryInst]; + + /// DirtyBlocks - This is the set of blocks that need to be recomputed. In + /// the cached case, this can happen due to instructions being deleted etc. In + /// the uncached case, this starts out as the set of predecessors we care + /// about. + SmallVector DirtyBlocks; + + if (!Cache.empty()) { + // If we already have a partially computed set of results, scan them to + // determine what is dirty, seeding our initial DirtyBlocks worklist. + // FIXME: In the "don't need to be updated" case, this is expensive, why not + // have a per-"cache" flag saying it is undirty? + for (DenseMap::iterator I = Cache.begin(), + E = Cache.end(); I != E; ++I) + if (I->second.getInt() == Dirty) + DirtyBlocks.push_back(I->first); + + NumCacheNonLocal++; + + //cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " + // << Cache.size() << " cached: " << *QueryInst; + } else { + // Seed DirtyBlocks with each of the preds of QueryInst's block. + BasicBlock *QueryBB = QueryInst->getParent(); + DirtyBlocks.append(pred_begin(QueryBB), pred_end(QueryBB)); + NumUncacheNonLocal++; + } + + // Iterate while we still have blocks to update. + while (!DirtyBlocks.empty()) { + BasicBlock *DirtyBB = DirtyBlocks.back(); + DirtyBlocks.pop_back(); + + // Get the entry for this block. Note that this relies on DepResultTy + // default initializing to Dirty. + DepResultTy &DirtyBBEntry = Cache[DirtyBB]; + + // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. + if (DirtyBBEntry.getInt() != Dirty) continue; + + // Find out if this block has a local dependency for QueryInst. + // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. + + // If the dirty entry has a pointer, start scanning from it so we don't have + // to rescan the entire block. + BasicBlock::iterator ScanPos = DirtyBB->end(); + if (Instruction *Inst = DirtyBBEntry.getPointer()) + ScanPos = Inst; + + DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, ScanPos, + DirtyBB)); + + // If the block has a dependency (i.e. it isn't completely transparent to + // the value), remember it! + if (DirtyBBEntry.getInt() != NonLocal) { + // Keep the ReverseNonLocalDeps map up to date so we can efficiently + // update this when we remove instructions. + if (Instruction *Inst = DirtyBBEntry.getPointer()) + ReverseNonLocalDeps[Inst].insert(QueryInst); + continue; + } + + // If the block *is* completely transparent to the load, we need to check + // the predecessors of this block. Add them to our worklist. + DirtyBlocks.append(pred_begin(DirtyBB), pred_end(DirtyBB)); + } + + + // Copy the result into the output set. + for (DenseMap::iterator I = Cache.begin(), + E = Cache.end(); I != E; ++I) + Result.push_back(std::make_pair(I->first, ConvToResult(I->second))); +} + /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. From sabre at nondot.org Sat Nov 29 19:26:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 01:26:32 -0000 Subject: [llvm-commits] [llvm] r60266 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300126.mAU1QWeT004018@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 19:26:32 2008 New Revision: 60266 URL: http://llvm.org/viewvc/llvm-project?rev=60266&view=rev Log: implement a fixme by introducing a new getDependencyFromInternal method that returns its result as a DepResultTy instead of as a MemDepResult. This reduces conversion back and forth. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60266&r1=60265&r2=60266&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 19:26:32 2008 @@ -170,8 +170,13 @@ /// getDependencyFrom - Return the instruction on which the memory operation /// 'QueryInst' depends. This starts scanning from the instruction before /// the position indicated by ScanIt. + /// + /// Note that this method does no caching at all. You should use + /// getDependency where possible. MemDepResult getDependencyFrom(Instruction *QueryInst, - BasicBlock::iterator ScanIt, BasicBlock *BB); + BasicBlock::iterator ScanIt, BasicBlock *BB){ + return ConvToResult(getDependencyFromInternal(QueryInst, ScanIt, BB)); + } /// getNonLocalDependency - Perform a full dependency query for the @@ -190,15 +195,6 @@ void removeInstruction(Instruction *InstToRemove); private: - DepResultTy ConvFromResult(MemDepResult R) { - if (Instruction *I = R.getInst()) - return DepResultTy(I, Normal); - if (R.isNonLocal()) - return DepResultTy(0, NonLocal); - assert(R.isNone() && "Unknown MemDepResult!"); - return DepResultTy(0, None); - } - MemDepResult ConvToResult(DepResultTy R) { if (R.getInt() == Normal) return MemDepResult::get(R.getPointer()); @@ -212,8 +208,13 @@ /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, - BasicBlock *BB); + /// getDependencyFromInternal - Return the instruction on which the memory + /// operation 'QueryInst' depends. This starts scanning from the + /// instruction before the position indicated by ScanIt. + DepResultTy getDependencyFromInternal(Instruction *QueryInst, + BasicBlock::iterator ScanIt, BasicBlock *BB); + DepResultTy getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, + BasicBlock *BB); }; } // End llvm namespace Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60266&r1=60265&r2=60266&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:26:32 2008 @@ -47,7 +47,7 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. -MemDepResult MemoryDependenceAnalysis:: +MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB) { AliasAnalysis &AA = getAnalysis(); @@ -84,24 +84,24 @@ if (AA.getModRefBehavior(CallSite::get(Inst)) == AliasAnalysis::DoesNotAccessMemory) continue; - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); } else continue; if (AA.getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); } // No dependence found. - return MemDepResult::getNonLocal(); + return DepResultTy(0, NonLocal); } /// getDependency - Return the instruction on which a memory operation /// depends. The local parameter indicates if the query should only /// evaluate dependencies within the same basic block. -MemDepResult MemoryDependenceAnalysis:: -getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, - BasicBlock *BB) { +MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: +getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt, + BasicBlock *BB) { AliasAnalysis &AA = getAnalysis(); TargetData &TD = getAnalysis(); @@ -128,7 +128,7 @@ } else if (isa(QueryInst) || isa(QueryInst)) return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); else // Non-memory instructions depend on nothing. - return MemDepResult::getNone(); + return DepResultTy(0, None); // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { @@ -139,7 +139,7 @@ if (MemVolatile && ((isa(Inst) && cast(Inst)->isVolatile()) || (isa(Inst) && cast(Inst)->isVolatile()))) - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); // MemDep is broken w.r.t. loads: it says that two loads of the same pointer // depend on each other. :( @@ -157,7 +157,7 @@ // May-alias loads don't depend on each other without a dependence. if (isa(QueryInst) && R == AliasAnalysis::MayAlias) continue; - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); } // FIXME: This claims that an access depends on the allocation. This may @@ -179,7 +179,7 @@ if (R == AliasAnalysis::NoAlias) continue; - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); } @@ -194,11 +194,11 @@ continue; // Otherwise, there is a dependence. - return MemDepResult::get(Inst); + return DepResultTy(Inst, Normal); } // If we found nothing, return the non-local flag. - return MemDepResult::getNonLocal(); + return DepResultTy(0, NonLocal); } /// getDependency - Return the instruction on which a memory operation @@ -220,16 +220,14 @@ ScanPos = Inst; // Do the scan. - MemDepResult Res = - getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); + LocalCache = getDependencyFromInternal(QueryInst, ScanPos, + QueryInst->getParent()); // Remember the result! - // FIXME: Don't convert back and forth! Make a shared helper function. - LocalCache = ConvFromResult(Res); - if (Instruction *I = Res.getInst()) + if (Instruction *I = LocalCache.getPointer()) ReverseLocalDeps[I].insert(QueryInst); - return Res; + return ConvToResult(LocalCache); } /// getNonLocalDependency - Perform a full dependency query for the @@ -287,17 +285,14 @@ // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. if (DirtyBBEntry.getInt() != Dirty) continue; - // Find out if this block has a local dependency for QueryInst. - // FIXME: Don't convert back and forth for MemDepResult <-> DepResultTy. - // If the dirty entry has a pointer, start scanning from it so we don't have // to rescan the entire block. BasicBlock::iterator ScanPos = DirtyBB->end(); if (Instruction *Inst = DirtyBBEntry.getPointer()) ScanPos = Inst; - DirtyBBEntry = ConvFromResult(getDependencyFrom(QueryInst, ScanPos, - DirtyBB)); + // Find out if this block has a local dependency for QueryInst. + DirtyBBEntry = getDependencyFromInternal(QueryInst, ScanPos, DirtyBB); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember it! From sabre at nondot.org Sat Nov 29 19:39:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 01:39:32 -0000 Subject: [llvm-commits] [llvm] r60267 - in /llvm/trunk/lib: Analysis/MemoryDependenceAnalysis.cpp Transforms/Scalar/GVN.cpp Message-ID: <200811300139.mAU1dW4Z004693@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 19:39:32 2008 New Revision: 60267 URL: http://llvm.org/viewvc/llvm-project?rev=60267&view=rev Log: Fix a fixme by making memdep's handling of allocations more logical. If we see that a load depends on the allocation of its memory with no intervening stores, we now return a 'None' depedency instead of "Normal". This tweaks GVN to do its optimization with the new result. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60267&r1=60266&r2=60267&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:39:32 2008 @@ -159,29 +159,19 @@ continue; return DepResultTy(Inst, Normal); } - - // FIXME: This claims that an access depends on the allocation. This may - // make sense, but is dubious at best. It would be better to fix GVN to - // handle a 'None' Query. + + // If this is an allocation, and if we know that the accessed pointer is to + // the allocation, return None. This means that there is no dependence and + // the access can be optimized based on that. For example, a load could + // turn into undef. if (AllocationInst *AI = dyn_cast(Inst)) { - Value *Pointer = AI; - uint64_t PointerSize; - if (ConstantInt *C = dyn_cast(AI->getArraySize())) - // Use ABI size (size between elements), not store size (size of one - // element without padding). - PointerSize = C->getZExtValue() * - TD.getABITypeSize(AI->getAllocatedType()); - else - PointerSize = ~0UL; + Value *AccessPtr = MemPtr->getUnderlyingObject(); - AliasAnalysis::AliasResult R = - AA.alias(Pointer, PointerSize, MemPtr, MemSize); - - if (R == AliasAnalysis::NoAlias) - continue; - return DepResultTy(Inst, Normal); + if (AccessPtr == AI || + AA.alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) + return DepResultTy(0, None); + continue; } - // See if this instruction mod/ref's the pointer. AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize); Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60267&r1=60266&r2=60267&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sat Nov 29 19:39:32 2008 @@ -1004,27 +1004,24 @@ toErase.push_back(L); deletedLoad = true; NumGVNLoad++; - break; } else { dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent()); } } - if (AllocationInst *DepAI = dyn_cast_or_null(dep.getInst())) { - // Check that this load is actually from the - // allocation we found - if (L->getOperand(0)->getUnderlyingObject() == DepAI) { - // If this load depends directly on an allocation, there isn't - // anything stored there; therefore, we can optimize this load - // to undef. - MD.removeInstruction(L); - - L->replaceAllUsesWith(UndefValue::get(L->getType())); - toErase.push_back(L); - deletedLoad = true; - NumGVNLoad++; - } + // If this load really doesn't depend on anything, then we must be loading an + // undef value. This can happen when loading for a fresh allocation with no + // intervening stores, for example. + if (dep.isNone()) { + // If this load depends directly on an allocation, there isn't + // anything stored there; therefore, we can optimize this load + // to undef. + MD.removeInstruction(L); + L->replaceAllUsesWith(UndefValue::get(L->getType())); + toErase.push_back(L); + deletedLoad = true; + NumGVNLoad++; } if (!deletedLoad) From sabre at nondot.org Sat Nov 29 19:44:00 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 01:44:00 -0000 Subject: [llvm-commits] [llvm] r60268 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300144.mAU1i0Ps004848@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 19:44:00 2008 New Revision: 60268 URL: http://llvm.org/viewvc/llvm-project?rev=60268&view=rev Log: calls never depend on allocations. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60268&r1=60267&r2=60268&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 19:44:00 2008 @@ -63,15 +63,6 @@ if (StoreInst *S = dyn_cast(Inst)) { Pointer = S->getPointerOperand(); PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (AllocationInst *AI = dyn_cast(Inst)) { - Pointer = AI; - if (ConstantInt *C = dyn_cast(AI->getArraySize())) - // Use ABI size (size between elements), not store size (size of one - // element without padding). - PointerSize = C->getZExtValue() * - TD.getABITypeSize(AI->getAllocatedType()); - else - PointerSize = ~0UL; } else if (VAArgInst *V = dyn_cast(Inst)) { Pointer = V->getOperand(0); PointerSize = TD.getTypeStoreSize(V->getType()); @@ -85,8 +76,10 @@ AliasAnalysis::DoesNotAccessMemory) continue; return DepResultTy(Inst, Normal); - } else + } else { + // Non-memory instruction. continue; + } if (AA.getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) return DepResultTy(Inst, Normal); @@ -141,8 +134,8 @@ (isa(Inst) && cast(Inst)->isVolatile()))) return DepResultTy(Inst, Normal); - // MemDep is broken w.r.t. loads: it says that two loads of the same pointer - // depend on each other. :( + // Values depend on loads if the pointers are must aliased. This means that + // a load depends on another must aliased load from the same value. if (LoadInst *L = dyn_cast(Inst)) { Value *Pointer = L->getPointerOperand(); uint64_t PointerSize = TD.getTypeStoreSize(L->getType()); From sabre at nondot.org Sat Nov 29 20:28:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 02:28:26 -0000 Subject: [llvm-commits] [llvm] r60271 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300228.mAU2SQqL006116@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 20:28:25 2008 New Revision: 60271 URL: http://llvm.org/viewvc/llvm-project?rev=60271&view=rev Log: Change NonLocalDeps to be a densemap of pointers to densemap instead of containing them by value. This increases the density (!) of NonLocalDeps as well as making the reallocation case faster. This speeds up gvn on 403.gcc by 2% and makes room for future improvements. I'm not super thrilled with having to explicitly manage the new/delete of the map, but it is necesary for the next change. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60271&r1=60270&r2=60271&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 20:28:25 2008 @@ -111,9 +111,9 @@ Normal, /// None - This dependence type indicates that the query does not depend - /// on any instructions, either because it scanned to the start of the - /// function or it scanned to the definition of the memory - /// (alloca/malloc). + /// on any instructions, either because it is not a memory instruction or + /// because it scanned to the definition of the memory (alloca/malloc) + /// being accessed. None, /// NonLocal - This marker indicates that the query has no dependency in @@ -128,9 +128,9 @@ LocalDepMapType LocalDeps; // A map from instructions to their non-local dependencies. - // FIXME: DENSEMAP of DENSEMAP not a great idea. typedef DenseMap > NonLocalDepMapType; + // This is an owning pointer. + DenseMap*> NonLocalDepMapType; NonLocalDepMapType NonLocalDeps; // A reverse mapping from dependencies to the dependees. This is @@ -153,6 +153,9 @@ /// Clean up memory in between runs void releaseMemory() { LocalDeps.clear(); + for (NonLocalDepMapType::iterator I = NonLocalDeps.begin(), + E = NonLocalDeps.end(); I != E; ++I) + delete I->second; NonLocalDeps.clear(); ReverseLocalDeps.clear(); ReverseNonLocalDeps.clear(); Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60271&r1=60270&r2=60271&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 20:28:25 2008 @@ -227,7 +227,10 @@ MemDepResult> > &Result) { assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); - DenseMap &Cache = NonLocalDeps[QueryInst]; + DenseMap* &CacheP = NonLocalDeps[QueryInst]; + if (CacheP == 0) CacheP = new DenseMap(); + + DenseMap &Cache = *CacheP; /// DirtyBlocks - This is the set of blocks that need to be recomputed. In /// the cached case, this can happen due to instructions being deleted etc. In @@ -271,8 +274,14 @@ // If the dirty entry has a pointer, start scanning from it so we don't have // to rescan the entire block. BasicBlock::iterator ScanPos = DirtyBB->end(); - if (Instruction *Inst = DirtyBBEntry.getPointer()) + if (Instruction *Inst = DirtyBBEntry.getPointer()) { ScanPos = Inst; + + // We're removing QueryInst's dependence on Inst. + SmallPtrSet &InstMap = ReverseNonLocalDeps[Inst]; + InstMap.erase(QueryInst); + if (InstMap.empty()) ReverseNonLocalDeps.erase(Inst); + } // Find out if this block has a local dependency for QueryInst. DirtyBBEntry = getDependencyFromInternal(QueryInst, ScanPos, DirtyBB); @@ -305,11 +314,16 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { // Walk through the Non-local dependencies, removing this one as the value // for any cached queries. - for (DenseMap::iterator DI = - NonLocalDeps[RemInst].begin(), DE = NonLocalDeps[RemInst].end(); - DI != DE; ++DI) - if (Instruction *Inst = DI->second.getPointer()) - ReverseNonLocalDeps[Inst].erase(RemInst); + NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); + if (NLDI != NonLocalDeps.end()) { + DenseMap &BlockMap = *NLDI->second; + for (DenseMap::iterator DI = + BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) + if (Instruction *Inst = DI->second.getPointer()) + ReverseNonLocalDeps[Inst].erase(RemInst); + delete &BlockMap; + NonLocalDeps.erase(NLDI); + } // If we have a cached local dependence query for this instruction, remove it. // @@ -347,10 +361,8 @@ for (SmallPtrSet::iterator I = ReverseDeps.begin(), E = ReverseDeps.end(); I != E; ++I) { Instruction *InstDependingOnRemInst = *I; - - // If we thought the instruction depended on itself (possible for - // unconfirmed dependencies) ignore the update. - if (InstDependingOnRemInst == RemInst) continue; + assert(InstDependingOnRemInst != RemInst && + "Already removed our local dep info"); LocalDeps[InstDependingOnRemInst] = DepResultTy(NewDepInst, Dirty); @@ -374,22 +386,27 @@ if (ReverseDepIt != ReverseNonLocalDeps.end()) { SmallPtrSet& set = ReverseDepIt->second; for (SmallPtrSet::iterator I = set.begin(), E = set.end(); - I != E; ++I) + I != E; ++I) { + assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); + + DenseMap &INLD = *NonLocalDeps[*I]; + assert(&INLD != 0 && "Reverse mapping out of date?"); + for (DenseMap::iterator - DI = NonLocalDeps[*I].begin(), DE = NonLocalDeps[*I].end(); - DI != DE; ++DI) - if (DI->second.getPointer() == RemInst) { - // Convert to a dirty entry for the subsequent instruction. - DI->second.setInt(Dirty); - if (RemInst->isTerminator()) - DI->second.setPointer(0); - else { - Instruction *NextI = next(BasicBlock::iterator(RemInst)); - DI->second.setPointer(NextI); - assert(NextI != RemInst); - ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); - } + DI = INLD.begin(), DE = INLD.end(); DI != DE; ++DI) { + if (DI->second.getPointer() != RemInst) continue; + + // Convert to a dirty entry for the subsequent instruction. + DI->second.setInt(Dirty); + if (RemInst->isTerminator()) + DI->second.setPointer(0); + else { + Instruction *NextI = next(BasicBlock::iterator(RemInst)); + DI->second.setPointer(NextI); + ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); } + } + } ReverseNonLocalDeps.erase(ReverseDepIt); @@ -401,7 +418,7 @@ } } - NonLocalDeps.erase(RemInst); + assert(!NonLocalDeps.count(RemInst) && "RemInst got reinserted?"); getAnalysis().deleteValue(RemInst); DEBUG(verifyRemoved(RemInst)); } @@ -419,21 +436,26 @@ for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - for (DenseMap::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) + DenseMap &INLD = *I->second; + for (DenseMap::iterator II = INLD.begin(), + EE = INLD.end(); II != EE; ++II) assert(II->second.getPointer() != D && "Inst occurs in data structures"); } for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), - E = ReverseLocalDeps.end(); I != E; ++I) + E = ReverseLocalDeps.end(); I != E; ++I) { + assert(I->first != D && "Inst occurs in data structures"); for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) assert(*II != D && "Inst occurs in data structures"); + } for (ReverseDepMapType::const_iterator I = ReverseNonLocalDeps.begin(), E = ReverseNonLocalDeps.end(); - I != E; ++I) + I != E; ++I) { + assert(I->first != D && "Inst occurs in data structures"); for (SmallPtrSet::const_iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) assert(*II != D && "Inst occurs in data structures"); + } } From sabre at nondot.org Sat Nov 29 20:30:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 02:30:51 -0000 Subject: [llvm-commits] [llvm] r60272 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300230.mAU2Up9M006194@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 20:30:50 2008 New Revision: 60272 URL: http://llvm.org/viewvc/llvm-project?rev=60272&view=rev Log: introduce a typedef, no functionality change. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60272&r1=60271&r2=60272&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 20:30:50 2008 @@ -127,10 +127,13 @@ typedef DenseMap LocalDepMapType; LocalDepMapType LocalDeps; + typedef DenseMap NonLocalDepInfo; + + // A map from instructions to their non-local dependencies. typedef DenseMap*> NonLocalDepMapType; + NonLocalDepInfo*> NonLocalDepMapType; NonLocalDepMapType NonLocalDeps; // A reverse mapping from dependencies to the dependees. This is Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60272&r1=60271&r2=60272&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 20:30:50 2008 @@ -227,10 +227,10 @@ MemDepResult> > &Result) { assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); - DenseMap* &CacheP = NonLocalDeps[QueryInst]; - if (CacheP == 0) CacheP = new DenseMap(); + NonLocalDepInfo *&CacheP = NonLocalDeps[QueryInst]; + if (CacheP == 0) CacheP = new NonLocalDepInfo(); - DenseMap &Cache = *CacheP; + NonLocalDepInfo &Cache = *CacheP; /// DirtyBlocks - This is the set of blocks that need to be recomputed. In /// the cached case, this can happen due to instructions being deleted etc. In @@ -243,8 +243,8 @@ // determine what is dirty, seeding our initial DirtyBlocks worklist. // FIXME: In the "don't need to be updated" case, this is expensive, why not // have a per-"cache" flag saying it is undirty? - for (DenseMap::iterator I = Cache.begin(), - E = Cache.end(); I != E; ++I) + for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); + I != E; ++I) if (I->second.getInt() == Dirty) DirtyBlocks.push_back(I->first); @@ -303,8 +303,7 @@ // Copy the result into the output set. - for (DenseMap::iterator I = Cache.begin(), - E = Cache.end(); I != E; ++I) + for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E;++I) Result.push_back(std::make_pair(I->first, ConvToResult(I->second))); } @@ -316,9 +315,9 @@ // for any cached queries. NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); if (NLDI != NonLocalDeps.end()) { - DenseMap &BlockMap = *NLDI->second; - for (DenseMap::iterator DI = - BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) + NonLocalDepInfo &BlockMap = *NLDI->second; + for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); + DI != DE; ++DI) if (Instruction *Inst = DI->second.getPointer()) ReverseNonLocalDeps[Inst].erase(RemInst); delete &BlockMap; @@ -389,11 +388,11 @@ I != E; ++I) { assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); - DenseMap &INLD = *NonLocalDeps[*I]; + NonLocalDepInfo &INLD = *NonLocalDeps[*I]; assert(&INLD != 0 && "Reverse mapping out of date?"); - for (DenseMap::iterator - DI = INLD.begin(), DE = INLD.end(); DI != DE; ++DI) { + for (NonLocalDepInfo::iterator DI = INLD.begin(), DE = INLD.end(); + DI != DE; ++DI) { if (DI->second.getPointer() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. @@ -436,9 +435,9 @@ for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - DenseMap &INLD = *I->second; - for (DenseMap::iterator II = INLD.begin(), - EE = INLD.end(); II != EE; ++II) + NonLocalDepInfo &INLD = *I->second; + for (NonLocalDepInfo::iterator II = INLD.begin(), EE = INLD.end(); + II != EE; ++II) assert(II->second.getPointer() != D && "Inst occurs in data structures"); } From eli.friedman at gmail.com Sat Nov 29 20:42:05 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 02:42:05 -0000 Subject: [llvm-commits] [llvm] r60273 - /llvm/trunk/cmake/modules/AddLLVM.cmake Message-ID: <200811300242.mAU2g5Fj006480@zion.cs.uiuc.edu> Author: efriedma Date: Sat Nov 29 20:42:05 2008 New Revision: 60273 URL: http://llvm.org/viewvc/llvm-project?rev=60273&view=rev Log: Fix a link issue I ran into trying compiling LLVM on MinGW with CMake. Hopefully this doesn't break anyone else's build... it shouldn't unless the MinGW variable means something other than compiling with MinGW. Modified: llvm/trunk/cmake/modules/AddLLVM.cmake Modified: llvm/trunk/cmake/modules/AddLLVM.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/AddLLVM.cmake?rev=60273&r1=60272&r2=60273&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Sat Nov 29 20:42:05 2008 @@ -31,7 +31,7 @@ else( MSVC ) add_dependencies(${name} llvm-config.target) if( MINGW ) - target_link_libraries(${name} DbgHelp psapi) + target_link_libraries(${name} imagehlp psapi) elseif( CMAKE_HOST_UNIX ) target_link_libraries(${name} dl) endif( MINGW ) From sabre at nondot.org Sat Nov 29 20:52:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 02:52:27 -0000 Subject: [llvm-commits] [llvm] r60274 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811300252.mAU2qRtB006789@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 29 20:52:26 2008 New Revision: 60274 URL: http://llvm.org/viewvc/llvm-project?rev=60274&view=rev Log: Two changes: Make getDependency remove QueryInst for a dirty record's ReverseLocalDeps when we update it. This fixes a regression test failure from my last commit. Second, for each non-local cached information structure, keep a bit that indicates whether it is dirty or not. This saves us a scan over the whole thing in the common case when it isn't dirty. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60274&r1=60273&r2=60274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Nov 29 20:52:26 2008 @@ -129,11 +129,14 @@ typedef DenseMap NonLocalDepInfo; + /// PerInstNLInfo - This is the instruction we keep for each cached access + /// that we have for an instruction. The pointer is an owning pointer and + /// the bool indicates whether we have any dirty bits in the set. + typedef PointerIntPair PerInstNLInfo; // A map from instructions to their non-local dependencies. - typedef DenseMap NonLocalDepMapType; + typedef DenseMap NonLocalDepMapType; + NonLocalDepMapType NonLocalDeps; // A reverse mapping from dependencies to the dependees. This is @@ -158,7 +161,7 @@ LocalDeps.clear(); for (NonLocalDepMapType::iterator I = NonLocalDeps.begin(), E = NonLocalDeps.end(); I != E; ++I) - delete I->second; + delete I->second.getPointer(); NonLocalDeps.clear(); ReverseLocalDeps.clear(); ReverseNonLocalDeps.clear(); Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60274&r1=60273&r2=60274&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Nov 29 20:52:26 2008 @@ -199,8 +199,14 @@ // Otherwise, if we have a dirty entry, we know we can start the scan at that // instruction, which may save us some work. - if (Instruction *Inst = LocalCache.getPointer()) + if (Instruction *Inst = LocalCache.getPointer()) { ScanPos = Inst; + + SmallPtrSet &InstMap = ReverseLocalDeps[Inst]; + InstMap.erase(QueryInst); + if (InstMap.empty()) + ReverseLocalDeps.erase(Inst); + } // Do the scan. LocalCache = getDependencyFromInternal(QueryInst, ScanPos, @@ -227,10 +233,10 @@ MemDepResult> > &Result) { assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); - NonLocalDepInfo *&CacheP = NonLocalDeps[QueryInst]; - if (CacheP == 0) CacheP = new NonLocalDepInfo(); + PerInstNLInfo &CacheP = NonLocalDeps[QueryInst]; + if (CacheP.getPointer() == 0) CacheP.setPointer(new NonLocalDepInfo()); - NonLocalDepInfo &Cache = *CacheP; + NonLocalDepInfo &Cache = *CacheP.getPointer(); /// DirtyBlocks - This is the set of blocks that need to be recomputed. In /// the cached case, this can happen due to instructions being deleted etc. In @@ -240,13 +246,13 @@ if (!Cache.empty()) { // If we already have a partially computed set of results, scan them to - // determine what is dirty, seeding our initial DirtyBlocks worklist. - // FIXME: In the "don't need to be updated" case, this is expensive, why not - // have a per-"cache" flag saying it is undirty? - for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); + // determine what is dirty, seeding our initial DirtyBlocks worklist. The + // Int bit of CacheP tells us if we have anything dirty. + if (CacheP.getInt()) + for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E; ++I) - if (I->second.getInt() == Dirty) - DirtyBlocks.push_back(I->first); + if (I->second.getInt() == Dirty) + DirtyBlocks.push_back(I->first); NumCacheNonLocal++; @@ -315,7 +321,7 @@ // for any cached queries. NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); if (NLDI != NonLocalDeps.end()) { - NonLocalDepInfo &BlockMap = *NLDI->second; + NonLocalDepInfo &BlockMap = *NLDI->second.getPointer(); for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) if (Instruction *Inst = DI->second.getPointer()) @@ -388,11 +394,13 @@ I != E; ++I) { assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); - NonLocalDepInfo &INLD = *NonLocalDeps[*I]; - assert(&INLD != 0 && "Reverse mapping out of date?"); + PerInstNLInfo &INLD = NonLocalDeps[*I]; + assert(INLD.getPointer() != 0 && "Reverse mapping out of date?"); + // The information is now dirty! + INLD.setInt(true); - for (NonLocalDepInfo::iterator DI = INLD.begin(), DE = INLD.end(); - DI != DE; ++DI) { + for (NonLocalDepInfo::iterator DI = INLD.getPointer()->begin(), + DE = INLD.getPointer()->end(); DI != DE; ++DI) { if (DI->second.getPointer() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. @@ -435,9 +443,9 @@ for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - NonLocalDepInfo &INLD = *I->second; - for (NonLocalDepInfo::iterator II = INLD.begin(), EE = INLD.end(); - II != EE; ++II) + const PerInstNLInfo &INLD = I->second; + for (NonLocalDepInfo::iterator II = INLD.getPointer()->begin(), + EE = INLD.getPointer()->end(); II != EE; ++II) assert(II->second.getPointer() != D && "Inst occurs in data structures"); } From isanbard at gmail.com Sat Nov 29 21:42:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 03:42:13 -0000 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll Message-ID: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 21:42:12 2008 New Revision: 60275 URL: http://llvm.org/viewvc/llvm-project?rev=60275&view=rev Log: Instcombine was illegally transforming -X/C into X/-C when either X or C overflowed on negation. This commit checks to make sure that neithe C nor X overflows. This requires that the RHS of X (a subtract instruction) be a constant integer. Added: llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/apint-sub.ll llvm/trunk/test/Transforms/InstCombine/sub.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60275&r1=60274&r2=60275&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 29 21:42:12 2008 @@ -2956,9 +2956,26 @@ if (RHS->isAllOnesValue()) return BinaryOperator::CreateNeg(Op0); - // -X/C -> X/-C - if (Value *LHSNeg = dyn_castNegVal(Op0)) - return BinaryOperator::CreateSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); + ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); + + // -X/C -> X/-C, if and only if negation doesn't overflow. + if ((RHS->getSExtValue() < 0 && + RHS->getSExtValue() < RHSNeg->getSExtValue()) || + (RHS->getSExtValue() > 0 && + RHS->getSExtValue() > RHSNeg->getSExtValue())) { + if (Value *LHSNeg = dyn_castNegVal(Op0)) { + if (ConstantInt *CI = dyn_cast(LHSNeg)) { + ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); + + if ((CI->getSExtValue() < 0 && + CI->getSExtValue() < CINeg->getSExtValue()) || + (CI->getSExtValue() > 0 && + CI->getSExtValue() > CINeg->getSExtValue())) + return BinaryOperator::CreateSDiv(LHSNeg, + ConstantExpr::getNeg(RHS)); + } + } + } } // If the sign bits of both operands are zero (i.e. we can prove they are Modified: llvm/trunk/test/Transforms/InstCombine/apint-sub.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-sub.ll?rev=60275&r1=60274&r2=60275&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/apint-sub.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/apint-sub.ll Sat Nov 29 21:42:12 2008 @@ -3,7 +3,7 @@ ; ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \ -; RUN: grep -v {sub i19 %Cok, %Bok} | not grep sub +; RUN: grep -v {sub i19 %Cok, %Bok} | grep -v {sub i25 0, %Aok} | not grep sub ; END. define i23 @test1(i23 %A) { @@ -107,8 +107,10 @@ ret i51 %Y } -define i25 @test17(i25 %A) { - %B = sub i25 0, %A ; [#uses=1] +; Can't fold subtract here because negation it might oveflow. +; PR3142 +define i25 @test17(i25 %Aok) { + %B = sub i25 0, %Aok ; [#uses=1] %C = sdiv i25 %B, 1234 ; [#uses=1] ret i25 %C } Added: llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll?rev=60275&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Sat Nov 29 21:42:12 2008 @@ -0,0 +1,22 @@ +; RUN: llvm-as < %s | opt -instcombine -inline | llvm-dis | grep {715827882} | count 2 +; PR3142 + +define i32 @a(i32 %X) nounwind readnone { +entry: + %0 = sub i32 0, %X + %1 = sdiv i32 %0, -3 + ret i32 %1 +} + +define i32 @b(i32 %X) nounwind readnone { +entry: + %0 = call i32 @a(i32 -2147483648) + ret i32 %0 +} + +define i32 @c(i32 %X) nounwind readnone { +entry: + %0 = sub i32 0, -2147483648 + %1 = sdiv i32 %0, -3 + ret i32 %1 +} Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=60275&r1=60274&r2=60275&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sub.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sub.ll Sat Nov 29 21:42:12 2008 @@ -1,7 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. ; ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \ -; RUN: grep -v {sub i32 %Cok, %Bok} | not grep sub +; RUN: grep -v {sub i32 %Cok, %Bok} | grep -v {sub i32 0, %Aok} | not grep sub define i32 @test1(i32 %A) { %B = sub i32 %A, %A ; [#uses=1] @@ -104,8 +104,10 @@ ret i32 %Y } -define i32 @test17(i32 %A) { - %B = sub i32 0, %A ; [#uses=1] +; Can't fold subtract here because negation it might oveflow. +; PR3142 +define i32 @test17(i32 %Aok) { + %B = sub i32 0, %Aok ; [#uses=1] %C = sdiv i32 %B, 1234 ; [#uses=1] ret i32 %C } From isanbard at gmail.com Sat Nov 29 22:33:55 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 04:33:55 -0000 Subject: [llvm-commits] [llvm] r60276 - /llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Message-ID: <200811300433.mAU4XtXK010951@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 22:33:53 2008 New Revision: 60276 URL: http://llvm.org/viewvc/llvm-project?rev=60276&view=rev Log: Strengthen check for div inst-combining. Modified: llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Modified: llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll?rev=60276&r1=60275&r2=60276&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Sat Nov 29 22:33:53 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine -inline | llvm-dis | grep {715827882} | count 2 +; RUN: llvm-as < %s | opt -instcombine -inline | llvm-dis | not grep '-715827882' ; PR3142 define i32 @a(i32 %X) nounwind readnone { From eli.friedman at gmail.com Sat Nov 29 22:59:26 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 04:59:26 -0000 Subject: [llvm-commits] [llvm] r60277 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/CellSPU/icmp16.ll test/CodeGen/X86/2008-11-29-ULT-Sign.ll Message-ID: <200811300459.mAU4xQMW011741@zion.cs.uiuc.edu> Author: efriedma Date: Sat Nov 29 22:59:26 2008 New Revision: 60277 URL: http://llvm.org/viewvc/llvm-project?rev=60277&view=rev Log: APIntify a test which is potentially unsafe otherwise, and fix the nearby FIXME. I'm not sure what the right way to fix the Cell test was; if the approach I used isn't okay, please let me know. Added: llvm/trunk/test/CodeGen/X86/2008-11-29-ULT-Sign.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/test/CodeGen/CellSPU/icmp16.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=60277&r1=60276&r2=60277&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sat Nov 29 22:59:26 2008 @@ -1583,12 +1583,19 @@ // by changing cc. // SETUGT X, SINTMAX -> SETLT X, 0 - if (Cond == ISD::SETUGT && OperandBitSize != 1 && - C1 == (~0ULL >> (65-OperandBitSize))) + if (Cond == ISD::SETUGT && + C1 == APInt::getSignedMaxValue(OperandBitSize)) return DAG.getSetCC(VT, N0, DAG.getConstant(0, N1.getValueType()), ISD::SETLT); - // FIXME: Implement the rest of these. + // SETULT X, SINTMIN -> SETGT X, -1 + if (Cond == ISD::SETULT && + C1 == APInt::getSignedMinValue(OperandBitSize)) { + SDValue ConstMinusOne = + DAG.getConstant(APInt::getAllOnesValue(OperandBitSize), + N1.getValueType()); + return DAG.getSetCC(VT, N0, ConstMinusOne, ISD::SETGT); + } // Fold bit comparisons when we can. if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && Modified: llvm/trunk/test/CodeGen/CellSPU/icmp16.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/icmp16.ll?rev=60277&r1=60276&r2=60277&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/icmp16.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/icmp16.ll Sat Nov 29 22:59:26 2008 @@ -204,7 +204,7 @@ define i16 @icmp_ult_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind { entry: - %A = icmp ult i16 %arg1, 32768 + %A = icmp ult i16 %arg1, 32769 %B = select i1 %A, i16 %val1, i16 %val2 ret i16 %B } Added: llvm/trunk/test/CodeGen/X86/2008-11-29-ULT-Sign.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-ULT-Sign.ll?rev=60277&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-ULT-Sign.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-ULT-Sign.ll Sat Nov 29 22:59:26 2008 @@ -0,0 +1,22 @@ +; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | grep "jns" | count 1 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i32 @a(i32 %x) nounwind { +entry: + %cmp = icmp ult i32 %x, -2147483648 ; [#uses=1] + br i1 %cmp, label %if.end, label %if.then + +if.then: ; preds = %entry + %call = call i32 (...)* @b() ; [#uses=0] + br label %if.end + +if.end: ; preds = %if.then, %entry + br label %return + +return: ; preds = %if.end + ret i32 undef +} + +declare i32 @b(...) + From isanbard at gmail.com Sat Nov 29 23:01:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 05:01:05 -0000 Subject: [llvm-commits] [llvm] r60278 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200811300501.mAU515ST011805@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 23:01:05 2008 New Revision: 60278 URL: http://llvm.org/viewvc/llvm-project?rev=60278&view=rev Log: >From Hacker's Delight: "For signed integers, the determination of overflow of x*y is not so simple. If x and y have the same sign, then overflow occurs iff xy > 2**31 - 1. If they have opposite signs, then overflow occurs iff xy < -2**31." In this case, x == -1. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60278&r1=60277&r2=60278&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 29 23:01:05 2008 @@ -2957,20 +2957,22 @@ return BinaryOperator::CreateNeg(Op0); ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); + APInt RHSNegAPI(RHSNeg->getBitWidth(), RHSNeg->getSExtValue(), true); + + APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); + APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1), + true); // -X/C -> X/-C, if and only if negation doesn't overflow. - if ((RHS->getSExtValue() < 0 && - RHS->getSExtValue() < RHSNeg->getSExtValue()) || - (RHS->getSExtValue() > 0 && - RHS->getSExtValue() > RHSNeg->getSExtValue())) { + if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) || + (RHS->getSExtValue() > 0 && RHSNegAPI.sgt(TwoToExp * NegOne))) { if (Value *LHSNeg = dyn_castNegVal(Op0)) { if (ConstantInt *CI = dyn_cast(LHSNeg)) { ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); + APInt CINegAPI(CINeg->getBitWidth(), CINeg->getSExtValue(), true); - if ((CI->getSExtValue() < 0 && - CI->getSExtValue() < CINeg->getSExtValue()) || - (CI->getSExtValue() > 0 && - CI->getSExtValue() > CINeg->getSExtValue())) + if ((CI->getSExtValue() < 0 && CINegAPI.slt(TwoToExp - 1)) || + (CI->getSExtValue() > 0 && CINegAPI.sgt(TwoToExp * NegOne))) return BinaryOperator::CreateSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); } From isanbard at gmail.com Sat Nov 29 23:29:33 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 05:29:33 -0000 Subject: [llvm-commits] [llvm] r60279 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200811300529.mAU5TXDc012512@zion.cs.uiuc.edu> Author: void Date: Sat Nov 29 23:29:33 2008 New Revision: 60279 URL: http://llvm.org/viewvc/llvm-project?rev=60279&view=rev Log: Don't make TwoToExp signed by default. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60279&r1=60278&r2=60279&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 29 23:29:33 2008 @@ -2960,8 +2960,7 @@ APInt RHSNegAPI(RHSNeg->getBitWidth(), RHSNeg->getSExtValue(), true); APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); - APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1), - true); + APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1)); // -X/C -> X/-C, if and only if negation doesn't overflow. if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) || From eli.friedman at gmail.com Sun Nov 30 00:02:27 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 06:02:27 -0000 Subject: [llvm-commits] [llvm] r60283 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll test/CodeGen/X86/urem-i8-constant.ll Message-ID: <200811300602.mAU62Rnu013388@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 00:02:26 2008 New Revision: 60283 URL: http://llvm.org/viewvc/llvm-project?rev=60283&view=rev Log: Fix for PR2164: allow transforming arbitrary-width unsigned divides into multiplies. Some more cleverness would be nice, though. It would be nice if we could do this transformation on illegal types. Also, we would prefer a narrower constant when possible so that we can use a narrower multiply, which can be cheaper. Added: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/test/CodeGen/X86/urem-i8-constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=60283&r1=60282&r2=60283&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sun Nov 30 00:02:26 2008 @@ -2221,19 +2221,64 @@ return true; } -// Magic for divide replacement +struct mu { + APInt m; // magic number + bool a; // add indicator + uint32_t s; // shift amount +}; + +/// magicu - calculate the magic numbers required to codegen an integer udiv as +/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. +static mu magicu(const APInt& d) { + unsigned p; + APInt nc, delta, q1, r1, q2, r2; + struct mu magu; + magu.a = 0; // initialize "add" indicator + APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()); + APInt signedMin = APInt::getSignedMinValue(d.getBitWidth()); + APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth()); + + nc = allOnes - (-d).urem(d); + p = d.getBitWidth() - 1; // initialize p + q1 = signedMin.udiv(nc); // initialize q1 = 2p/nc + r1 = signedMin - q1*nc; // initialize r1 = rem(2p,nc) + q2 = signedMax.udiv(d); // initialize q2 = (2p-1)/d + r2 = signedMax - q2*d; // initialize r2 = rem((2p-1),d) + do { + p = p + 1; + if (r1.uge(nc - r1)) { + q1 = q1 + q1 + 1; // update q1 + r1 = r1 + r1 - nc; // update r1 + } + else { + q1 = q1+q1; // update q1 + r1 = r1+r1; // update r1 + } + if ((r2 + 1).uge(d - r2)) { + if (q2.uge(signedMax)) magu.a = 1; + q2 = q2+q2 + 1; // update q2 + r2 = r2+r2 + 1 - d; // update r2 + } + else { + if (q2.uge(signedMin)) magu.a = 1; + q2 = q2+q2; // update q2 + r2 = r2+r2 + 1; // update r2 + } + delta = d - 1 - r2; + } while (p < d.getBitWidth()*2 && + (q1.ult(delta) || (q1 == delta && r1 == 0))); + magu.m = q2 + 1; // resulting magic number + magu.s = p - d.getBitWidth(); // resulting shift + return magu; +} +// Magic for divide replacement +// FIXME: This should be APInt'ified struct ms { int64_t m; // magic number int64_t s; // shift amount }; -struct mu { - uint64_t m; // magic number - int64_t a; // add indicator - int64_t s; // shift amount -}; - /// magic - calculate the magic numbers required to codegen an integer sdiv as /// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, /// or -1. @@ -2274,46 +2319,6 @@ return mag; } -/// magicu - calculate the magic numbers required to codegen an integer udiv as -/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. -static mu magicu32(uint32_t d) { - int32_t p; - uint32_t nc, delta, q1, r1, q2, r2; - struct mu magu; - magu.a = 0; // initialize "add" indicator - nc = - 1 - (-d)%d; - p = 31; // initialize p - q1 = 0x80000000/nc; // initialize q1 = 2p/nc - r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) - do { - p = p + 1; - if (r1 >= nc - r1 ) { - q1 = 2*q1 + 1; // update q1 - r1 = 2*r1 - nc; // update r1 - } - else { - q1 = 2*q1; // update q1 - r1 = 2*r1; // update r1 - } - if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFF) magu.a = 1; - q2 = 2*q2 + 1; // update q2 - r2 = 2*r2 + 1 - d; // update r2 - } - else { - if (q2 >= 0x80000000) magu.a = 1; - q2 = 2*q2; // update q2 - r2 = 2*r2 + 1; // update r2 - } - delta = d - 1 - r2; - } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); - magu.m = q2 + 1; // resulting magic number - magu.s = p - 32; // resulting shift - return magu; -} - /// magic - calculate the magic numbers required to codegen an integer sdiv as /// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, /// or -1. @@ -2354,47 +2359,6 @@ return mag; } -/// magicu - calculate the magic numbers required to codegen an integer udiv as -/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. -static mu magicu64(uint64_t d) -{ - int64_t p; - uint64_t nc, delta, q1, r1, q2, r2; - struct mu magu; - magu.a = 0; // initialize "add" indicator - nc = - 1 - (-d)%d; - p = 63; // initialize p - q1 = 0x8000000000000000ull/nc; // initialize q1 = 2p/nc - r1 = 0x8000000000000000ull - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFFFFFFFFFFull/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFFFFFFFFFFull - q2*d; // initialize r2 = rem((2p-1),d) - do { - p = p + 1; - if (r1 >= nc - r1 ) { - q1 = 2*q1 + 1; // update q1 - r1 = 2*r1 - nc; // update r1 - } - else { - q1 = 2*q1; // update q1 - r1 = 2*r1; // update r1 - } - if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1; - q2 = 2*q2 + 1; // update q2 - r2 = 2*r2 + 1 - d; // update r2 - } - else { - if (q2 >= 0x8000000000000000ull) magu.a = 1; - q2 = 2*q2; // update q2 - r2 = 2*r2 + 1; // update r2 - } - delta = d - 1 - r2; - } while (p < 128 && (q1 < delta || (q1 == delta && r1 == 0))); - magu.m = q2 + 1; // resulting magic number - magu.s = p - 64; // resulting shift - return magu; -} - /// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, /// return a DAG expression to select that will generate the same value by /// multiplying by a magic number. See: @@ -2456,15 +2420,19 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, std::vector* Created) const { MVT VT = N->getValueType(0); - + // Check to see if we can do this. - if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) - return SDValue(); // BuildUDIV only operates on i32 or i64 - - uint64_t d = cast(N->getOperand(1))->getZExtValue(); - mu magics = (VT == MVT::i32) ? magicu32(d) : magicu64(d); - + // FIXME: We should be more aggressive here. + if (!isTypeLegal(VT)) + return SDValue(); + + // FIXME: We should use a narrower constant when the upper + // bits are known to be zero. + ConstantSDNode *N1C = cast(N->getOperand(1)); + mu magics = magicu(N1C->getAPIntValue()); + // Multiply the numerator (operand 0) by the magic value + // FIXME: We should support doing a MUL in a wider type SDValue Q; if (isOperationLegal(ISD::MULHU, VT)) Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), @@ -2479,6 +2447,8 @@ Created->push_back(Q.getNode()); if (magics.a == 0) { + assert(magics.s < N1C->getAPIntValue().getBitWidth() && + "We shouldn't generate an undefined shift!"); return DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(magics.s, getShiftAmountTy())); } else { Added: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll?rev=60283&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Sun Nov 30 00:02:26 2008 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | grep 63551 | count 1 +; ModuleID = '' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define zeroext i16 @a(i16 zeroext %x) nounwind { +entry: + %div = udiv i16 %x, 33 ; [#uses=1] + ret i16 %div +} Modified: llvm/trunk/test/CodeGen/X86/urem-i8-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/urem-i8-constant.ll?rev=60283&r1=60282&r2=60283&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/urem-i8-constant.ll (original) +++ llvm/trunk/test/CodeGen/X86/urem-i8-constant.ll Sun Nov 30 00:02:26 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | not grep mul +; RUN: llvm-as < %s | llc -march=x86 | grep 111 define i8 @foo(i8 %tmp325) { %t546 = urem i8 %tmp325, 37 From eli.friedman at gmail.com Sun Nov 30 00:35:39 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 06:35:39 -0000 Subject: [llvm-commits] [llvm] r60284 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll Message-ID: <200811300635.mAU6ZdBv014261@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 00:35:39 2008 New Revision: 60284 URL: http://llvm.org/viewvc/llvm-project?rev=60284&view=rev Log: Followup to r60283: optimize arbitrary width signed divisions as well as unsigned divisions. Same caveats as before. Added: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=60284&r1=60283&r2=60284&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sun Nov 30 00:35:39 2008 @@ -2224,7 +2224,7 @@ struct mu { APInt m; // magic number bool a; // add indicator - uint32_t s; // shift amount + unsigned s; // shift amount }; /// magicu - calculate the magic numbers required to codegen an integer udiv as @@ -2273,89 +2273,50 @@ } // Magic for divide replacement -// FIXME: This should be APInt'ified struct ms { - int64_t m; // magic number - int64_t s; // shift amount + APInt m; // magic number + unsigned s; // shift amount }; /// magic - calculate the magic numbers required to codegen an integer sdiv as /// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, /// or -1. -static ms magic32(int32_t d) { - int32_t p; - uint32_t ad, anc, delta, q1, r1, q2, r2, t; - const uint32_t two31 = 0x80000000U; - struct ms mag; - - ad = abs(d); - t = two31 + ((uint32_t)d >> 31); - anc = t - 1 - t%ad; // absolute value of nc - p = 31; // initialize p - q1 = two31/anc; // initialize q1 = 2p/abs(nc) - r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) - q2 = two31/ad; // initialize q2 = 2p/abs(d) - r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) - do { - p = p + 1; - q1 = 2*q1; // update q1 = 2p/abs(nc) - r1 = 2*r1; // update r1 = rem(2p/abs(nc)) - if (r1 >= anc) { // must be unsigned comparison - q1 = q1 + 1; - r1 = r1 - anc; - } - q2 = 2*q2; // update q2 = 2p/abs(d) - r2 = 2*r2; // update r2 = rem(2p/abs(d)) - if (r2 >= ad) { // must be unsigned comparison - q2 = q2 + 1; - r2 = r2 - ad; - } - delta = ad - r2; - } while (q1 < delta || (q1 == delta && r1 == 0)); - - mag.m = (int32_t)(q2 + 1); // make sure to sign extend - if (d < 0) mag.m = -mag.m; // resulting magic number - mag.s = p - 32; // resulting shift - return mag; -} - -/// magic - calculate the magic numbers required to codegen an integer sdiv as -/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, -/// or -1. -static ms magic64(int64_t d) { - int64_t p; - uint64_t ad, anc, delta, q1, r1, q2, r2, t; - const uint64_t two63 = 9223372036854775808ULL; // 2^63 +static ms magic(const APInt& d) { + unsigned p; + APInt ad, anc, delta, q1, r1, q2, r2, t; + APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()); + APInt signedMin = APInt::getSignedMinValue(d.getBitWidth()); + APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth()); struct ms mag; - ad = d >= 0 ? d : -d; - t = two63 + ((uint64_t)d >> 63); - anc = t - 1 - t%ad; // absolute value of nc - p = 63; // initialize p - q1 = two63/anc; // initialize q1 = 2p/abs(nc) - r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) - q2 = two63/ad; // initialize q2 = 2p/abs(d) - r2 = two63 - q2*ad; // initialize r2 = rem(2p,abs(d)) + ad = d.abs(); + t = signedMin + (d.lshr(d.getBitWidth() - 1)); + anc = t - 1 - t.urem(ad); // absolute value of nc + p = d.getBitWidth() - 1; // initialize p + q1 = signedMin.udiv(anc); // initialize q1 = 2p/abs(nc) + r1 = signedMin - q1*anc; // initialize r1 = rem(2p,abs(nc)) + q2 = signedMin.udiv(ad); // initialize q2 = 2p/abs(d) + r2 = signedMin - q2*ad; // initialize r2 = rem(2p,abs(d)) do { p = p + 1; - q1 = 2*q1; // update q1 = 2p/abs(nc) - r1 = 2*r1; // update r1 = rem(2p/abs(nc)) - if (r1 >= anc) { // must be unsigned comparison + q1 = q1<<1; // update q1 = 2p/abs(nc) + r1 = r1<<1; // update r1 = rem(2p/abs(nc)) + if (r1.uge(anc)) { // must be unsigned comparison q1 = q1 + 1; r1 = r1 - anc; } - q2 = 2*q2; // update q2 = 2p/abs(d) - r2 = 2*r2; // update r2 = rem(2p/abs(d)) - if (r2 >= ad) { // must be unsigned comparison + q2 = q2<<1; // update q2 = 2p/abs(d) + r2 = r2<<1; // update r2 = rem(2p/abs(d)) + if (r2.uge(ad)) { // must be unsigned comparison q2 = q2 + 1; r2 = r2 - ad; } delta = ad - r2; - } while (q1 < delta || (q1 == delta && r1 == 0)); + } while (q1.ule(delta) || (q1 == delta && r1 == 0)); mag.m = q2 + 1; - if (d < 0) mag.m = -mag.m; // resulting magic number - mag.s = p - 64; // resulting shift + if (d.isNegative()) mag.m = -mag.m; // resulting magic number + mag.s = p - d.getBitWidth(); // resulting shift return mag; } @@ -2368,13 +2329,15 @@ MVT VT = N->getValueType(0); // Check to see if we can do this. - if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) - return SDValue(); // BuildSDIV only operates on i32 or i64 + // FIXME: We should be more aggressive here. + if (!isTypeLegal(VT)) + return SDValue(); - int64_t d = cast(N->getOperand(1))->getSExtValue(); - ms magics = (VT == MVT::i32) ? magic32(d) : magic64(d); + APInt d = cast(N->getOperand(1))->getAPIntValue(); + ms magics = magic(d); // Multiply the numerator (operand 0) by the magic value + // FIXME: We should support doing a MUL in a wider type SDValue Q; if (isOperationLegal(ISD::MULHS, VT)) Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), @@ -2386,13 +2349,13 @@ else return SDValue(); // No mulhs or equvialent // If d > 0 and m < 0, add the numerator - if (d > 0 && magics.m < 0) { + if (d.isStrictlyPositive() && magics.m.isNegative()) { Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0)); if (Created) Created->push_back(Q.getNode()); } // If d < 0 and m > 0, subtract the numerator. - if (d < 0 && magics.m > 0) { + if (d.isNegative() && magics.m.isStrictlyPositive()) { Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0)); if (Created) Created->push_back(Q.getNode()); Added: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll?rev=60284&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll Sun Nov 30 00:35:39 2008 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | grep 63551 +; ModuleID = '' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define signext i16 @a(i16 signext %x) nounwind { +entry: + %div = sdiv i16 %x, 33 ; [#uses=1] + ret i16 %div +} From eli.friedman at gmail.com Sun Nov 30 01:36:04 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 07:36:04 -0000 Subject: [llvm-commits] [llvm] r60285 - /llvm/trunk/lib/Target/README.txt Message-ID: <200811300736.mAU7a4xv015840@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 01:36:04 2008 New Revision: 60285 URL: http://llvm.org/viewvc/llvm-project?rev=60285&view=rev Log: Moving potential optimizations out of PR2330 into lib/Target/README.txt. Hopefully this isn't too much stuff to dump into this file. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60285&r1=60284&r2=60285&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Nov 30 01:36:04 2008 @@ -1002,3 +1002,265 @@ } //===---------------------------------------------------------------------===// + +From gcc bug 24696: +int +f (unsigned long a, unsigned long b, unsigned long c) +{ + return ((a & (c - 1)) != 0) || ((b & (c - 1)) != 0); +} +int +f (unsigned long a, unsigned long b, unsigned long c) +{ + return ((a & (c - 1)) != 0) | ((b & (c - 1)) != 0); +} +Both should combine to ((a|b) & (c-1)) != 0. Currently not optimized with +"clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 20192: +#define PMD_MASK (~((1UL << 23) - 1)) +void clear_pmd_range(unsigned long start, unsigned long end) +{ + if (!(start & ~PMD_MASK) && !(end & ~PMD_MASK)) + f(); +} +The expression should optimize to something like +"!((start|end)&~PMD_MASK). Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 15241: +unsigned int +foo (unsigned int a, unsigned int b) +{ + if (a <= 7 && b <= 7) + baz (); +} +Should combine to "(a|b) <= 7". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 3756: +int +pn (int n) +{ + return (n >= 0 ? 1 : -1); +} +Should combine to (n >> 31) | 1. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts | llc". + +//===---------------------------------------------------------------------===// + +From GCC Bug 28685: +int test(int a, int b) +{ + int lt = a < b; + int eq = a == b; + + return (lt || eq); +} +Should combine to "a <= b". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts | llc". + +//===---------------------------------------------------------------------===// + +void a(int variable) +{ + if (variable == 4 || variable == 6) + bar(); +} +This should optimize to "if ((variable | 2) == 6)". Currently not +optimized with "clang -emit-llvm-bc | opt -std-compile-opts | llc". + +//===---------------------------------------------------------------------===// + +unsigned int f(unsigned int i, unsigned int n) {++i; if (i == n) ++i; return +i;} +unsigned int f2(unsigned int i, unsigned int n) {++i; i += i == n; return i;} +These should combine to the same thing. Currently, the first function +produces better code on X86. + +//===---------------------------------------------------------------------===// + +From GCC Bug 33512: +int f(int y, int x) +{ + return x & ((~x) | y); +} +Should combine to x & y. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 15784: +#define abs(x) x>0?x:-x +int f(int x, int y) +{ + return (abs(x)) >= 0; +} +This should optimize to x == INT_MIN. (With -fwrapv.) Currently not +optimized with "clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 14753: +void +rotate_cst (unsigned int a) +{ + a = (a << 10) | (a >> 22); + if (a == 123) + bar (); +} +void +minus_cst (unsigned int a) +{ + unsigned int tem; + + tem = 20 - a; + if (tem == 5) + bar (); +} +void +mask_gt (unsigned int a) +{ + /* This is equivalent to a > 15. */ + if ((a & ~7) > 8) + bar (); +} +void +rshift_gt (unsigned int a) +{ + /* This is equivalent to a > 23. */ + if ((a >> 2) > 5) + bar (); +} +All should simplify to a single comparison. All of these are +currently not optimized with "clang -emit-llvm-bc | opt +-std-compile-opts". + +//===---------------------------------------------------------------------===// + +From GCC Bug 32605: +int c(int* x) {return (char*)x+2 == (char*)x;} +Should combine to 0. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts" (although llc can optimize it). + +//===---------------------------------------------------------------------===// + +int a(unsigned char* b) {return *b > 99;} +There's an unnecessary zext in the generated code with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b) {return ((a|b)&1) | (b&-2);} +Should be combined to "(a&1)|b". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(unsigned b) {return ((b << 31) | (b << 30)) >> 31;} +Should be combined to "((b >> 1) | b) & 1". Currently not optimized +with "clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +unsigned a(unsigned x, unsigned y) { return x | (y & 1) | (y & 2);} +Should combine to "x | (y & 3)". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +unsigned a(unsigned a) {return ((a | 1) & 3) | (a & -4);} +Should combine to "a | 1". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b, int c) {return ((a&~b) | (~a&b));} +Should fold to xor. Currently not optimized with "clang -emit-llvm-bc +| opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b, int c) {return (~a & c) | ((c|a) & b);} +Should fold to "(~a & c) | (a & b)". Currently not optimized with +"clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a,int b) {return (~(a|b))|a;} +Should fold to "a|~b". Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b) {return (a&&b) || (a&&!b);} +Should fold to "a". Currently not optimized with "clang -emit-llvm-bc +| opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b, int c) {return (a&&b) || (!a&&c);} +Should fold to "a ? b : c", or at least something sane. Currently not +optimized with "clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int a, int b, int c) {return (a&&b) || (a&&c) || (a&&b&&c);} +Should fold to a && (b || c). Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int x) {return x | ((x & 8) ^ 8);} +Should combine to x | 8. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int x) {return x ^ ((x & 8) ^ 8);} +Should also combine to x | 8. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int x) {return (x & 8) == 0 ? -1 : -9;} +Should combine to (x | -9) ^ 8. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int x) {return (x & 8) == 0 ? -9 : -1;} +Should combine to x | -9. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +int a(int x) {return ((x | -9) ^ 8) & x;} +Should combine to x & -9. Currently not optimized with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +unsigned a(unsigned a) {return a * 0x11111111 >> 28 & 1;} +Should combine to "a * 0x88888888 >> 31". Currently not optimized +with "clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +unsigned a(char* x) {if ((*x & 32) == 0) return b();} +There's an unnecessary zext in the generated code with "clang +-emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// + +unsigned a(unsigned long long x) {return 40 * (x >> 1);} +Should combine to "20 * (((unsigned)x) & -2)". Currently not +optimized with "clang -emit-llvm-bc | opt -std-compile-opts". + +//===---------------------------------------------------------------------===// From eli.friedman at gmail.com Sun Nov 30 01:52:27 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 07:52:27 -0000 Subject: [llvm-commits] [llvm] r60286 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200811300752.mAU7qSoL016414@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 01:52:27 2008 New Revision: 60286 URL: http://llvm.org/viewvc/llvm-project?rev=60286&view=rev Log: A couple small cleanups, plus a new potential optimization. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=60286&r1=60285&r2=60286&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sun Nov 30 01:52:27 2008 @@ -394,6 +394,10 @@ However, if we care more about code size, then imull is better. It's two bytes shorter than movl + leal. +On a Pentium M, both variants have the same characteristics with regard +to throughput; however, the multiplication has a latency of four cycles, as +opposed to two cycles for the movl+lea variant. + //===---------------------------------------------------------------------===// __builtin_ffs codegen is messy. @@ -628,9 +632,9 @@ to grab the bytes from the next cacheline. 532 532 0x3cfc movb (1809(%esp, %esi), %bl <<<--- spans 2 64 byte lines -942 942 0x3d03 movl %dh, (1809(%esp, %esi) -937 937 0x3d0a incl %esi -3 3 0x3d0b cmpb %bl, %dl +942 942 0x3d03 movl %dh, (1809(%esp, %esi) +937 937 0x3d0a incl %esi +3 3 0x3d0b cmpb %bl, %dl 27 27 0x3d0d jnz 0x000062db //===---------------------------------------------------------------------===// @@ -1790,3 +1794,25 @@ (v8i8 (MMX_MOVDQ2Qrr VR128:$src))>; There are other cases in various td files. + +//===---------------------------------------------------------------------===// + +Take something like the following on x86-32: +unsigned a(unsigned long long x, unsigned y) {return x % y;} + +We currently generate a libcall, but we really shouldn't: the expansion is +shorter and likely faster than the libcall. The expected code is something +like the following: + + movl 12(%ebp), %eax + movl 16(%ebp), %ecx + xorl %edx, %edx + divl %ecx + movl 8(%ebp), %eax + divl %ecx + movl %edx, %eax + ret + +A similar code sequence works for division. + +//===---------------------------------------------------------------------===// From eli.friedman at gmail.com Sun Nov 30 02:32:19 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 08:32:19 -0000 Subject: [llvm-commits] [llvm] r60287 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/SimplifyLibCalls/memmove.ll test/Transforms/SimplifyLibCalls/memset.ll Message-ID: <200811300832.mAU8WKFl017591@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 02:32:11 2008 New Revision: 60287 URL: http://llvm.org/viewvc/llvm-project?rev=60287&view=rev Log: Optimize memmove and memset into the LLVM builtins. Note that these only show up in code from front-ends besides llvm-gcc, like clang. Added: llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=60287&r1=60286&r2=60287&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sun Nov 30 02:32:11 2008 @@ -707,6 +707,60 @@ } }; +//===---------------------------------------===// +// 'memmove' Optimizations + +struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || + !isa(FT->getParamType(0)) || + !isa(FT->getParamType(1)) || + FT->getParamType(2) != TD->getIntPtrType()) + return 0; + + // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) + Module *M = Caller->getParent(); + Intrinsic::ID IID = Intrinsic::memmove; + const Type *Tys[1]; + Tys[0] = TD->getIntPtrType(); + Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1); + Value *Dst = CastToCStr(CI->getOperand(1), B); + Value *Src = CastToCStr(CI->getOperand(2), B); + Value *Size = CI->getOperand(3); + Value *Align = ConstantInt::get(Type::Int32Ty, 1); + B.CreateCall4(MemMove, Dst, Src, Size, Align); + return CI->getOperand(1); + } +}; + +//===---------------------------------------===// +// 'memset' Optimizations + +struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || + !isa(FT->getParamType(0)) || + FT->getParamType(1) != TD->getIntPtrType() || + FT->getParamType(2) != TD->getIntPtrType()) + return 0; + + // memset(p, v, n) -> llvm.memset(p, v, n, 1) + Module *M = Caller->getParent(); + Intrinsic::ID IID = Intrinsic::memset; + const Type *Tys[1]; + Tys[0] = TD->getIntPtrType(); + Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1); + Value *Dst = CastToCStr(CI->getOperand(1), B); + Value *Val = B.CreateTrunc(CI->getOperand(2), Type::Int8Ty); + Value *Size = CI->getOperand(3); + Value *Align = ConstantInt::get(Type::Int32Ty, 1); + B.CreateCall4(MemSet, Dst, Val, Size, Align); + return CI->getOperand(1); + } +}; + //===----------------------------------------------------------------------===// // Math Library Optimizations //===----------------------------------------------------------------------===// @@ -1197,6 +1251,7 @@ // String and Memory LibCall Optimizations StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt MemCpy; + MemMoveOpt MemMove; MemSetOpt MemSet; // Math Library Optimizations PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP; // Integer Optimizations @@ -1242,6 +1297,8 @@ Optimizations["strlen"] = &StrLen; Optimizations["memcmp"] = &MemCmp; Optimizations["memcpy"] = &MemCpy; + Optimizations["memmove"] = &MemMove; + Optimizations["memset"] = &MemSet; // Math Library Optimizations Optimizations["powf"] = &Pow; @@ -1386,10 +1443,6 @@ // * memcmp(x,y,l) -> cnst // (if all arguments are constant and strlen(x) <= l and strlen(y) <= l) // -// memmove: -// * memmove(d,s,l,a) -> memcpy(d,s,l,a) -// (if s is a global constant array) -// // pow, powf, powl: // * pow(exp(x),y) -> exp(x*y) // * pow(sqrt(x),y) -> pow(x,y*0.5) Added: llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll?rev=60287&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll (added) +++ llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll Sun Nov 30 02:32:11 2008 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep {llvm.memmove} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i8* @test(i8* %a, i8* %b, i32 %x) { +entry: + %call = call i8* @memmove(i8* %a, i8* %b, i32 %x ) + ret i8* %call +} + +declare i8* @memmove(i8*,i8*,i32) + Added: llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll?rev=60287&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll (added) +++ llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll Sun Nov 30 02:32:11 2008 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep {llvm.memset} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i8* @test(i8* %a, i32 %b, i32 %x) { +entry: + %call = call i8* @memset(i8* %a, i32 %b, i32 %x ) + ret i8* %call +} + +declare i8* @memset(i8*,i32,i32) + From isanbard at gmail.com Sun Nov 30 06:38:25 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 12:38:25 -0000 Subject: [llvm-commits] [llvm] r60288 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sdiv-2.ll Message-ID: <200811301238.mAUCcQvT026737@zion.cs.uiuc.edu> Author: void Date: Sun Nov 30 06:38:24 2008 New Revision: 60288 URL: http://llvm.org/viewvc/llvm-project?rev=60288&view=rev Log: getSExtValue() doesn't work for ConstantInts with bitwidth > 64 bits. Use all APInt calls instead. This fixes PR3144. Added: llvm/trunk/test/Transforms/InstCombine/sdiv-2.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60288&r1=60287&r2=60288&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 06:38:24 2008 @@ -2957,21 +2957,21 @@ return BinaryOperator::CreateNeg(Op0); ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); - APInt RHSNegAPI(RHSNeg->getBitWidth(), RHSNeg->getSExtValue(), true); + APInt RHSNegAPI(RHSNeg->getValue()); APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1)); // -X/C -> X/-C, if and only if negation doesn't overflow. - if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) || - (RHS->getSExtValue() > 0 && RHSNegAPI.sgt(TwoToExp * NegOne))) { + if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - 1)) || + (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp * NegOne))) { if (Value *LHSNeg = dyn_castNegVal(Op0)) { if (ConstantInt *CI = dyn_cast(LHSNeg)) { ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); APInt CINegAPI(CINeg->getBitWidth(), CINeg->getSExtValue(), true); - if ((CI->getSExtValue() < 0 && CINegAPI.slt(TwoToExp - 1)) || - (CI->getSExtValue() > 0 && CINegAPI.sgt(TwoToExp * NegOne))) + if ((CI->getValue().isNegative() && CINegAPI.slt(TwoToExp - 1)) || + (CI->getValue().isNonNegative() && CINegAPI.sgt(TwoToExp*NegOne))) return BinaryOperator::CreateSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); } Added: llvm/trunk/test/Transforms/InstCombine/sdiv-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sdiv-2.ll?rev=60288&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/sdiv-2.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/sdiv-2.ll Sun Nov 30 06:38:24 2008 @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output +; PR3144 + +define fastcc i32 @func(i32 %length) nounwind { +entry: + %0 = icmp ne i32 %length, -1 ; [#uses=1] + %iftmp.13.0 = select i1 %0, i128 0, i128 200000000 ; [#uses=2] + %1 = sdiv i128 %iftmp.13.0, 10 ; [#uses=1] + br label %bb5 + +bb5: ; preds = %bb8, %entry + %v.0 = phi i128 [ 0, %entry ], [ %6, %bb8 ] ; [#uses=2] + %2 = icmp sgt i128 %v.0, %1 ; [#uses=1] + br i1 %2, label %overflow, label %bb7 + +bb7: ; preds = %bb5 + %3 = mul i128 %v.0, 10 ; [#uses=2] + %4 = sub i128 %iftmp.13.0, 0 ; [#uses=1] + %5 = icmp slt i128 %4, %3 ; [#uses=1] + br i1 %5, label %overflow, label %bb8 + +bb8: ; preds = %bb7 + %6 = add i128 0, %3 ; [#uses=1] + br label %bb5 + +overflow: ; preds = %bb7, %bb5 + ret i32 1 +} From isanbard at gmail.com Sun Nov 30 06:41:09 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 12:41:09 -0000 Subject: [llvm-commits] [llvm] r60289 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200811301241.mAUCfAJ6026912@zion.cs.uiuc.edu> Author: void Date: Sun Nov 30 06:41:09 2008 New Revision: 60289 URL: http://llvm.org/viewvc/llvm-project?rev=60289&view=rev Log: Forgot one remaining call to getSExtValue(). Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60289&r1=60288&r2=60289&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 06:41:09 2008 @@ -2968,7 +2968,7 @@ if (Value *LHSNeg = dyn_castNegVal(Op0)) { if (ConstantInt *CI = dyn_cast(LHSNeg)) { ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); - APInt CINegAPI(CINeg->getBitWidth(), CINeg->getSExtValue(), true); + APInt CINegAPI(CINeg->getValue()); if ((CI->getValue().isNegative() && CINegAPI.slt(TwoToExp - 1)) || (CI->getValue().isNonNegative() && CINegAPI.sgt(TwoToExp*NegOne))) From isanbard at gmail.com Sun Nov 30 07:08:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 13:08:13 -0000 Subject: [llvm-commits] [llvm] r60290 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and-not-or.ll Message-ID: <200811301308.mAUD8Dtd027657@zion.cs.uiuc.edu> Author: void Date: Sun Nov 30 07:08:13 2008 New Revision: 60290 URL: http://llvm.org/viewvc/llvm-project?rev=60290&view=rev Log: Implement (A&((~A)|B)) -> A&B transformation in the instruction combiner. This takes care of all permutations of this pattern. Added: llvm/trunk/test/Transforms/InstCombine/and-not-or.ll Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60290&r1=60289&r2=60290&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Nov 30 07:08:13 2008 @@ -1086,16 +1086,6 @@ //===---------------------------------------------------------------------===// -From GCC Bug 33512: -int f(int y, int x) -{ - return x & ((~x) | y); -} -Should combine to x & y. Currently not optimized with "clang --emit-llvm-bc | opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - From GCC Bug 15784: #define abs(x) x>0?x:-x int f(int x, int y) Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60290&r1=60289&r2=60290&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 07:08:13 2008 @@ -3993,6 +3993,7 @@ std::swap(Op0, Op1); } } + if (Op1->hasOneUse() && match(Op1, m_Xor(m_Value(A), m_Value(B)))) { if (B == Op0) { // B&(A^B) -> B&(B^A) @@ -4005,6 +4006,24 @@ return BinaryOperator::CreateAnd(A, NotB); } } + + // (A&((~A)|B)) -> A&B + if (match(Op0, m_Or(m_Not(m_Value(A)), m_Value(B)))) { + if (A == Op1) + return BinaryOperator::CreateAnd(A, B); + } + if (match(Op0, m_Or(m_Value(A), m_Not(m_Value(B))))) { + if (B == Op1) + return BinaryOperator::CreateAnd(A, B); + } + if (match(Op1, m_Or(m_Not(m_Value(A)), m_Value(B)))) { + if (A == Op0) + return BinaryOperator::CreateAnd(A, B); + } + if (match(Op1, m_Or(m_Value(A), m_Not(m_Value(B))))) { + if (B == Op0) + return BinaryOperator::CreateAnd(A, B); + } } if (ICmpInst *RHS = dyn_cast(Op1)) { Added: llvm/trunk/test/Transforms/InstCombine/and-not-or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and-not-or.ll?rev=60290&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/and-not-or.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/and-not-or.ll Sun Nov 30 07:08:13 2008 @@ -0,0 +1,36 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %y, %x} | count 2 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %x, %y} | count 2 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {xor} +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {or} + +define i32 @func1(i32 %x, i32 %y) nounwind { +entry: + %n = xor i32 %y, -1 + %o = or i32 %n, %x + %a = and i32 %o, %y + ret i32 %a +} + +define i32 @func2(i32 %x, i32 %y) nounwind { +entry: + %n = xor i32 %y, -1 + %o = or i32 %x, %n + %a = and i32 %o, %y + ret i32 %a +} + +define i32 @func3(i32 %x, i32 %y) nounwind { +entry: + %n = xor i32 %y, -1 + %o = or i32 %n, %x + %a = and i32 %y, %o + ret i32 %a +} + +define i32 @func4(i32 %x, i32 %y) nounwind { +entry: + %n = xor i32 %y, -1 + %o = or i32 %x, %n + %a = and i32 %y, %o + ret i32 %a +} From isanbard at gmail.com Sun Nov 30 07:52:49 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 13:52:49 -0000 Subject: [llvm-commits] [llvm] r60291 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or-to-xor.ll Message-ID: <200811301352.mAUDqoDt029527@zion.cs.uiuc.edu> Author: void Date: Sun Nov 30 07:52:49 2008 New Revision: 60291 URL: http://llvm.org/viewvc/llvm-project?rev=60291&view=rev Log: Add instruction combining for ((A&~B)|(~A&B)) -> A^B and all permutations. Added: llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60291&r1=60290&r2=60291&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Nov 30 07:52:49 2008 @@ -1171,12 +1171,6 @@ //===---------------------------------------------------------------------===// -int a(int a, int b, int c) {return ((a&~b) | (~a&b));} -Should fold to xor. Currently not optimized with "clang -emit-llvm-bc -| opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - int a(int a, int b, int c) {return (~a & c) | ((c|a) & b);} Should fold to "(~a & c) | (a & b)". Currently not optimized with "clang -emit-llvm-bc | opt -std-compile-opts". Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60291&r1=60290&r2=60291&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 07:52:49 2008 @@ -4638,6 +4638,29 @@ return Match; if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C)) return Match; + + V1 = V2 = 0; + + // ((A&~B)|(~A&B)) -> A^B + if ((match(C, m_Not(m_Value(V1))) && + match(B, m_Not(m_Value(V2))))) + if (V1 == D && V2 == A) + return BinaryOperator::CreateXor(V1, V2); + // ((~B&A)|(~A&B)) -> A^B + if ((match(A, m_Not(m_Value(V1))) && + match(B, m_Not(m_Value(V2))))) + if (V1 == D && V2 == C) + return BinaryOperator::CreateXor(V1, V2); + // ((A&~B)|(B&~A)) -> A^B + if ((match(C, m_Not(m_Value(V1))) && + match(D, m_Not(m_Value(V2))))) + if (V1 == B && V2 == A) + return BinaryOperator::CreateXor(V1, V2); + // ((~B&A)|(B&~A)) -> A^B + if ((match(A, m_Not(m_Value(V1))) && + match(D, m_Not(m_Value(V2))))) + if (V1 == B && V2 == C) + return BinaryOperator::CreateXor(V1, V2); } // (X >> Z) | (Y >> Z) -> (X|Y) >> Z for all shifts. Added: llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll?rev=60291&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll Sun Nov 30 07:52:49 2008 @@ -0,0 +1,42 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {xor i32 %b, %a} | count 4 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {and} + +define i32 @func1(i32 %a, i32 %b) nounwind readnone { +entry: + %b_not = xor i32 %b, -1 + %0 = and i32 %a, %b_not + %a_not = xor i32 %a, -1 + %1 = and i32 %a_not, %b + %2 = or i32 %0, %1 + ret i32 %2 +} + +define i32 @func2(i32 %a, i32 %b) nounwind readnone { +entry: + %b_not = xor i32 %b, -1 + %0 = and i32 %b_not, %a + %a_not = xor i32 %a, -1 + %1 = and i32 %a_not, %b + %2 = or i32 %0, %1 + ret i32 %2 +} + +define i32 @func3(i32 %a, i32 %b) nounwind readnone { +entry: + %b_not = xor i32 %b, -1 + %0 = and i32 %a, %b_not + %a_not = xor i32 %a, -1 + %1 = and i32 %b, %a_not + %2 = or i32 %0, %1 + ret i32 %2 +} + +define i32 @func4(i32 %a, i32 %b) nounwind readnone { +entry: + %b_not = xor i32 %b, -1 + %0 = and i32 %b_not, %a + %a_not = xor i32 %a, -1 + %1 = and i32 %b, %a_not + %2 = or i32 %0, %1 + ret i32 %2 +} From sabre at nondot.org Sun Nov 30 13:10:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 19:10:42 -0000 Subject: [llvm-commits] [llvm] r60303 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200811301910.mAUJAgkH013584@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 13:10:41 2008 New Revision: 60303 URL: http://llvm.org/viewvc/llvm-project?rev=60303&view=rev Log: add the rest of the comparison routines. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60303&r1=60302&r2=60303&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Sun Nov 30 13:10:41 2008 @@ -60,12 +60,12 @@ void *getOpaqueValue() const { return reinterpret_cast(Value); } void setFromOpaqueValue(void *Val) { Value = reinterpret_cast(Val);} - bool operator==(const PointerIntPair &RHS) const { - return Value == RHS.Value; - } - bool operator!=(const PointerIntPair &RHS) const { - return Value != RHS.Value; - } + bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;} + bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;} + bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;} + bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;} + bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;} + bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;} }; // Provide specialization of DenseMapInfo for PointerIntPair. From sabre at nondot.org Sun Nov 30 13:24:31 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 19:24:31 -0000 Subject: [llvm-commits] [llvm] r60304 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811301924.mAUJOVqO014476@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 13:24:31 2008 New Revision: 60304 URL: http://llvm.org/viewvc/llvm-project?rev=60304&view=rev Log: Cache TargetData/AliasAnalysis in the pass instead of calling getAnalysis<>. getAnalysis<> is apparently extremely expensive. Doing this speeds up GVN on 403.gcc by 16%! Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60304&r1=60303&r2=60304&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Nov 30 13:24:31 2008 @@ -25,6 +25,8 @@ class FunctionPass; class Instruction; class CallSite; + class AliasAnalysis; + class TargetData; /// MemDepResult - A memory dependence query can return one of three different /// answers: @@ -148,13 +150,15 @@ // A reverse mapping form dependencies to the non-local dependees. ReverseDepMapType ReverseNonLocalDeps; + /// Current AA implementation, just a cache. + AliasAnalysis *AA; + TargetData *TD; public: MemoryDependenceAnalysis() : FunctionPass(&ID) {} static char ID; - /// Pass Implementation stuff. This doesn't do any analysis. - /// - bool runOnFunction(Function &) {return false; } + /// Pass Implementation stuff. This doesn't do any analysis eagerly. + bool runOnFunction(Function &); /// Clean up memory in between runs void releaseMemory() { Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60304&r1=60303&r2=60304&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Nov 30 13:24:31 2008 @@ -45,14 +45,17 @@ AU.addRequiredTransitive(); } +bool MemoryDependenceAnalysis::runOnFunction(Function &) { + AA = &getAnalysis(); + TD = &getAnalysis(); + return false; +} + /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB) { - AliasAnalysis &AA = getAnalysis(); - TargetData &TD = getAnalysis(); - // Walk backwards through the block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -62,17 +65,17 @@ uint64_t PointerSize = 0; if (StoreInst *S = dyn_cast(Inst)) { Pointer = S->getPointerOperand(); - PointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); + PointerSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); } else if (VAArgInst *V = dyn_cast(Inst)) { Pointer = V->getOperand(0); - PointerSize = TD.getTypeStoreSize(V->getType()); + PointerSize = TD->getTypeStoreSize(V->getType()); } else if (FreeInst *F = dyn_cast(Inst)) { Pointer = F->getPointerOperand(); // FreeInsts erase the entire structure PointerSize = ~0UL; } else if (isa(Inst) || isa(Inst)) { - if (AA.getModRefBehavior(CallSite::get(Inst)) == + if (AA->getModRefBehavior(CallSite::get(Inst)) == AliasAnalysis::DoesNotAccessMemory) continue; return DepResultTy(Inst, Normal); @@ -81,7 +84,7 @@ continue; } - if (AA.getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) + if (AA->getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) return DepResultTy(Inst, Normal); } @@ -95,9 +98,6 @@ MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt, BasicBlock *BB) { - AliasAnalysis &AA = getAnalysis(); - TargetData &TD = getAnalysis(); - // Get the pointer value for which dependence will be determined Value *MemPtr = 0; uint64_t MemSize = 0; @@ -105,15 +105,15 @@ if (StoreInst* S = dyn_cast(QueryInst)) { MemPtr = S->getPointerOperand(); - MemSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); + MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); MemVolatile = S->isVolatile(); } else if (LoadInst* L = dyn_cast(QueryInst)) { MemPtr = L->getPointerOperand(); - MemSize = TD.getTypeStoreSize(L->getType()); + MemSize = TD->getTypeStoreSize(L->getType()); MemVolatile = L->isVolatile(); } else if (VAArgInst* V = dyn_cast(QueryInst)) { MemPtr = V->getOperand(0); - MemSize = TD.getTypeStoreSize(V->getType()); + MemSize = TD->getTypeStoreSize(V->getType()); } else if (FreeInst* F = dyn_cast(QueryInst)) { MemPtr = F->getPointerOperand(); // FreeInsts erase the entire structure, not just a field. @@ -138,11 +138,11 @@ // a load depends on another must aliased load from the same value. if (LoadInst *L = dyn_cast(Inst)) { Value *Pointer = L->getPointerOperand(); - uint64_t PointerSize = TD.getTypeStoreSize(L->getType()); + uint64_t PointerSize = TD->getTypeStoreSize(L->getType()); // If we found a pointer, check if it could be the same as our pointer AliasAnalysis::AliasResult R = - AA.alias(Pointer, PointerSize, MemPtr, MemSize); + AA->alias(Pointer, PointerSize, MemPtr, MemSize); if (R == AliasAnalysis::NoAlias) continue; @@ -161,13 +161,13 @@ Value *AccessPtr = MemPtr->getUnderlyingObject(); if (AccessPtr == AI || - AA.alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) + AA->alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) return DepResultTy(0, None); continue; } // See if this instruction mod/ref's the pointer. - AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize); + AliasAnalysis::ModRefResult MRR = AA->getModRefInfo(Inst, MemPtr, MemSize); if (MRR == AliasAnalysis::NoModRef) continue; @@ -426,7 +426,7 @@ } assert(!NonLocalDeps.count(RemInst) && "RemInst got reinserted?"); - getAnalysis().deleteValue(RemInst); + AA->deleteValue(RemInst); DEBUG(verifyRemoved(RemInst)); } From eli.friedman at gmail.com Sun Nov 30 15:09:13 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 21:09:13 -0000 Subject: [llvm-commits] [llvm] r60306 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200811302109.mAUL9EJF021642@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 15:09:11 2008 New Revision: 60306 URL: http://llvm.org/viewvc/llvm-project?rev=60306&view=rev Log: Some minor cleanups to instcombine; no functionality change. Note that the FoldOpIntoPhi call is dead because it's impossible for the first operand of a subtraction to be both a ConstantInt and a PHINode. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60306&r1=60305&r2=60306&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 15:09:11 2008 @@ -344,13 +344,6 @@ } private: - /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the - /// InsertBefore instruction. This is specialized a bit to avoid inserting - /// casts that are known to not do anything... - /// - Value *InsertOperandCastBefore(Instruction::CastOps opcode, - Value *V, const Type *DestTy, - Instruction *InsertBefore); /// SimplifyCommutative - This performs a few simplifications for /// commutative operators. @@ -505,20 +498,6 @@ return true; } -/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the -/// InsertBefore instruction. This is specialized a bit to avoid inserting -/// casts that are known to not do anything... -/// -Value *InstCombiner::InsertOperandCastBefore(Instruction::CastOps opcode, - Value *V, const Type *DestTy, - Instruction *InsertBefore) { - if (V->getType() == DestTy) return V; - if (Constant *C = dyn_cast(V)) - return ConstantExpr::getCast(opcode, C, DestTy); - - return InsertCastBefore(opcode, V, DestTy, *InsertBefore); -} - // SimplifyCommutative - This performs a few simplifications for commutative // operators: // @@ -1815,11 +1794,7 @@ static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO, InstCombiner *IC) { if (CastInst *CI = dyn_cast(&I)) { - if (Constant *SOC = dyn_cast(SO)) - return ConstantExpr::getCast(CI->getOpcode(), SOC, I.getType()); - - return IC->InsertNewInstBefore(CastInst::Create( - CI->getOpcode(), SO, I.getType(), SO->getName() + ".cast"), I); + return IC->InsertCastBefore(CI->getOpcode(), SO, I.getType(), I); } // Figure out if the constant is the left or the right argument. @@ -2413,10 +2388,6 @@ if (SelectInst *SI = dyn_cast(Op1)) if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; - - if (isa(Op0)) - if (Instruction *NV = FoldOpIntoPhi(I)) - return NV; } if (I.getType() == Type::Int1Ty) @@ -7893,8 +7864,8 @@ !ValueRequiresCast(CI.getOpcode(), Op1, DestTy,TD) || !ValueRequiresCast(CI.getOpcode(), Op0, DestTy, TD)) { Instruction::CastOps opcode = CI.getOpcode(); - Value *Op0c = InsertOperandCastBefore(opcode, Op0, DestTy, SrcI); - Value *Op1c = InsertOperandCastBefore(opcode, Op1, DestTy, SrcI); + Value *Op0c = InsertCastBefore(opcode, Op0, DestTy, *SrcI); + Value *Op1c = InsertCastBefore(opcode, Op1, DestTy, *SrcI); return BinaryOperator::Create( cast(SrcI)->getOpcode(), Op0c, Op1c); } @@ -7905,7 +7876,7 @@ SrcI->getOpcode() == Instruction::Xor && Op1 == ConstantInt::getTrue() && (!Op0->hasOneUse() || !isa(Op0))) { - Value *New = InsertOperandCastBefore(Instruction::ZExt, Op0, DestTy, &CI); + Value *New = InsertCastBefore(Instruction::ZExt, Op0, DestTy, CI); return BinaryOperator::CreateXor(New, ConstantInt::get(CI.getType(), 1)); } break; @@ -7920,10 +7891,10 @@ // only be converting signedness, which is a noop. if (!ValueRequiresCast(CI.getOpcode(), Op1, DestTy, TD) || !ValueRequiresCast(CI.getOpcode(), Op0, DestTy, TD)) { - Value *Op0c = InsertOperandCastBefore(Instruction::BitCast, - Op0, DestTy, SrcI); - Value *Op1c = InsertOperandCastBefore(Instruction::BitCast, - Op1, DestTy, SrcI); + Value *Op0c = InsertCastBefore(Instruction::BitCast, + Op0, DestTy, *SrcI); + Value *Op1c = InsertCastBefore(Instruction::BitCast, + Op1, DestTy, *SrcI); return BinaryOperator::Create( cast(SrcI)->getOpcode(), Op0c, Op1c); } @@ -7940,8 +7911,8 @@ (DestBitSize < SrcBitSize && isa(Op1))) { Instruction::CastOps opcode = (DestBitSize == SrcBitSize ? Instruction::BitCast : Instruction::Trunc); - Value *Op0c = InsertOperandCastBefore(opcode, Op0, DestTy, SrcI); - Value *Op1c = InsertOperandCastBefore(opcode, Op1, DestTy, SrcI); + Value *Op0c = InsertCastBefore(opcode, Op0, DestTy, *SrcI); + Value *Op1c = InsertCastBefore(opcode, Op1, DestTy, *SrcI); return BinaryOperator::CreateShl(Op0c, Op1c); } break; @@ -8507,10 +8478,10 @@ Tmp->getOperand(0)->getType() == DestTy) || ((Tmp = dyn_cast(SVI->getOperand(1))) && Tmp->getOperand(0)->getType() == DestTy)) { - Value *LHS = InsertOperandCastBefore(Instruction::BitCast, - SVI->getOperand(0), DestTy, &CI); - Value *RHS = InsertOperandCastBefore(Instruction::BitCast, - SVI->getOperand(1), DestTy, &CI); + Value *LHS = InsertCastBefore(Instruction::BitCast, + SVI->getOperand(0), DestTy, CI); + Value *RHS = InsertCastBefore(Instruction::BitCast, + SVI->getOperand(1), DestTy, CI); // Return a new shuffle vector. Use the same element ID's, as we // know the vector types match #elts. return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2)); @@ -8835,8 +8806,6 @@ "not."+CondVal->getName()), SI); return CastInst::Create(Instruction::ZExt, NotCond, SI.getType()); } - - // FIXME: Turn select 0/-1 and -1/0 into sext from condition! if (ICmpInst *IC = dyn_cast(SI.getCondition())) { @@ -8852,17 +8821,9 @@ Instruction *SRA = BinaryOperator::Create(Instruction::AShr, X, ShAmt, "ones"); InsertNewInstBefore(SRA, SI); - - // Finally, convert to the type of the select RHS. We figure out - // if this requires a SExt, Trunc or BitCast based on the sizes. - Instruction::CastOps opc = Instruction::BitCast; - uint32_t SRASize = SRA->getType()->getPrimitiveSizeInBits(); - uint32_t SISize = SI.getType()->getPrimitiveSizeInBits(); - if (SRASize < SISize) - opc = Instruction::SExt; - else if (SRASize > SISize) - opc = Instruction::Trunc; - return CastInst::Create(opc, SRA, SI.getType()); + + // Then cast to the appropriate width. + return CastInst::CreateIntegerCast(SRA, SI.getType(), true); } } From eli.friedman at gmail.com Sun Nov 30 16:48:50 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 30 Nov 2008 22:48:50 -0000 Subject: [llvm-commits] [llvm] r60307 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200811302248.mAUMmp9G028515@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 16:48:49 2008 New Revision: 60307 URL: http://llvm.org/viewvc/llvm-project?rev=60307&view=rev Log: Minor cleanup: use getTrue and getFalse where appropriate. No functional change. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60307&r1=60306&r2=60307&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 16:48:49 2008 @@ -5443,9 +5443,9 @@ Pred = ICmpInst::ICMP_NE; break; case FCmpInst::FCMP_ORD: - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); case FCmpInst::FCMP_UNO: - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); } const IntegerType *IntTy = cast(LHSI->getOperand(0)->getType()); @@ -5465,8 +5465,8 @@ if (SMax.compare(RHS) == APFloat::cmpLessThan) { // smax < 13123.0 if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SLE) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); } } else { // If the RHS value is > UnsignedMax, fold the comparison. This handles @@ -5477,8 +5477,8 @@ if (UMax.compare(RHS) == APFloat::cmpLessThan) { // umax < 13123.0 if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); } } @@ -5490,8 +5490,8 @@ if (SMin.compare(RHS) == APFloat::cmpGreaterThan) { // smin > 12312.0 if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SGE) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I,ConstantInt::getTrue()); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); } } @@ -5508,14 +5508,14 @@ switch (Pred) { default: assert(0 && "Unexpected integer comparison!"); case ICmpInst::ICMP_NE: // (float)int != 4.4 --> true - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); case ICmpInst::ICMP_EQ: // (float)int == 4.4 --> false - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); case ICmpInst::ICMP_ULE: // (float)int <= 4.4 --> int <= 4 // (float)int <= -4.4 --> false if (RHS.isNegative()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); break; case ICmpInst::ICMP_SLE: // (float)int <= 4.4 --> int <= 4 @@ -5527,7 +5527,7 @@ // (float)int < -4.4 --> false // (float)int < 4.4 --> int <= 4 if (RHS.isNegative()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); Pred = ICmpInst::ICMP_ULE; break; case ICmpInst::ICMP_SLT: @@ -5540,7 +5540,7 @@ // (float)int > 4.4 --> int > 4 // (float)int > -4.4 --> true if (RHS.isNegative()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); break; case ICmpInst::ICMP_SGT: // (float)int > 4.4 --> int > 4 @@ -5552,7 +5552,7 @@ // (float)int >= -4.4 --> true // (float)int >= 4.4 --> int > 4 if (!RHS.isNegative()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); Pred = ICmpInst::ICMP_UGT; break; case ICmpInst::ICMP_SGE: @@ -5575,9 +5575,9 @@ // Fold trivial predicates. if (I.getPredicate() == FCmpInst::FCMP_FALSE) - return ReplaceInstUsesWith(I, Constant::getNullValue(Type::Int1Ty)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); if (I.getPredicate() == FCmpInst::FCMP_TRUE) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); // Simplify 'fcmp pred X, X' if (Op0 == Op1) { @@ -5586,11 +5586,11 @@ case FCmpInst::FCMP_UEQ: // True if unordered or equal case FCmpInst::FCMP_UGE: // True if unordered, greater than, or equal case FCmpInst::FCMP_ULE: // True if unordered, less than, or equal - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); case FCmpInst::FCMP_OGT: // True if ordered and greater than case FCmpInst::FCMP_OLT: // True if ordered and less than case FCmpInst::FCMP_ONE: // True if ordered and operands are unequal - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); case FCmpInst::FCMP_UNO: // True if unordered: isnan(X) | isnan(Y) case FCmpInst::FCMP_ULT: // True if unordered or less than @@ -5621,11 +5621,11 @@ if (ConstantFP *CFP = dyn_cast(RHSC)) { if (CFP->getValueAPF().isNaN()) { if (FCmpInst::isOrdered(I.getPredicate())) // True if ordered and... - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 0)); + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); assert(FCmpInst::isUnordered(I.getPredicate()) && "Comparison must be either ordered or unordered!"); // True if unordered. - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, 1)); + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); } } From sabre at nondot.org Sun Nov 30 17:17:19 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 23:17:19 -0000 Subject: [llvm-commits] [llvm] r60308 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200811302317.mAUNHJuJ029348@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 17:17:19 2008 New Revision: 60308 URL: http://llvm.org/viewvc/llvm-project?rev=60308&view=rev Log: Eliminate the DepResultTy abstraction. It is now completely redundant with MemDepResult, and MemDepResult has a nicer interface. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60308&r1=60307&r2=60308&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Nov 30 17:17:19 2008 @@ -27,17 +27,28 @@ class CallSite; class AliasAnalysis; class TargetData; + class MemoryDependenceAnalysis; /// MemDepResult - A memory dependence query can return one of three different - /// answers: - /// Normal : The query is dependent on a specific instruction. - /// NonLocal: The query does not depend on anything inside this block, but - /// we haven't scanned beyond the block to find out what. - /// None : The query does not depend on anything: we found the entry - /// block or the allocation site of the memory. + /// answers, described below. class MemDepResult { enum DepType { - Invalid = 0, Normal, NonLocal, None + /// Invalid - Clients of MemDep never see this. + Invalid = 0, + /// Normal - This is a normal instruction dependence. The pointer member + /// of the DepResultTy pair holds the instruction. + Normal, + + /// NonLocal - This marker indicates that the query has no dependency in + /// the specified block. To find out more, the client should query other + /// predecessor blocks. + NonLocal, + + /// None - This dependence type indicates that the query does not depend + /// on any instructions, either because it is not a memory instruction or + /// because it scanned to the definition of the memory (alloca/malloc) + /// being accessed. + None }; typedef PointerIntPair PairTy; PairTy Value; @@ -72,10 +83,29 @@ /// getInst() - If this is a normal dependency, return the instruction that /// is depended on. Otherwise, return null. - Instruction *getInst() const { return isNormal() ? Value.getPointer() : 0; } + Instruction *getInst() const { return Value.getPointer(); } bool operator==(const MemDepResult &M) { return M.Value == Value; } bool operator!=(const MemDepResult &M) { return M.Value != Value; } + private: + friend class MemoryDependenceAnalysis; + /// Dirty - Entries with this marker occur in a LocalDeps map or + /// NonLocalDeps map when the instruction they previously referenced was + /// removed from MemDep. In either case, the entry may include an + /// instruction pointer. If so, the pointer is an instruction in the + /// block where scanning can start from, saving some work. + /// + /// In a default-constructed DepResultTy object, the type will be Dirty + /// and the instruction pointer will be null. + /// + + /// isDirty - Return true if this is a MemDepResult in its dirty/invalid. + /// state. + bool isDirty() const { return Value.getInt() == Invalid; } + + static MemDepResult getDirty(Instruction *Inst) { + return MemDepResult(PairTy(Inst, Invalid)); + } }; /// MemoryDependenceAnalysis - This is an analysis that determines, for a @@ -94,42 +124,11 @@ /// internal caching mechanism. /// class MemoryDependenceAnalysis : public FunctionPass { - /// DepType - This enum is used to indicate what flavor of dependence this - /// is. If the type is Normal, there is an associated instruction pointer. - enum DepType { - /// Dirty - Entries with this marker occur in a LocalDeps map or - /// NonLocalDeps map when the instruction they previously referenced was - /// removed from MemDep. In either case, the entry may include an - /// instruction pointer. If so, the pointer is an instruction in the - /// block where scanning can start from, saving some work. - /// - /// In a default-constructed DepResultTy object, the type will be Dirty - /// and the instruction pointer will be null. - /// - Dirty = 0, - - /// Normal - This is a normal instruction dependence. The pointer member - /// of the DepResultTy pair holds the instruction. - Normal, - - /// None - This dependence type indicates that the query does not depend - /// on any instructions, either because it is not a memory instruction or - /// because it scanned to the definition of the memory (alloca/malloc) - /// being accessed. - None, - - /// NonLocal - This marker indicates that the query has no dependency in - /// the specified block. To find out more, the client should query other - /// predecessor blocks. - NonLocal - }; - typedef PointerIntPair DepResultTy; - // A map from instructions to their dependency. - typedef DenseMap LocalDepMapType; + typedef DenseMap LocalDepMapType; LocalDepMapType LocalDeps; - typedef DenseMap NonLocalDepInfo; + typedef DenseMap NonLocalDepInfo; /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and @@ -187,9 +186,7 @@ /// Note that this method does no caching at all. You should use /// getDependency where possible. MemDepResult getDependencyFrom(Instruction *QueryInst, - BasicBlock::iterator ScanIt, BasicBlock *BB){ - return ConvToResult(getDependencyFromInternal(QueryInst, ScanIt, BB)); - } + BasicBlock::iterator ScanIt, BasicBlock *BB); /// getNonLocalDependency - Perform a full dependency query for the @@ -208,25 +205,11 @@ void removeInstruction(Instruction *InstToRemove); private: - MemDepResult ConvToResult(DepResultTy R) { - if (R.getInt() == Normal) - return MemDepResult::get(R.getPointer()); - if (R.getInt() == NonLocal) - return MemDepResult::getNonLocal(); - assert(R.getInt() == None && "Unknown MemDepResult!"); - return MemDepResult::getNone(); - } - /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - /// getDependencyFromInternal - Return the instruction on which the memory - /// operation 'QueryInst' depends. This starts scanning from the - /// instruction before the position indicated by ScanIt. - DepResultTy getDependencyFromInternal(Instruction *QueryInst, - BasicBlock::iterator ScanIt, BasicBlock *BB); - DepResultTy getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, + MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB); }; Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60308&r1=60307&r2=60308&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Nov 30 17:17:19 2008 @@ -53,9 +53,8 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. -MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: -getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, - BasicBlock *BB) { +MemDepResult MemoryDependenceAnalysis:: +getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB) { // Walk backwards through the block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -78,26 +77,25 @@ if (AA->getModRefBehavior(CallSite::get(Inst)) == AliasAnalysis::DoesNotAccessMemory) continue; - return DepResultTy(Inst, Normal); + return MemDepResult::get(Inst); } else { // Non-memory instruction. continue; } if (AA->getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) - return DepResultTy(Inst, Normal); + return MemDepResult::get(Inst); } // No dependence found. - return DepResultTy(0, NonLocal); + return MemDepResult::getNonLocal(); } -/// getDependency - Return the instruction on which a memory operation -/// depends. The local parameter indicates if the query should only -/// evaluate dependencies within the same basic block. -MemoryDependenceAnalysis::DepResultTy MemoryDependenceAnalysis:: -getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt, - BasicBlock *BB) { +/// getDependencyFrom - Return the instruction on which a memory operation +/// depends. +MemDepResult MemoryDependenceAnalysis:: +getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, + BasicBlock *BB) { // Get the pointer value for which dependence will be determined Value *MemPtr = 0; uint64_t MemSize = 0; @@ -121,7 +119,7 @@ } else if (isa(QueryInst) || isa(QueryInst)) return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); else // Non-memory instructions depend on nothing. - return DepResultTy(0, None); + return MemDepResult::getNone(); // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { @@ -132,7 +130,7 @@ if (MemVolatile && ((isa(Inst) && cast(Inst)->isVolatile()) || (isa(Inst) && cast(Inst)->isVolatile()))) - return DepResultTy(Inst, Normal); + return MemDepResult::get(Inst); // Values depend on loads if the pointers are must aliased. This means that // a load depends on another must aliased load from the same value. @@ -150,7 +148,7 @@ // May-alias loads don't depend on each other without a dependence. if (isa(QueryInst) && R == AliasAnalysis::MayAlias) continue; - return DepResultTy(Inst, Normal); + return MemDepResult::get(Inst); } // If this is an allocation, and if we know that the accessed pointer is to @@ -162,7 +160,7 @@ if (AccessPtr == AI || AA->alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) - return DepResultTy(0, None); + return MemDepResult::getNone(); continue; } @@ -177,11 +175,11 @@ continue; // Otherwise, there is a dependence. - return DepResultTy(Inst, Normal); + return MemDepResult::get(Inst); } // If we found nothing, return the non-local flag. - return DepResultTy(0, NonLocal); + return MemDepResult::getNonLocal(); } /// getDependency - Return the instruction on which a memory operation @@ -190,16 +188,16 @@ Instruction *ScanPos = QueryInst; // Check for a cached result - DepResultTy &LocalCache = LocalDeps[QueryInst]; + MemDepResult &LocalCache = LocalDeps[QueryInst]; // If the cached entry is non-dirty, just return it. Note that this depends - // on DepResultTy's default constructing to 'dirty'. - if (LocalCache.getInt() != Dirty) - return ConvToResult(LocalCache); + // on MemDepResult's default constructing to 'dirty'. + if (!LocalCache.isDirty()) + return LocalCache; // Otherwise, if we have a dirty entry, we know we can start the scan at that // instruction, which may save us some work. - if (Instruction *Inst = LocalCache.getPointer()) { + if (Instruction *Inst = LocalCache.getInst()) { ScanPos = Inst; SmallPtrSet &InstMap = ReverseLocalDeps[Inst]; @@ -209,14 +207,13 @@ } // Do the scan. - LocalCache = getDependencyFromInternal(QueryInst, ScanPos, - QueryInst->getParent()); + LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); // Remember the result! - if (Instruction *I = LocalCache.getPointer()) + if (Instruction *I = LocalCache.getInst()) ReverseLocalDeps[I].insert(QueryInst); - return ConvToResult(LocalCache); + return LocalCache; } /// getNonLocalDependency - Perform a full dependency query for the @@ -251,7 +248,7 @@ if (CacheP.getInt()) for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E; ++I) - if (I->second.getInt() == Dirty) + if (I->second.isDirty()) DirtyBlocks.push_back(I->first); NumCacheNonLocal++; @@ -270,17 +267,17 @@ BasicBlock *DirtyBB = DirtyBlocks.back(); DirtyBlocks.pop_back(); - // Get the entry for this block. Note that this relies on DepResultTy + // Get the entry for this block. Note that this relies on MemDepResult // default initializing to Dirty. - DepResultTy &DirtyBBEntry = Cache[DirtyBB]; + MemDepResult &DirtyBBEntry = Cache[DirtyBB]; // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. - if (DirtyBBEntry.getInt() != Dirty) continue; + if (!DirtyBBEntry.isDirty()) continue; // If the dirty entry has a pointer, start scanning from it so we don't have // to rescan the entire block. BasicBlock::iterator ScanPos = DirtyBB->end(); - if (Instruction *Inst = DirtyBBEntry.getPointer()) { + if (Instruction *Inst = DirtyBBEntry.getInst()) { ScanPos = Inst; // We're removing QueryInst's dependence on Inst. @@ -290,14 +287,14 @@ } // Find out if this block has a local dependency for QueryInst. - DirtyBBEntry = getDependencyFromInternal(QueryInst, ScanPos, DirtyBB); + DirtyBBEntry = getDependencyFrom(QueryInst, ScanPos, DirtyBB); // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember it! - if (DirtyBBEntry.getInt() != NonLocal) { + if (!DirtyBBEntry.isNonLocal()) { // Keep the ReverseNonLocalDeps map up to date so we can efficiently // update this when we remove instructions. - if (Instruction *Inst = DirtyBBEntry.getPointer()) + if (Instruction *Inst = DirtyBBEntry.getInst()) ReverseNonLocalDeps[Inst].insert(QueryInst); continue; } @@ -310,7 +307,7 @@ // Copy the result into the output set. for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E;++I) - Result.push_back(std::make_pair(I->first, ConvToResult(I->second))); + Result.push_back(std::make_pair(I->first, I->second)); } /// removeInstruction - Remove an instruction from the dependence analysis, @@ -324,7 +321,7 @@ NonLocalDepInfo &BlockMap = *NLDI->second.getPointer(); for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) - if (Instruction *Inst = DI->second.getPointer()) + if (Instruction *Inst = DI->second.getInst()) ReverseNonLocalDeps[Inst].erase(RemInst); delete &BlockMap; NonLocalDeps.erase(NLDI); @@ -335,7 +332,7 @@ LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); if (LocalDepEntry != LocalDeps.end()) { // Remove us from DepInst's reverse set now that the local dep info is gone. - if (Instruction *Inst = LocalDepEntry->second.getPointer()) { + if (Instruction *Inst = LocalDepEntry->second.getInst()) { SmallPtrSet &RLD = ReverseLocalDeps[Inst]; RLD.erase(RemInst); if (RLD.empty()) @@ -369,7 +366,7 @@ assert(InstDependingOnRemInst != RemInst && "Already removed our local dep info"); - LocalDeps[InstDependingOnRemInst] = DepResultTy(NewDepInst, Dirty); + LocalDeps[InstDependingOnRemInst] = MemDepResult::getDirty(NewDepInst); // Make sure to remember that new things depend on NewDepInst. ReverseDepsToAdd.push_back(std::make_pair(NewDepInst, @@ -401,17 +398,15 @@ for (NonLocalDepInfo::iterator DI = INLD.getPointer()->begin(), DE = INLD.getPointer()->end(); DI != DE; ++DI) { - if (DI->second.getPointer() != RemInst) continue; + if (DI->second.getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - DI->second.setInt(Dirty); - if (RemInst->isTerminator()) - DI->second.setPointer(0); - else { - Instruction *NextI = next(BasicBlock::iterator(RemInst)); - DI->second.setPointer(NextI); + Instruction *NextI = 0; + if (!RemInst->isTerminator()) { + NextI = next(BasicBlock::iterator(RemInst)); ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); } + DI->second = MemDepResult::getDirty(NextI); } } @@ -436,7 +431,7 @@ for (LocalDepMapType::const_iterator I = LocalDeps.begin(), E = LocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); - assert(I->second.getPointer() != D && + assert(I->second.getInst() != D && "Inst occurs in data structures"); } @@ -446,7 +441,7 @@ const PerInstNLInfo &INLD = I->second; for (NonLocalDepInfo::iterator II = INLD.getPointer()->begin(), EE = INLD.getPointer()->end(); II != EE; ++II) - assert(II->second.getPointer() != D && "Inst occurs in data structures"); + assert(II->second.getInst() != D && "Inst occurs in data structures"); } for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(), From sabre at nondot.org Sun Nov 30 17:39:23 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 30 Nov 2008 23:39:23 -0000 Subject: [llvm-commits] [llvm] r60309 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200811302339.mAUNdO2l030212@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 17:39:23 2008 New Revision: 60309 URL: http://llvm.org/viewvc/llvm-project?rev=60309&view=rev Log: improve indentation, do cheap checks before expensive ones, remove some fixme's. This speeds up GVN very slightly on 403.gcc (4.06->4.03s) Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60309&r1=60308&r2=60309&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Nov 30 17:39:23 2008 @@ -461,8 +461,9 @@ if (local_dep.isNone()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (Instruction *LocalDepInst = local_dep.getInst()) { - // FIXME: INDENT PROPERLY! + } + + if (Instruction *LocalDepInst = local_dep.getInst()) { if (!isa(LocalDepInst)) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; @@ -470,28 +471,29 @@ CallInst* local_cdep = cast(LocalDepInst); - // FIXME: INDENT PROPERLY. if (local_cdep->getCalledFunction() != C->getCalledFunction() || local_cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (!C->getCalledFunction()) { + } + + if (!C->getCalledFunction()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else { - for (unsigned i = 1; i < C->getNumOperands(); ++i) { - uint32_t c_vn = lookup_or_add(C->getOperand(i)); - uint32_t cd_vn = lookup_or_add(local_cdep->getOperand(i)); - if (c_vn != cd_vn) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } - } + } - uint32_t v = lookup_or_add(local_cdep); - valueNumbering.insert(std::make_pair(V, v)); - return v; + for (unsigned i = 1; i < C->getNumOperands(); ++i) { + uint32_t c_vn = lookup_or_add(C->getOperand(i)); + uint32_t cd_vn = lookup_or_add(local_cdep->getOperand(i)); + if (c_vn != cd_vn) { + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + return nextValueNumber++; + } } + + uint32_t v = lookup_or_add(local_cdep); + valueNumbering.insert(std::make_pair(V, v)); + return v; } @@ -499,27 +501,30 @@ MD->getNonLocalDependency(C, deps); CallInst* cdep = 0; + // Check to see if we have a single dominating call instruction that is + // identical to C. for (SmallVector, 32> ::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { - if (I->second.isNone()) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } else if (Instruction *NonLocalDepInst = I->second.getInst()) { - // FIXME: INDENT PROPERLY - // FIXME: All duplicated with non-local case. - if (cdep == 0 && DT->properlyDominates(I->first, C->getParent())) { - if (CallInst* CD = dyn_cast(NonLocalDepInst)) - cdep = CD; - else { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } - } else { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } + // Ignore non-local dependencies. + if (I->second.isNonLocal()) + continue; + + // We don't handle non-depedencies. If we already have a call, reject + // instruction dependencies. + if (I->second.isNone() || cdep != 0) { + cdep = 0; + break; + } + + CallInst *NonLocalDepCall = dyn_cast(I->second.getInst()); + // FIXME: All duplicated with non-local case. + if (NonLocalDepCall && DT->properlyDominates(I->first, C->getParent())){ + cdep = NonLocalDepCall; + continue; } + + cdep = 0; + break; } if (!cdep) { @@ -527,34 +532,28 @@ return nextValueNumber++; } - // FIXME: THIS ISN'T SAFE: CONSIDER: - // X = strlen(str) - // if (C) - // str[0] = 1; - // Y = strlen(str) - // This doesn't guarantee all-paths availability! if (cdep->getCalledFunction() != C->getCalledFunction() || cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else if (!C->getCalledFunction()) { + } + if (!C->getCalledFunction()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; - } else { - for (unsigned i = 1; i < C->getNumOperands(); ++i) { - uint32_t c_vn = lookup_or_add(C->getOperand(i)); - uint32_t cd_vn = lookup_or_add(cdep->getOperand(i)); - if (c_vn != cd_vn) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } + } + for (unsigned i = 1; i < C->getNumOperands(); ++i) { + uint32_t c_vn = lookup_or_add(C->getOperand(i)); + uint32_t cd_vn = lookup_or_add(cdep->getOperand(i)); + if (c_vn != cd_vn) { + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + return nextValueNumber++; } - - uint32_t v = lookup_or_add(cdep); - valueNumbering.insert(std::make_pair(V, v)); - return v; } + uint32_t v = lookup_or_add(cdep); + valueNumbering.insert(std::make_pair(V, v)); + return v; + } else { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; From espindola at google.com Sun Nov 30 17:54:36 2008 From: espindola at google.com (Rafael Espindola) Date: Sun, 30 Nov 2008 23:54:36 +0000 Subject: [llvm-commits] [patch] fix bug 2843 Message-ID: <38a0d8450811301554q137902f0m976105ae8f3bbc78@mail.gmail.com> This patch is a new attempt to fix bug 2843 (format warning being printed by default). I tested that on linux, no warning is printed for the testase. Adding -Wformat -Wformat-security prints the warning. For some reason the changes in darwin.h to enable Wformat and Wformat-security are not working in my test. Can someone familiar with darwin take a look? I understand that a previous version of the patch caused some problems for fortran. Can someone familiar with that FE check if everything is fine? Thanks, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 From sabre at nondot.org Sun Nov 30 18:40:32 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 00:40:32 -0000 Subject: [llvm-commits] [llvm] r60310 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812010040.mB10eWbg032203@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 18:40:32 2008 New Revision: 60310 URL: http://llvm.org/viewvc/llvm-project?rev=60310&view=rev Log: Cache analyses in ivars and add some useful DEBUG output. This speeds up GVN from 4.0386s to 3.9376s. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60310&r1=60309&r2=60310&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Nov 30 18:40:32 2008 @@ -166,6 +166,7 @@ void erase(Value* v); unsigned size(); void setAliasAnalysis(AliasAnalysis* A) { AA = A; } + AliasAnalysis *getAliasAnalysis() const { return AA; } void setMemDep(MemoryDependenceAnalysis* M) { MD = M; } void setDomTree(DominatorTree* D) { DT = D; } uint32_t getNextUnusedValueNumber() { return nextValueNumber; } @@ -710,6 +711,9 @@ GVN() : FunctionPass(&ID) { } private: + MemoryDependenceAnalysis *MD; + DominatorTree *DT; + ValueTable VN; DenseMap localAvail; @@ -771,16 +775,14 @@ } Value* GVN::CollapsePhi(PHINode* p) { - DominatorTree &DT = getAnalysis(); Value* constVal = p->hasConstantValue(); - if (!constVal) return 0; Instruction* inst = dyn_cast(constVal); if (!inst) return constVal; - if (DT.dominates(inst, p)) + if (DT->dominates(inst, p)) if (isSafeReplacement(p, inst)) return inst; return 0; @@ -811,7 +813,7 @@ // If the block is unreachable, just return undef, since this path // can't actually occur at runtime. - if (!getAnalysis().isReachableFromEntry(BB)) + if (!DT->isReachableFromEntry(BB)) return Phis[BB] = UndefValue::get(orig->getType()); BasicBlock* singlePred = BB->getSinglePredecessor(); @@ -836,8 +838,7 @@ PN->addIncoming(val, *PI); } - AliasAnalysis& AA = getAnalysis(); - AA.copyValue(orig, PN); + VN.getAliasAnalysis()->copyValue(orig, PN); // Attempt to collapse PHI nodes that are trivially redundant Value* v = CollapsePhi(PN); @@ -847,9 +848,6 @@ return PN; } - MemoryDependenceAnalysis& MD = getAnalysis(); - - MD.removeInstruction(PN); PN->replaceAllUsesWith(v); for (DenseMap::iterator I = Phis.begin(), @@ -857,6 +855,8 @@ if (I->second == PN) I->second = v; + DEBUG(cerr << "GVN removed: " << *PN); + MD->removeInstruction(PN); PN->eraseFromParent(); Phis[BB] = v; @@ -867,11 +867,12 @@ /// non-local by performing PHI construction. bool GVN::processNonLocalLoad(LoadInst* L, SmallVectorImpl &toErase) { - MemoryDependenceAnalysis& MD = getAnalysis(); - // Find the non-local dependencies of the load SmallVector, 32> deps; - MD.getNonLocalDependency(L, deps); + MD->getNonLocalDependency(L, deps); + + DEBUG(cerr << "INVESTIGATING NONLOCAL LOAD: " << deps.size() << *L); + // If we had to process more than one hundred blocks to find the // dependencies, this load isn't worth worrying about. Optimizing @@ -919,7 +920,6 @@ for (SmallPtrSet::iterator I = p.begin(), E = p.end(); I != E; ++I) { if ((*I)->getParent() == L->getParent()) { - MD.removeInstruction(L); L->replaceAllUsesWith(*I); toErase.push_back(L); NumGVNLoad++; @@ -928,16 +928,15 @@ repl.insert(std::make_pair((*I)->getParent(), *I)); } - + + DEBUG(cerr << "GVN REMOVING NONLOCAL LOAD: " << *L); + // Perform PHI construction SmallPtrSet visited; Value* v = GetValueForBlock(L->getParent(), L, repl, true); - - MD.removeInstruction(L); L->replaceAllUsesWith(v); toErase.push_back(L); NumGVNLoad++; - return true; } @@ -954,9 +953,8 @@ LoadInst*& last = lastLoad[pointer]; // ... to a pointer that has been loaded from before... - MemoryDependenceAnalysis& MD = getAnalysis(); bool removedNonLocal = false; - MemDepResult dep = MD.getDependency(L); + MemDepResult dep = MD->getDependency(L); if (dep.isNonLocal() && L->getParent() != &L->getParent()->getParent()->getEntryBlock()) { removedNonLocal = processNonLocalLoad(L, toErase); @@ -977,8 +975,6 @@ if (StoreInst* S = dyn_cast(DepInst)) { if (S->getPointerOperand() == pointer) { // Remove it! - MD.removeInstruction(L); - L->replaceAllUsesWith(S->getOperand(0)); toErase.push_back(L); deletedLoad = true; @@ -997,15 +993,13 @@ break; } else if (DepInst == last) { // Remove it! - MD.removeInstruction(L); - L->replaceAllUsesWith(last); toErase.push_back(L); deletedLoad = true; NumGVNLoad++; break; } else { - dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent()); + dep = MD->getDependencyFrom(L, DepInst, DepInst->getParent()); } } @@ -1016,7 +1010,6 @@ // If this load depends directly on an allocation, there isn't // anything stored there; therefore, we can optimize this load // to undef. - MD.removeInstruction(L); L->replaceAllUsesWith(UndefValue::get(L->getType())); toErase.push_back(L); deletedLoad = true; @@ -1098,9 +1091,6 @@ // Perform value-number based elimination } else if (Value* repl = lookupNumber(I->getParent(), num)) { // Remove it! - MemoryDependenceAnalysis& MD = getAnalysis(); - MD.removeInstruction(I); - VN.erase(I); I->replaceAllUsesWith(repl); toErase.push_back(I); @@ -1116,9 +1106,11 @@ // function. // bool GVN::runOnFunction(Function& F) { + MD = &getAnalysis(); + DT = &getAnalysis(); VN.setAliasAnalysis(&getAnalysis()); - VN.setMemDep(&getAnalysis()); - VN.setDomTree(&getAnalysis()); + VN.setMemDep(MD); + VN.setDomTree(DT); bool changed = false; bool shouldContinue = true; @@ -1155,7 +1147,6 @@ bool GVN::processBlock(DomTreeNode* DTN) { BasicBlock* BB = DTN->getBlock(); - SmallVector toErase; DenseMap lastSeenLoad; bool changed_function = false; @@ -1183,8 +1174,11 @@ --BI; for (SmallVector::iterator I = toErase.begin(), - E = toErase.end(); I != E; ++I) + E = toErase.end(); I != E; ++I) { + DEBUG(cerr << "GVN removed: " << **I); + MD->removeInstruction(*I); (*I)->eraseFromParent(); + } if (AtStart) BI = BB->begin(); @@ -1336,8 +1330,9 @@ Instruction* erase = BI; BI++; + DEBUG(cerr << "GVN removed: " << *erase); + MD->removeInstruction(erase); erase->eraseFromParent(); - changed = true; } } @@ -1351,14 +1346,12 @@ // iterateOnFunction - Executes one iteration of GVN bool GVN::iterateOnFunction(Function &F) { - DominatorTree &DT = getAnalysis(); - cleanupGlobalSets(); // Top-down walk of the dominator tree bool changed = false; - for (df_iterator DI = df_begin(DT.getRootNode()), - DE = df_end(DT.getRootNode()); DI != DE; ++DI) + for (df_iterator DI = df_begin(DT->getRootNode()), + DE = df_end(DT->getRootNode()); DI != DE; ++DI) changed |= processBlock(*DI); return changed; From eli.friedman at gmail.com Sun Nov 30 18:43:48 2008 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 01 Dec 2008 00:43:48 -0000 Subject: [llvm-commits] [llvm] r60311 - /llvm/trunk/include/llvm/ADT/APInt.h Message-ID: <200812010043.mB10hmAW032321@zion.cs.uiuc.edu> Author: efriedma Date: Sun Nov 30 18:43:48 2008 New Revision: 60311 URL: http://llvm.org/viewvc/llvm-project?rev=60311&view=rev Log: Fix bogus assertion using getSExtValue for legitimate values, like -1 in an 128-bit-wide integer. No testcase; the issue I ran into depends on local changes. Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=60311&r1=60310&r2=60311&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Sun Nov 30 18:43:48 2008 @@ -1046,7 +1046,7 @@ if (isSingleWord()) return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >> (APINT_BITS_PER_WORD - BitWidth); - assert(getActiveBits() <= 64 && "Too many bits for int64_t"); + assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); return int64_t(pVal[0]); } From isanbard at gmail.com Sun Nov 30 19:07:11 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 01:07:11 -0000 Subject: [llvm-commits] [llvm] r60312 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and-or.ll Message-ID: <200812010107.mB117BFE000445@zion.cs.uiuc.edu> Author: void Date: Sun Nov 30 19:07:11 2008 New Revision: 60312 URL: http://llvm.org/viewvc/llvm-project?rev=60312&view=rev Log: Implement ((A|B)&1)|(B&-2) -> (A&1) | B transformation. This also takes care of permutations of this pattern. Added: llvm/trunk/test/Transforms/InstCombine/and-or.ll Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60312&r1=60311&r2=60312&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Nov 30 19:07:11 2008 @@ -1147,12 +1147,6 @@ //===---------------------------------------------------------------------===// -int a(int a, int b) {return ((a|b)&1) | (b&-2);} -Should be combined to "(a&1)|b". Currently not optimized with "clang --emit-llvm-bc | opt -std-compile-opts". - -//===---------------------------------------------------------------------===// - int a(unsigned b) {return ((b << 31) | (b << 30)) >> 31;} Should be combined to "((b >> 1) | b) & 1". Currently not optimized with "clang -emit-llvm-bc | opt -std-compile-opts". Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60312&r1=60311&r2=60312&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 19:07:11 2008 @@ -4649,6 +4649,73 @@ } } + // ((A|B)&1)|(B&-2) -> (A&1) | B + if (match(Op0, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || + match(Op0, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getValue() == 1) { + Value *V1 = 0, *C2 = 0; + if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { + ConstantInt *CI2 = dyn_cast(C2); + + if (!CI2) { + std::swap(V1, C2); + CI2 = dyn_cast(C2); + } + + if (CI2) { + APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); + if (CI2->getValue().eq(NegTwo)) { + if (V1 == B) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); + return BinaryOperator::CreateOr(NewOp, B); + } + if (V1 == A) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); + return BinaryOperator::CreateOr(NewOp, A); + } + } + } + } + } + } + } + // (B&-2)|((A|B)&1) -> (A&1) | B + if (match(Op1, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || + match(Op1, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getValue() == 1) { + Value *V1 = 0, *C2 = 0; + if (match(Op0, m_And(m_Value(V1), m_Value(C2)))) { + ConstantInt *CI2 = dyn_cast(C2); + + if (!CI2) { + std::swap(V1, C2); + CI2 = dyn_cast(C2); + } + + if (CI2) { + APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); + if (CI2->getValue().eq(NegTwo)) { + if (V1 == B) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); + return BinaryOperator::CreateOr(NewOp, B); + } + if (V1 == A) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); + return BinaryOperator::CreateOr(NewOp, A); + } + } + } + } + } + } + } + if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1 if (A == Op1) // ~A | A == -1 return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); Added: llvm/trunk/test/Transforms/InstCombine/and-or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and-or.ll?rev=60312&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/and-or.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/and-or.ll Sun Nov 30 19:07:11 2008 @@ -0,0 +1,39 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %a, 1} | count 4 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {or i32 %0, %b} | count 4 + + +define i32 @func1(i32 %a, i32 %b) nounwind readnone { +entry: + %0 = or i32 %b, %a ; [#uses=1] + %1 = and i32 %0, 1 ; [#uses=1] + %2 = and i32 %b, -2 ; [#uses=1] + %3 = or i32 %1, %2 ; [#uses=1] + ret i32 %3 +} + +define i32 @func2(i32 %a, i32 %b) nounwind readnone { +entry: + %0 = or i32 %a, %b ; [#uses=1] + %1 = and i32 1, %0 ; [#uses=1] + %2 = and i32 -2, %b ; [#uses=1] + %3 = or i32 %1, %2 ; [#uses=1] + ret i32 %3 +} + +define i32 @func3(i32 %a, i32 %b) nounwind readnone { +entry: + %0 = or i32 %b, %a ; [#uses=1] + %1 = and i32 %0, 1 ; [#uses=1] + %2 = and i32 %b, -2 ; [#uses=1] + %3 = or i32 %2, %1 ; [#uses=1] + ret i32 %3 +} + +define i32 @func4(i32 %a, i32 %b) nounwind readnone { +entry: + %0 = or i32 %a, %b ; [#uses=1] + %1 = and i32 1, %0 ; [#uses=1] + %2 = and i32 -2, %b ; [#uses=1] + %3 = or i32 %2, %1 ; [#uses=1] + ret i32 %3 +} From sabre at nondot.org Sun Nov 30 19:15:43 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 01:15:43 -0000 Subject: [llvm-commits] [llvm] r60313 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp Message-ID: <200812010115.mB11FhCw000693@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 19:15:42 2008 New Revision: 60313 URL: http://llvm.org/viewvc/llvm-project?rev=60313&view=rev Log: Reimplement the non-local dependency data structure in terms of a sorted vector instead of a densemap. This shrinks the memory usage of this thing substantially (the high water mark) as well as making operations like scanning it faster. This speeds up memdep slightly, gvn goes from 3.9376 to 3.9118s on 403.gcc This also splits out the statistics for the cached non-local case to differentiate between the dirty and clean cached case. Here's the stats for 403.gcc: 6153 memdep - Number of dirty cached non-local responses 169336 memdep - Number of fully cached non-local responses 162428 memdep - Number of uncached non-local responses yay for caching :) Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60313&r1=60312&r2=60313&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Nov 30 19:15:42 2008 @@ -36,7 +36,7 @@ /// Invalid - Clients of MemDep never see this. Invalid = 0, /// Normal - This is a normal instruction dependence. The pointer member - /// of the DepResultTy pair holds the instruction. + /// of the MemDepResult pair holds the instruction. Normal, /// NonLocal - This marker indicates that the query has no dependency in @@ -85,8 +85,10 @@ /// is depended on. Otherwise, return null. Instruction *getInst() const { return Value.getPointer(); } - bool operator==(const MemDepResult &M) { return M.Value == Value; } - bool operator!=(const MemDepResult &M) { return M.Value != Value; } + bool operator==(const MemDepResult &M) const { return M.Value == Value; } + bool operator!=(const MemDepResult &M) const { return M.Value != Value; } + bool operator<(const MemDepResult &M) const { return M.Value < Value; } + bool operator>(const MemDepResult &M) const { return M.Value > Value; } private: friend class MemoryDependenceAnalysis; /// Dirty - Entries with this marker occur in a LocalDeps map or @@ -95,14 +97,14 @@ /// instruction pointer. If so, the pointer is an instruction in the /// block where scanning can start from, saving some work. /// - /// In a default-constructed DepResultTy object, the type will be Dirty + /// In a default-constructed MemDepResult object, the type will be Dirty /// and the instruction pointer will be null. /// - + /// isDirty - Return true if this is a MemDepResult in its dirty/invalid. /// state. bool isDirty() const { return Value.getInt() == Invalid; } - + static MemDepResult getDirty(Instruction *Inst) { return MemDepResult(PairTy(Inst, Invalid)); } @@ -128,12 +130,15 @@ typedef DenseMap LocalDepMapType; LocalDepMapType LocalDeps; - typedef DenseMap NonLocalDepInfo; + public: + typedef std::pair NonLocalDepEntry; + typedef std::vector NonLocalDepInfo; + private: /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and /// the bool indicates whether we have any dirty bits in the set. - typedef PointerIntPair PerInstNLInfo; + typedef std::pair PerInstNLInfo; // A map from instructions to their non-local dependencies. typedef DenseMap NonLocalDepMapType; @@ -162,9 +167,7 @@ /// Clean up memory in between runs void releaseMemory() { LocalDeps.clear(); - for (NonLocalDepMapType::iterator I = NonLocalDeps.begin(), - E = NonLocalDeps.end(); I != E; ++I) - delete I->second.getPointer(); + NonLocalDeps.clear(); NonLocalDeps.clear(); ReverseLocalDeps.clear(); ReverseNonLocalDeps.clear(); @@ -194,11 +197,14 @@ /// potentially live across. The returned set of results will include a /// "NonLocal" result for all blocks where the value is live across. /// - /// This method assumes the instruction returns a "nonlocal" dependency + /// This method assumes the instruction returns a "NonLocal" dependency /// within its own block. - void getNonLocalDependency(Instruction *QueryInst, - SmallVectorImpl > &Result); + /// + /// This returns a reference to an internal data structure that may be + /// invalidated on the next non-local query or when an instruction is + /// removed. Clients must copy this data if they want it around longer than + /// that. + const NonLocalDepInfo &getNonLocalDependency(Instruction *QueryInst); /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60313&r1=60312&r2=60313&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Nov 30 19:15:42 2008 @@ -28,9 +28,9 @@ #include "llvm/Target/TargetData.h" using namespace llvm; -STATISTIC(NumCacheNonLocal, "Number of cached non-local responses"); +STATISTIC(NumCacheNonLocal, "Number of fully cached non-local responses"); +STATISTIC(NumCacheDirtyNonLocal, "Number of dirty cached non-local responses"); STATISTIC(NumUncacheNonLocal, "Number of uncached non-local responses"); - char MemoryDependenceAnalysis::ID = 0; // Register this pass... @@ -51,10 +51,12 @@ return false; } + /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. MemDepResult MemoryDependenceAnalysis:: getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB) { + // Walk backwards through the block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -224,16 +226,13 @@ /// This method assumes the instruction returns a "nonlocal" dependency /// within its own block. /// -void MemoryDependenceAnalysis:: -getNonLocalDependency(Instruction *QueryInst, - SmallVectorImpl > &Result) { +const MemoryDependenceAnalysis::NonLocalDepInfo & +MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) { assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); PerInstNLInfo &CacheP = NonLocalDeps[QueryInst]; - if (CacheP.getPointer() == 0) CacheP.setPointer(new NonLocalDepInfo()); - NonLocalDepInfo &Cache = *CacheP.getPointer(); + NonLocalDepInfo &Cache = CacheP.first; /// DirtyBlocks - This is the set of blocks that need to be recomputed. In /// the cached case, this can happen due to instructions being deleted etc. In @@ -242,17 +241,24 @@ SmallVector DirtyBlocks; if (!Cache.empty()) { + // Okay, we have a cache entry. If we know it is not dirty, just return it + // with no computation. + if (!CacheP.second) { + NumCacheNonLocal++; + return Cache; + } + // If we already have a partially computed set of results, scan them to - // determine what is dirty, seeding our initial DirtyBlocks worklist. The - // Int bit of CacheP tells us if we have anything dirty. - if (CacheP.getInt()) - for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); - I != E; ++I) - if (I->second.isDirty()) - DirtyBlocks.push_back(I->first); + // determine what is dirty, seeding our initial DirtyBlocks worklist. + for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); + I != E; ++I) + if (I->second.isDirty()) + DirtyBlocks.push_back(I->first); - NumCacheNonLocal++; + // Sort the cache so that we can do fast binary search lookups below. + std::sort(Cache.begin(), Cache.end()); + ++NumCacheDirtyNonLocal; //cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " // << Cache.size() << " cached: " << *QueryInst; } else { @@ -262,52 +268,80 @@ NumUncacheNonLocal++; } + // Visited checked first, vector in sorted order. + SmallPtrSet Visited; + + unsigned NumSortedEntries = Cache.size(); + // Iterate while we still have blocks to update. while (!DirtyBlocks.empty()) { BasicBlock *DirtyBB = DirtyBlocks.back(); DirtyBlocks.pop_back(); - // Get the entry for this block. Note that this relies on MemDepResult - // default initializing to Dirty. - MemDepResult &DirtyBBEntry = Cache[DirtyBB]; + // Already processed this block? + if (!Visited.insert(DirtyBB)) + continue; + + // Do a binary search to see if we already have an entry for this block in + // the cache set. If so, find it. + NonLocalDepInfo::iterator Entry = + std::upper_bound(Cache.begin(), Cache.begin()+NumSortedEntries, + std::make_pair(DirtyBB, MemDepResult())); + if (Entry != Cache.begin() && (&*Entry)[-1].first == DirtyBB) + --Entry; + + MemDepResult *ExistingResult = 0; + if (Entry != Cache.begin()+NumSortedEntries && + Entry->first == DirtyBB) { + // If we already have an entry, and if it isn't already dirty, the block + // is done. + if (!Entry->second.isDirty()) + continue; + + // Otherwise, remember this slot so we can update the value. + ExistingResult = &Entry->second; + } - // If DirtyBBEntry isn't dirty, it ended up on the worklist multiple times. - if (!DirtyBBEntry.isDirty()) continue; - // If the dirty entry has a pointer, start scanning from it so we don't have // to rescan the entire block. BasicBlock::iterator ScanPos = DirtyBB->end(); - if (Instruction *Inst = DirtyBBEntry.getInst()) { - ScanPos = Inst; + if (ExistingResult) { + if (Instruction *Inst = ExistingResult->getInst()) { + ScanPos = Inst; - // We're removing QueryInst's dependence on Inst. - SmallPtrSet &InstMap = ReverseNonLocalDeps[Inst]; - InstMap.erase(QueryInst); - if (InstMap.empty()) ReverseNonLocalDeps.erase(Inst); + // We're removing QueryInst's use of Inst. + SmallPtrSet &InstMap = ReverseNonLocalDeps[Inst]; + InstMap.erase(QueryInst); + if (InstMap.empty()) ReverseNonLocalDeps.erase(Inst); + } } // Find out if this block has a local dependency for QueryInst. - DirtyBBEntry = getDependencyFrom(QueryInst, ScanPos, DirtyBB); - + MemDepResult Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB); + + // If we had a dirty entry for the block, update it. Otherwise, just add + // a new entry. + if (ExistingResult) + *ExistingResult = Dep; + else + Cache.push_back(std::make_pair(DirtyBB, Dep)); + // If the block has a dependency (i.e. it isn't completely transparent to - // the value), remember it! - if (!DirtyBBEntry.isNonLocal()) { + // the value), remember the association! + if (!Dep.isNonLocal()) { // Keep the ReverseNonLocalDeps map up to date so we can efficiently // update this when we remove instructions. - if (Instruction *Inst = DirtyBBEntry.getInst()) + if (Instruction *Inst = Dep.getInst()) ReverseNonLocalDeps[Inst].insert(QueryInst); - continue; - } + } else { - // If the block *is* completely transparent to the load, we need to check - // the predecessors of this block. Add them to our worklist. - DirtyBlocks.append(pred_begin(DirtyBB), pred_end(DirtyBB)); + // If the block *is* completely transparent to the load, we need to check + // the predecessors of this block. Add them to our worklist. + DirtyBlocks.append(pred_begin(DirtyBB), pred_end(DirtyBB)); + } } - - // Copy the result into the output set. - for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); I != E;++I) - Result.push_back(std::make_pair(I->first, I->second)); + return Cache; } /// removeInstruction - Remove an instruction from the dependence analysis, @@ -318,12 +352,11 @@ // for any cached queries. NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); if (NLDI != NonLocalDeps.end()) { - NonLocalDepInfo &BlockMap = *NLDI->second.getPointer(); + NonLocalDepInfo &BlockMap = NLDI->second.first; for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) if (Instruction *Inst = DI->second.getInst()) ReverseNonLocalDeps[Inst].erase(RemInst); - delete &BlockMap; NonLocalDeps.erase(NLDI); } @@ -392,12 +425,11 @@ assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); PerInstNLInfo &INLD = NonLocalDeps[*I]; - assert(INLD.getPointer() != 0 && "Reverse mapping out of date?"); // The information is now dirty! - INLD.setInt(true); + INLD.second = true; - for (NonLocalDepInfo::iterator DI = INLD.getPointer()->begin(), - DE = INLD.getPointer()->end(); DI != DE; ++DI) { + for (NonLocalDepInfo::iterator DI = INLD.first.begin(), + DE = INLD.first.end(); DI != DE; ++DI) { if (DI->second.getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. @@ -439,8 +471,8 @@ E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); const PerInstNLInfo &INLD = I->second; - for (NonLocalDepInfo::iterator II = INLD.getPointer()->begin(), - EE = INLD.getPointer()->end(); II != EE; ++II) + for (NonLocalDepInfo::const_iterator II = INLD.first.begin(), + EE = INLD.first.end(); II != EE; ++II) assert(II->second.getInst() != D && "Inst occurs in data structures"); } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60313&r1=60312&r2=60313&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Nov 30 19:15:42 2008 @@ -497,15 +497,15 @@ return v; } - - SmallVector, 32> deps; - MD->getNonLocalDependency(C, deps); + + const MemoryDependenceAnalysis::NonLocalDepInfo &deps = + MD->getNonLocalDependency(C); CallInst* cdep = 0; // Check to see if we have a single dominating call instruction that is // identical to C. - for (SmallVector, 32> - ::iterator I = deps.begin(), E = deps.end(); I != E; ++I) { + for (unsigned i = 0, e = deps.size(); i != e; ++i) { + const MemoryDependenceAnalysis::NonLocalDepEntry *I = &deps[i]; // Ignore non-local dependencies. if (I->second.isNonLocal()) continue; @@ -868,11 +868,18 @@ bool GVN::processNonLocalLoad(LoadInst* L, SmallVectorImpl &toErase) { // Find the non-local dependencies of the load - SmallVector, 32> deps; - MD->getNonLocalDependency(L, deps); - + const MemoryDependenceAnalysis::NonLocalDepInfo &deps = + MD->getNonLocalDependency(L); DEBUG(cerr << "INVESTIGATING NONLOCAL LOAD: " << deps.size() << *L); - +#if 0 + DEBUG(for (unsigned i = 0, e = deps.size(); i != e; ++i) { + cerr << " " << deps[i].first->getName(); + if (Instruction *I = deps[i].second.getInst()) + cerr << *I; + else + cerr << "\n"; + }); +#endif // If we had to process more than one hundred blocks to find the // dependencies, this load isn't worth worrying about. Optimizing @@ -885,31 +892,36 @@ DenseMap repl; // Filter out useless results (non-locals, etc) - for (SmallVector, 32>::iterator - I = deps.begin(), E = deps.end(); I != E; ++I) { - if (I->second.isNone()) { - repl[I->first] = UndefValue::get(L->getType()); - continue; - } - - if (I->second.isNonLocal()) { + for (unsigned i = 0, e = deps.size(); i != e; ++i) { + BasicBlock *DepBB = deps[i].first; + MemDepResult DepInfo = deps[i].second; + + if (DepInfo.isNonLocal()) { // If this is a non-local dependency in the entry block, then we depend on // the value live-in at the start of the function. We could insert a load // in the entry block to get this, but for now we'll just bail out. + // // FIXME: Consider emitting a load in the entry block to catch this case! - if (I->first == EntryBlock) + // Tricky part is to sink so that it doesn't execute in places where it + // isn't needed. + if (DepBB == EntryBlock) return false; continue; } + + if (DepInfo.isNone()) { + repl[DepBB] = UndefValue::get(L->getType()); + continue; + } - if (StoreInst* S = dyn_cast(I->second.getInst())) { + if (StoreInst* S = dyn_cast(DepInfo.getInst())) { if (S->getPointerOperand() != L->getPointerOperand()) return false; - repl[I->first] = S->getOperand(0); - } else if (LoadInst* LD = dyn_cast(I->second.getInst())) { + repl[DepBB] = S->getOperand(0); + } else if (LoadInst* LD = dyn_cast(DepInfo.getInst())) { if (LD->getPointerOperand() != L->getPointerOperand()) return false; - repl[I->first] = LD; + repl[DepBB] = LD; } else { return false; } From sabre at nondot.org Sun Nov 30 19:31:36 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 01:31:36 -0000 Subject: [llvm-commits] [llvm] r60314 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812010131.mB11VapM001156@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 19:31:36 2008 New Revision: 60314 URL: http://llvm.org/viewvc/llvm-project?rev=60314&view=rev Log: Make GVN be more intelligent about redundant load elimination: when finding dependent load/stores, realize that they are the same if aliasing claims must alias instead of relying on the pointers to be exactly equal. This makes load elimination more aggressive. For example, on 403.gcc, we had: < 68 gvn - Number of instructions PRE'd < 152718 gvn - Number of instructions deleted < 49699 gvn - Number of loads deleted < 6153 memdep - Number of dirty cached non-local responses < 169336 memdep - Number of fully cached non-local responses < 162428 memdep - Number of uncached non-local responses now we have: > 64 gvn - Number of instructions PRE'd > 153623 gvn - Number of instructions deleted > 49856 gvn - Number of loads deleted > 5022 memdep - Number of dirty cached non-local responses > 159030 memdep - Number of fully cached non-local responses > 162443 memdep - Number of uncached non-local responses That's an extra 157 loads deleted and extra 905 other instructions nuked. This slows down GVN very slightly, from 3.91 to 3.96s. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60314&r1=60313&r2=60314&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Nov 30 19:31:36 2008 @@ -915,11 +915,28 @@ } if (StoreInst* S = dyn_cast(DepInfo.getInst())) { - if (S->getPointerOperand() != L->getPointerOperand()) + // Reject loads and stores that are to the same address but are of + // different types. + // NOTE: 403.gcc does have this case (e.g. in readonly_fields_p) because + // of bitfield access, it would be interesting to optimize for it at some + // point. + if (S->getOperand(0)->getType() != L->getType()) + return false; + + if (S->getPointerOperand() != L->getPointerOperand() && + VN.getAliasAnalysis()->alias(S->getPointerOperand(), 1, + L->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) return false; repl[DepBB] = S->getOperand(0); } else if (LoadInst* LD = dyn_cast(DepInfo.getInst())) { - if (LD->getPointerOperand() != L->getPointerOperand()) + if (LD->getType() != L->getType()) + return false; + + if (LD->getPointerOperand() != L->getPointerOperand() && + VN.getAliasAnalysis()->alias(LD->getPointerOperand(), 1, + L->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) return false; repl[DepBB] = LD; } else { From sabre at nondot.org Sun Nov 30 19:42:03 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 01:42:03 -0000 Subject: [llvm-commits] [llvm] r60315 - /llvm/trunk/test/Transforms/GVN/rle-must-alias.ll Message-ID: <200812010142.mB11g3M3001446@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 19:42:03 2008 New Revision: 60315 URL: http://llvm.org/viewvc/llvm-project?rev=60315&view=rev Log: testcase for my previous commit. Added: llvm/trunk/test/Transforms/GVN/rle-must-alias.ll Added: llvm/trunk/test/Transforms/GVN/rle-must-alias.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/rle-must-alias.ll?rev=60315&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/rle-must-alias.ll (added) +++ llvm/trunk/test/Transforms/GVN/rle-must-alias.ll Sun Nov 30 19:42:03 2008 @@ -0,0 +1,42 @@ +; RUN: llvm-as < %s | opt -gvn | llvm-dis | grep {DEAD.rle = phi i32} +; The %7 and %4 loads combine to make %DEAD unneeded. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + at H = common global [100 x i32] zeroinitializer, align 32 ; <[100 x i32]*> [#uses=3] + at G = common global i32 0 ; [#uses=2] + +define i32 @test(i32 %i) nounwind { +entry: + %0 = tail call i32 (...)* @foo() nounwind ; [#uses=1] + %1 = icmp eq i32 %0, 0 ; [#uses=1] + br i1 %1, label %bb1, label %bb + +bb: ; preds = %entry + %2 = tail call i32 (...)* @bar() nounwind ; [#uses=0] + %3 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; [#uses=1] + %4 = load i32* %3, align 4 ; [#uses=1] + store i32 %4, i32* @G, align 4 + br label %bb3 + +bb1: ; preds = %entry + %5 = tail call i32 (...)* @baz() nounwind ; [#uses=0] + %6 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; [#uses=1] + %7 = load i32* %6, align 4 ; [#uses=2] + store i32 %7, i32* @G, align 4 + %8 = icmp eq i32 %7, 0 ; [#uses=1] + br i1 %8, label %bb3, label %bb4 + +bb3: ; preds = %bb1, %bb + %9 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; [#uses=1] + %DEAD = load i32* %9, align 4 ; [#uses=1] + ret i32 %DEAD + +bb4: ; preds = %bb1 + ret i32 0 +} + +declare i32 @foo(...) + +declare i32 @bar(...) + +declare i32 @baz(...) From sabre at nondot.org Sun Nov 30 20:34:36 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 02:34:36 -0000 Subject: [llvm-commits] [llvm] r60322 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/phi.ll Message-ID: <200812010234.mB12YbvU002993@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 20:34:36 2008 New Revision: 60322 URL: http://llvm.org/viewvc/llvm-project?rev=60322&view=rev Log: Teach inst combine to merge GEPs through PHIs. This is really important because it is sinking the loads using the GEPs, but not the GEPs themselves. This triggers 647 times on 403.gcc and makes the .s file much much nicer. For example before: je LBB1_87 ## bb78 LBB1_62: ## bb77 leal 84(%esi), %eax LBB1_63: ## bb79 movl (%eax), %eax .. LBB1_87: ## bb78 movl $0, 4(%esp) movl %esi, (%esp) call L_make_decl_rtl$stub jmp LBB1_62 ## bb77 after: jne LBB1_63 ## bb79 LBB1_62: ## bb78 movl $0, 4(%esp) movl %esi, (%esp) call L_make_decl_rtl$stub LBB1_63: ## bb79 movl 84(%esi), %eax The input code was (and the GEPs are merged and the PHI is now eliminated by instcombine): br i1 %tmp233, label %bb78, label %bb77 bb77: %tmp234 = getelementptr %struct.tree_node* %t_addr.3, i32 0, i32 0, i32 22 br label %bb79 bb78: call void @make_decl_rtl(%struct.tree_node* %t_addr.3, i8* null) nounwind %tmp235 = getelementptr %struct.tree_node* %t_addr.3, i32 0, i32 0, i32 22 br label %bb79 bb79: %iftmp.12.0.in = phi %struct.rtx_def** [ %tmp235, %bb78 ], [ %tmp234, %bb77 ] %iftmp.12.0 = load %struct.rtx_def** %iftmp.12.0.in Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/phi.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60322&r1=60321&r2=60322&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 20:34:36 2008 @@ -372,7 +372,8 @@ // inputs, and do the operation once, to the result of the PHI. Instruction *FoldPHIArgOpIntoPHI(PHINode &PN); Instruction *FoldPHIArgBinOpIntoPHI(PHINode &PN); - + Instruction *FoldPHIArgGEPIntoPHI(PHINode &PN); + Instruction *OptAndOp(Instruction *Op, ConstantInt *OpRHS, ConstantInt *AndRHS, BinaryOperator &TheAnd); @@ -9985,7 +9986,7 @@ // Scan to see if all operands are the same opcode, all have one use, and all // kill their operands (i.e. the operands have one use). - for (unsigned i = 0; i != PN.getNumIncomingValues(); ++i) { + for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) { Instruction *I = dyn_cast(PN.getIncomingValue(i)); if (!I || I->getOpcode() != Opc || !I->hasOneUse() || // Verify type of the LHS matches so we don't fold cmp's of different @@ -10010,6 +10011,7 @@ // If this is a GEP, and if the index (not the pointer) needs a PHI, bail out. // Indexes are often folded into load/store instructions, so we don't want to // hide them behind a phi. + // URR?? if (isa(FirstInst) && RHSVal == 0) return 0; @@ -10035,28 +10037,101 @@ } // Add all operands to the new PHIs. - for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { - if (NewLHS) { - Value *NewInLHS =cast(PN.getIncomingValue(i))->getOperand(0); - NewLHS->addIncoming(NewInLHS, PN.getIncomingBlock(i)); - } - if (NewRHS) { - Value *NewInRHS =cast(PN.getIncomingValue(i))->getOperand(1); - NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i)); + if (NewLHS || NewRHS) { + for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { + Instruction *InInst = cast(PN.getIncomingValue(i)); + if (NewLHS) { + Value *NewInLHS = InInst->getOperand(0); + NewLHS->addIncoming(NewInLHS, PN.getIncomingBlock(i)); + } + if (NewRHS) { + Value *NewInRHS = InInst->getOperand(1); + NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i)); + } } } if (BinaryOperator *BinOp = dyn_cast(FirstInst)) return BinaryOperator::Create(BinOp->getOpcode(), LHSVal, RHSVal); - else if (CmpInst *CIOp = dyn_cast(FirstInst)) + if (CmpInst *CIOp = dyn_cast(FirstInst)) return CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), LHSVal, RHSVal); - else { - assert(isa(FirstInst)); - return GetElementPtrInst::Create(LHSVal, RHSVal); + assert(isa(FirstInst)); + return GetElementPtrInst::Create(LHSVal, RHSVal); +} + +Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { + GetElementPtrInst *FirstInst =cast(PN.getIncomingValue(0)); + + SmallVector FixedOperands(FirstInst->op_begin(), + FirstInst->op_end()); + + // Scan to see if all operands are the same opcode, all have one use, and all + // kill their operands (i.e. the operands have one use). + for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) { + GetElementPtrInst *GEP= dyn_cast(PN.getIncomingValue(i)); + if (!GEP || !GEP->hasOneUse() || GEP->getType() != FirstInst->getType() || + GEP->getNumOperands() != FirstInst->getNumOperands()) + return 0; + + // Compare the operand lists. + for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) { + if (FirstInst->getOperand(op) == GEP->getOperand(op)) + continue; + + // Don't merge two GEPs when two operands differ (introducing phi nodes) + // if one of the PHIs has a constant for the index. The index may be + // substantially cheaper to compute for the constants, so making it a + // variable index could pessimize the path. This also handles the case + // for struct indices, which must always be constant. + if (isa(FirstInst->getOperand(op)) || + isa(GEP->getOperand(op))) + return 0; + + if (FirstInst->getOperand(op)->getType() !=GEP->getOperand(op)->getType()) + return 0; + FixedOperands[op] = 0; // Needs a PHI. + } } + + // Otherwise, this is safe to transform. Insert PHI nodes for each operand + // that is variable. + SmallVector OperandPhis(FixedOperands.size()); + + bool HasAnyPHIs = false; + for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) { + if (FixedOperands[i]) continue; // operand doesn't need a phi. + Value *FirstOp = FirstInst->getOperand(i); + PHINode *NewPN = PHINode::Create(FirstOp->getType(), + FirstOp->getName()+".pn"); + InsertNewInstBefore(NewPN, PN); + + NewPN->reserveOperandSpace(e); + NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0)); + OperandPhis[i] = NewPN; + FixedOperands[i] = NewPN; + HasAnyPHIs = true; + } + + + // Add all operands to the new PHIs. + if (HasAnyPHIs) { + for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { + GetElementPtrInst *InGEP =cast(PN.getIncomingValue(i)); + BasicBlock *InBB = PN.getIncomingBlock(i); + + for (unsigned op = 0, e = OperandPhis.size(); op != e; ++op) + if (PHINode *OpPhi = OperandPhis[op]) + OpPhi->addIncoming(InGEP->getOperand(op), InBB); + } + } + + Value *Base = FixedOperands[0]; + return GetElementPtrInst::Create(Base, FixedOperands.begin()+1, + FixedOperands.end()); } + /// isSafeToSinkLoad - Return true if we know that it is safe sink the load out /// of the block that defines it. This means that it must be obvious the value /// of the load is not changed from the point of the load to the end of the @@ -10134,8 +10209,7 @@ } else if (isa(FirstInst)) { if (FirstInst->getNumOperands() == 2) return FoldPHIArgBinOpIntoPHI(PN); - // Can't handle general GEPs yet. - return 0; + return FoldPHIArgGEPIntoPHI(PN); } else { return 0; // Cannot fold this operation. } @@ -10279,6 +10353,11 @@ // If all PHI operands are the same operation, pull them through the PHI, // reducing code size. if (isa(PN.getIncomingValue(0)) && + isa(PN.getIncomingValue(1)) && + cast(PN.getIncomingValue(0))->getOpcode() == + cast(PN.getIncomingValue(1))->getOpcode() && + // FIXME: The hasOneUse check will fail for PHIs that use the value more + // than themselves more than once. PN.getIncomingValue(0)->hasOneUse()) if (Instruction *Result = FoldPHIArgOpIntoPHI(PN)) return Result; Modified: llvm/trunk/test/Transforms/InstCombine/phi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/phi.ll?rev=60322&r1=60321&r2=60322&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/phi.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/phi.ll Sun Nov 30 20:34:36 2008 @@ -1,7 +1,6 @@ ; This test makes sure that these instructions are properly eliminated. ; ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep phi -; END. define i32 @test1(i32 %A, i1 %b) { BB0: @@ -98,4 +97,19 @@ ret i32 0 } +define i32* @test8({ i32, i32 } *%A, i1 %b) { +BB0: + %X = getelementptr { i32, i32 } *%A, i32 0, i32 1 + br i1 %b, label %BB1, label %BB2 + +BB1: + %Y = getelementptr { i32, i32 } *%A, i32 0, i32 1 + br label %BB2 + +BB2: + ;; Suck GEPs into phi + %B = phi i32* [ %X, %BB0 ], [ %Y, %BB1 ] + ret i32* %B +} + From sabre at nondot.org Sun Nov 30 21:42:52 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 03:42:52 -0000 Subject: [llvm-commits] [llvm] r60325 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812010342.mB13gqbF004903@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 21:42:51 2008 New Revision: 60325 URL: http://llvm.org/viewvc/llvm-project?rev=60325&view=rev Log: Change instcombine to use FoldPHIArgGEPIntoPHI to fold two operand PHIs instead of using FoldPHIArgBinOpIntoPHI. In addition to being more obvious, this also fixes a problem where instcombine wouldn't merge two phis that had different variable indices. This prevented instcombine from factoring big chunks of code in 403.gcc. For example: insn_cuid.exit: - %tmp336 = load i32** @uid_cuid, align 4 - %tmp337 = getelementptr %struct.rtx_def* %insn_addr.0.ph.i, i32 0, i32 3 - %tmp338 = bitcast [1 x %struct.rtunion]* %tmp337 to i32* - %tmp339 = load i32* %tmp338, align 4 - %tmp340 = getelementptr i32* %tmp336, i32 %tmp339 br label %bb62 bb61: - %tmp341 = load i32** @uid_cuid, align 4 - %tmp342 = getelementptr %struct.rtx_def* %insn, i32 0, i32 3 - %tmp343 = bitcast [1 x %struct.rtunion]* %tmp342 to i32* - %tmp344 = load i32* %tmp343, align 4 - %tmp345 = getelementptr i32* %tmp341, i32 %tmp344 br label %bb62 bb62: - %iftmp.62.0.in = phi i32* [ %tmp345, %bb61 ], [ %tmp340, %insn_cuid.exit ] + %insn.pn2 = phi %struct.rtx_def* [ %insn, %bb61 ], [ %insn_addr.0.ph.i, %insn_cuid.exit ] + %tmp344.pn.in.in = getelementptr %struct.rtx_def* %insn.pn2, i32 0, i32 3 + %tmp344.pn.in = bitcast [1 x %struct.rtunion]* %tmp344.pn.in.in to i32* + %tmp341.pn = load i32** @uid_cuid + %tmp344.pn = load i32* %tmp344.pn.in + %iftmp.62.0.in = getelementptr i32* %tmp341.pn, i32 %tmp344.pn %iftmp.62.0 = load i32* %iftmp.62.0.in Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60325&r1=60324&r2=60325&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 21:42:51 2008 @@ -9975,8 +9975,7 @@ /// and a single binop. Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { Instruction *FirstInst = cast(PN.getIncomingValue(0)); - assert(isa(FirstInst) || isa(FirstInst) || - isa(FirstInst)); + assert(isa(FirstInst) || isa(FirstInst)); unsigned Opc = FirstInst->getOpcode(); Value *LHSVal = FirstInst->getOperand(0); Value *RHSVal = FirstInst->getOperand(1); @@ -10006,14 +10005,7 @@ if (I->getOperand(1) != RHSVal) RHSVal = 0; } - // Otherwise, this is safe to transform, determine if it is profitable. - - // If this is a GEP, and if the index (not the pointer) needs a PHI, bail out. - // Indexes are often folded into load/store instructions, so we don't want to - // hide them behind a phi. - // URR?? - if (isa(FirstInst) && RHSVal == 0) - return 0; + // Otherwise, this is safe to transform! Value *InLHS = FirstInst->getOperand(0); Value *InRHS = FirstInst->getOperand(1); @@ -10053,11 +10045,9 @@ if (BinaryOperator *BinOp = dyn_cast(FirstInst)) return BinaryOperator::Create(BinOp->getOpcode(), LHSVal, RHSVal); - if (CmpInst *CIOp = dyn_cast(FirstInst)) - return CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), LHSVal, - RHSVal); - assert(isa(FirstInst)); - return GetElementPtrInst::Create(LHSVal, RHSVal); + CmpInst *CIOp = cast(FirstInst); + return CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), LHSVal, + RHSVal); } Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) { @@ -10207,8 +10197,6 @@ return 0; } else if (isa(FirstInst)) { - if (FirstInst->getNumOperands() == 2) - return FoldPHIArgBinOpIntoPHI(PN); return FoldPHIArgGEPIntoPHI(PN); } else { return 0; // Cannot fold this operation. From sabre at nondot.org Sun Nov 30 21:58:39 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 03:58:39 -0000 Subject: [llvm-commits] [llvm] r60326 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200812010358.mB13wdpO005307@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 21:58:38 2008 New Revision: 60326 URL: http://llvm.org/viewvc/llvm-project?rev=60326&view=rev Log: The PreVerifier pass preserves everything. In practice, this prevents the passmgr from adding yet-another domtree invocation for Verifier if there is already one live. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=60326&r1=60325&r2=60326&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sun Nov 30 21:58:38 2008 @@ -72,6 +72,10 @@ PreVerifier() : FunctionPass(&ID) { } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + // Check that the prerequisites for successful DominatorTree construction // are satisfied. bool runOnFunction(Function &F) { From monping at apple.com Sun Nov 30 22:12:32 2008 From: monping at apple.com (Mon Ping Wang) Date: Sun, 30 Nov 2008 20:12:32 -0800 Subject: [llvm-commits] Patch: updated widen in LegalizeType Message-ID: <6400B666-5A24-42E8-8C6C-2F70F94E3020@apple.com> Hi, Here is an updated patch based with fixes thanks to comments from Duncan. This patch is long so I didn't include the dozen or so of new test cases for X86 to try different aspect of widening. The main differences with this version from the previous one are 1) We have added a few vector simple types (v2i8, v4i8, v2i16) in order to enable getTypeAction to work properly with widening. Given a type, it is clear which ones we want to widen or which ones we want to split. 2) The LegalizeType code no longer uses getWidenVectorTypes. Instead, we use getTypeToTransformTo. 3) The code for converts has changed. Because the result type and the input type different, it is possible we have a legal widen result type but if we widen the input type, we might create an illegal vector type that might need to be split. If did widen the input, we might end up in a case where we repeatedly try to widen the input, split it, and then widen it again. To avoid this, the code checks if the input type is illegal and if so, it will not widen the input. Instead, it does is conservative and unroll the convert and rebuild the vector. 4) Widening of load and stores now support extended vector loads and truncating stores. The current implementation is conservative as it unrolls the operation and rebuilds the vector. We could probably do a little better here though. 5) Added WidenVecOp_CONCAT_VECTORS as we can have a legal result type but the input vectors may not be legal. In a separate patch, I will send out some fixes that widening exposes in codegen for MMX. Thanks, -- Mon Ping -------------- next part -------------- A non-text attachment was scrubbed... Name: widen2.patch Type: application/octet-stream Size: 65141 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081130/c9b807ed/attachment.obj From clattner at apple.com Sun Nov 30 22:17:05 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 30 Nov 2008 20:17:05 -0800 Subject: [llvm-commits] [llvm] r60306 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200811302109.mAUL9EJF021642@zion.cs.uiuc.edu> References: <200811302109.mAUL9EJF021642@zion.cs.uiuc.edu> Message-ID: <80437BC2-C2F6-44DF-ADF2-A2433A9386B4@apple.com> On Nov 30, 2008, at 1:09 PM, Eli Friedman wrote: > Author: efriedma > Date: Sun Nov 30 15:09:11 2008 > New Revision: 60306 > > URL: http://llvm.org/viewvc/llvm-project?rev=60306&view=rev > Log: > Some minor cleanups to instcombine; no functionality change. Hi Eli, After hacking on instcombine a bit, I think what it really needs is a spiffy new kind of IRBuilder. Before calling visit() on an instruction, the top level could set the builder to be positioned on the instruction (so any new instructions would default to going before it). It could then use a template parameter to intercept the "insert" calls, implicitly adding the new instructions to the worklist in addition to inserting them into the program. What do you think? -Chris From clattner at apple.com Sun Nov 30 22:23:33 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 30 Nov 2008 20:23:33 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> Message-ID: On Nov 29, 2008, at 7:42 PM, Bill Wendling wrote: > Author: void > Date: Sat Nov 29 21:42:12 2008 > New Revision: 60275 > > URL: http://llvm.org/viewvc/llvm-project?rev=60275&view=rev > Log: > Instcombine was illegally transforming -X/C into X/-C when either X > or C > overflowed on negation. This commit checks to make sure that neithe > C nor X > overflows. This requires that the RHS of X (a subtract instruction) > be a > constant integer. Hi Bill, I think that negate only overflows on minint, instead of: > + ConstantInt *RHSNeg = > cast(ConstantExpr::getNeg(RHS)); > + > + // -X/C -> X/-C, if and only if negation doesn't overflow. > + if ((RHS->getSExtValue() < 0 && > + RHS->getSExtValue() < RHSNeg->getSExtValue()) || > + (RHS->getSExtValue() > 0 && > + RHS->getSExtValue() > RHSNeg->getSExtValue())) { How about checking: "RHSNext != RHS" ? Also, please check the "if (Value *LHSNeg = dyn_castNegVal(Op0)) {" condition before computing the negation of the RHS. This is a very uncommon transformation, so you shouldn't be fiddling with constants unless the pattern matches. -Chris > > + if (Value *LHSNeg = dyn_castNegVal(Op0)) { > + if (ConstantInt *CI = dyn_cast(LHSNeg)) { > + ConstantInt *CINeg = > cast(ConstantExpr::getNeg(CI)); > + > + if ((CI->getSExtValue() < 0 && > + CI->getSExtValue() < CINeg->getSExtValue()) || > + (CI->getSExtValue() > 0 && > + CI->getSExtValue() > CINeg->getSExtValue())) > + return BinaryOperator::CreateSDiv(LHSNeg, > + > ConstantExpr::getNeg(RHS)); > + } > + } > + } > } > > // If the sign bits of both operands are zero (i.e. we can prove > they are > > Modified: llvm/trunk/test/Transforms/InstCombine/apint-sub.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-sub.ll?rev=60275&r1=60274&r2=60275&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Transforms/InstCombine/apint-sub.ll (original) > +++ llvm/trunk/test/Transforms/InstCombine/apint-sub.ll Sat Nov 29 > 21:42:12 2008 > @@ -3,7 +3,7 @@ > ; > > ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \ > -; RUN: grep -v {sub i19 %Cok, %Bok} | not grep sub > +; RUN: grep -v {sub i19 %Cok, %Bok} | grep -v {sub i25 0, %Aok} | > not grep sub > ; END. > > define i23 @test1(i23 %A) { > @@ -107,8 +107,10 @@ > ret i51 %Y > } > > -define i25 @test17(i25 %A) { > - %B = sub i25 0, %A ; [#uses=1] > +; Can't fold subtract here because negation it might oveflow. > +; PR3142 > +define i25 @test17(i25 %Aok) { > + %B = sub i25 0, %Aok ; [#uses=1] > %C = sdiv i25 %B, 1234 ; [#uses=1] > ret i25 %C > } > > Added: llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll?rev=60275&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll (added) > +++ llvm/trunk/test/Transforms/InstCombine/sdiv-1.ll Sat Nov 29 > 21:42:12 2008 > @@ -0,0 +1,22 @@ > +; RUN: llvm-as < %s | opt -instcombine -inline | llvm-dis | grep > {715827882} | count 2 > +; PR3142 > + > +define i32 @a(i32 %X) nounwind readnone { > +entry: > + %0 = sub i32 0, %X > + %1 = sdiv i32 %0, -3 > + ret i32 %1 > +} > + > +define i32 @b(i32 %X) nounwind readnone { > +entry: > + %0 = call i32 @a(i32 -2147483648) > + ret i32 %0 > +} > + > +define i32 @c(i32 %X) nounwind readnone { > +entry: > + %0 = sub i32 0, -2147483648 > + %1 = sdiv i32 %0, -3 > + ret i32 %1 > +} > > Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=60275&r1=60274&r2=60275&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/Transforms/InstCombine/sub.ll (original) > +++ llvm/trunk/test/Transforms/InstCombine/sub.ll Sat Nov 29 > 21:42:12 2008 > @@ -1,7 +1,7 @@ > ; This test makes sure that these instructions are properly > eliminated. > ; > ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \ > -; RUN: grep -v {sub i32 %Cok, %Bok} | not grep sub > +; RUN: grep -v {sub i32 %Cok, %Bok} | grep -v {sub i32 0, %Aok} | > not grep sub > > define i32 @test1(i32 %A) { > %B = sub i32 %A, %A ; [#uses=1] > @@ -104,8 +104,10 @@ > ret i32 %Y > } > > -define i32 @test17(i32 %A) { > - %B = sub i32 0, %A ; [#uses=1] > +; Can't fold subtract here because negation it might oveflow. > +; PR3142 > +define i32 @test17(i32 %Aok) { > + %B = sub i32 0, %Aok ; [#uses=1] > %C = sdiv i32 %B, 1234 ; [#uses=1] > ret i32 %C > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From monping at apple.com Sun Nov 30 22:32:48 2008 From: monping at apple.com (Mon Ping Wang) Date: Sun, 30 Nov 2008 20:32:48 -0800 Subject: [llvm-commits] Patch: small fix to bit convert and shifts Message-ID: Hi, This is a small patch that fixes two problems in SelectionDAG.cpp 1) in getShuffleScalarElt, the code assumes that if the input to the shuffle is a BIT_CONVERT, the input to the bit convert is also a vector. This is not necessarily true as it is legal to bit convert a 2) In getNode, the code assumes that for shifts, the shift amount is always a scalar. Since shifts can operate also on vectors, this assumption is not correct. -- Mon Ping -------------- next part -------------- A non-text attachment was scrubbed... Name: selection.patch Type: application/octet-stream Size: 1174 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081130/baf5580c/attachment.obj From sabre at nondot.org Sun Nov 30 22:48:09 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 04:48:09 -0000 Subject: [llvm-commits] [llvm] r60327 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200812010448.mB14mAU0006980@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 22:48:07 2008 New Revision: 60327 URL: http://llvm.org/viewvc/llvm-project?rev=60327&view=rev Log: Teach jump threading to clean up after itself, DCE and constfolding the new instructions it simplifies. Because we're threading jumps on edges with constants coming in from PHI's, we inherently are exposing a lot more constants to the new block. Folding them and deleting dead conditions allows the cost model in jump threading to be more accurate as it iterates. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60327&r1=60326&r2=60327&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Sun Nov 30 22:48:07 2008 @@ -17,8 +17,10 @@ #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Target/TargetData.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -51,10 +53,15 @@ /// revectored to the false side of the second if. /// class VISIBILITY_HIDDEN JumpThreading : public FunctionPass { + TargetData *TD; public: static char ID; // Pass identification JumpThreading() : FunctionPass(&ID) {} + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + bool runOnFunction(Function &F); bool ProcessBlock(BasicBlock *BB); void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB); @@ -79,6 +86,7 @@ /// bool JumpThreading::runOnFunction(Function &F) { DOUT << "Jump threading on function '" << F.getNameStart() << "'\n"; + TD = &getAnalysis(); bool AnotherIteration = true, EverChanged = false; while (AnotherIteration) { @@ -679,7 +687,7 @@ PN->addIncoming(IV, NewBB); } - // Finally, NewBB is good to go. Update the terminator of PredBB to jump to + // Ok, NewBB is good to go. Update the terminator of PredBB to jump to // NewBB instead of BB. This eliminates predecessors from BB, which requires // us to simplify any PHI nodes in BB. TerminatorInst *PredTerm = PredBB->getTerminator(); @@ -688,4 +696,19 @@ BB->removePredecessor(PredBB); PredTerm->setSuccessor(i, NewBB); } + + // At this point, the IR is fully up to date and consistent. Do a quick scan + // over the new instructions and zap any that are constants or dead. This + // frequently happens because of phi translation. + BI = NewBB->begin(); + for (BasicBlock::iterator E = NewBB->end(); BI != E; ) { + Instruction *Inst = BI++; + if (Constant *C = ConstantFoldInstruction(Inst, TD)) { + Inst->replaceAllUsesWith(C); + Inst->eraseFromParent(); + continue; + } + + RecursivelyDeleteTriviallyDeadInstructions(Inst); + } } From sabre at nondot.org Sun Nov 30 23:16:26 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 05:16:26 -0000 Subject: [llvm-commits] [llvm] r60328 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and-not-or.ll Message-ID: <200812010516.mB15GR2K007778@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 30 23:16:26 2008 New Revision: 60328 URL: http://llvm.org/viewvc/llvm-project?rev=60328&view=rev Log: simplify these patterns using m_Specific. No need to grep for xor in testcase (or is a substring). Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/and-not-or.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60328&r1=60327&r2=60328&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 30 23:16:26 2008 @@ -3980,22 +3980,12 @@ } // (A&((~A)|B)) -> A&B - if (match(Op0, m_Or(m_Not(m_Value(A)), m_Value(B)))) { - if (A == Op1) - return BinaryOperator::CreateAnd(A, B); - } - if (match(Op0, m_Or(m_Value(A), m_Not(m_Value(B))))) { - if (B == Op1) - return BinaryOperator::CreateAnd(A, B); - } - if (match(Op1, m_Or(m_Not(m_Value(A)), m_Value(B)))) { - if (A == Op0) - return BinaryOperator::CreateAnd(A, B); - } - if (match(Op1, m_Or(m_Value(A), m_Not(m_Value(B))))) { - if (B == Op0) - return BinaryOperator::CreateAnd(A, B); - } + if (match(Op0, m_Or(m_Not(m_Specific(Op1)), m_Value(A))) || + match(Op0, m_Or(m_Value(A), m_Not(m_Specific(Op1))))) + return BinaryOperator::CreateAnd(A, Op1); + if (match(Op1, m_Or(m_Not(m_Specific(Op0)), m_Value(A))) || + match(Op1, m_Or(m_Value(A), m_Not(m_Specific(Op0))))) + return BinaryOperator::CreateAnd(A, Op0); } if (ICmpInst *RHS = dyn_cast(Op1)) { Modified: llvm/trunk/test/Transforms/InstCombine/and-not-or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and-not-or.ll?rev=60328&r1=60327&r2=60328&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/and-not-or.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/and-not-or.ll Sun Nov 30 23:16:26 2008 @@ -1,6 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %y, %x} | count 2 -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %x, %y} | count 2 -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {xor} +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {and i32 %x, %y} | count 4 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {or} define i32 @func1(i32 %x, i32 %y) nounwind { From clattner at apple.com Sun Nov 30 23:17:50 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 30 Nov 2008 21:17:50 -0800 Subject: [llvm-commits] [llvm] r60291 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or-to-xor.ll In-Reply-To: <200811301352.mAUDqoDt029527@zion.cs.uiuc.edu> References: <200811301352.mAUDqoDt029527@zion.cs.uiuc.edu> Message-ID: On Nov 30, 2008, at 5:52 AM, Bill Wendling wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=60291&view=rev > Log: > Add instruction combining for ((A&~B)|(~A&B)) -> A^B and all > permutations. Thanks Bill! > + V1 = V2 = 0; > + > + // ((A&~B)|(~A&B)) -> A^B > + if ((match(C, m_Not(m_Value(V1))) && > + match(B, m_Not(m_Value(V2))))) > + if (V1 == D && V2 == A) > + return BinaryOperator::CreateXor(V1, V2); > + // ((~B&A)|(~A&B)) -> A^B > + if ((match(A, m_Not(m_Value(V1))) && > + match(B, m_Not(m_Value(V2))))) > + if (V1 == D && V2 == C) > + return BinaryOperator::CreateXor(V1, V2); > + // ((A&~B)|(B&~A)) -> A^B > + if ((match(C, m_Not(m_Value(V1))) && > + match(D, m_Not(m_Value(V2))))) > + if (V1 == B && V2 == A) > + return BinaryOperator::CreateXor(V1, V2); > + // ((~B&A)|(B&~A)) -> A^B > + if ((match(A, m_Not(m_Value(V1))) && > + match(D, m_Not(m_Value(V2))))) > + if (V1 == B && V2 == C) > + return BinaryOperator::CreateXor(V1, V2); > } Please use m_Specific instead of two stage matching where possible. -Chris From clattner at apple.com Sun Nov 30 23:19:45 2008 From: clattner at apple.com (Chris Lattner) Date: Sun, 30 Nov 2008 21:19:45 -0800 Subject: [llvm-commits] [llvm] r60312 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and-or.ll In-Reply-To: <200812010107.mB117BFE000445@zion.cs.uiuc.edu> References: <200812010107.mB117BFE000445@zion.cs.uiuc.edu> Message-ID: <281BB764-A42D-4365-8464-0A1D84EB3E1A@apple.com> On Nov 30, 2008, at 5:07 PM, Bill Wendling wrote: > Author: void > Date: Sun Nov 30 19:07:11 2008 > New Revision: 60312 > > URL: http://llvm.org/viewvc/llvm-project?rev=60312&view=rev > Log: > Implement ((A|B)&1)|(B&-2) -> (A&1) | B transformation. This also > takes care of > permutations of this pattern. Hi Bill, > @@ -4649,6 +4649,73 @@ > } > } > > + // ((A|B)&1)|(B&-2) -> (A&1) | B > + if (match(Op0, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || > + match(Op0, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { This much code should be split out into a helper function. Please do something like: > + if (match(Op0, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || > + match(Op0, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) HandleBlah(....) > + // (B&-2)|((A|B)&1) -> (A&1) | B > + if (match(Op1, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || > + match(Op1, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { HandleBlah(....) so that the code is shared, not copied and pasted. Also, I don't think that this pattern has anything to do with the magic constants 1 and -2. Please generalize it. -Chris