From sabre at nondot.org Mon Dec 20 01:38:24 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 07:38:24 -0000 Subject: [llvm-commits] [llvm] r122232 - /llvm/trunk/test/Transforms/Inline/byval.ll Message-ID: <20101220073824.EC3FC2A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 01:38:24 2010 New Revision: 122232 URL: http://llvm.org/viewvc/llvm-project?rev=122232&view=rev Log: filecheckize Modified: llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=122232&r1=122231&r2=122232&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval.ll Mon Dec 20 01:38:24 2010 @@ -1,4 +1,4 @@ -; RUN: opt < %s -inline -S | grep {llvm.memcpy} +; RUN: opt < %s -inline -S | FileCheck %s ; Inlining a byval struct should cause an explicit copy into an alloca. @@ -16,7 +16,7 @@ declare i32 @printf(i8*, ...) nounwind -define i32 @main() nounwind { +define i32 @caller() nounwind { entry: %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] @@ -25,4 +25,7 @@ store i64 2, i64* %tmp4, align 4 call void @f( %struct.ss* byval %S ) nounwind ret i32 0 +; CHECK: @caller() +; CHECK: %b = alloca %struct.ss +; CHECK: call void @llvm.memcpy } From sabre at nondot.org Mon Dec 20 01:39:57 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 07:39:57 -0000 Subject: [llvm-commits] [llvm] r122233 - in /llvm/trunk/test/Transforms/Inline: byval.ll byval2.ll Message-ID: <20101220073957.AD9D82A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 01:39:57 2010 New Revision: 122233 URL: http://llvm.org/viewvc/llvm-project?rev=122233&view=rev Log: merge two tests. Removed: llvm/trunk/test/Transforms/Inline/byval2.ll Modified: llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=122233&r1=122232&r2=122233&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval.ll Mon Dec 20 01:39:57 2010 @@ -16,7 +16,7 @@ declare i32 @printf(i8*, ...) nounwind -define i32 @caller() nounwind { +define i32 @test1() nounwind { entry: %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] @@ -25,7 +25,34 @@ store i64 2, i64* %tmp4, align 4 call void @f( %struct.ss* byval %S ) nounwind ret i32 0 -; CHECK: @caller() +; CHECK: @test1() ; CHECK: %b = alloca %struct.ss ; CHECK: call void @llvm.memcpy +; CHECK: ret i32 0 +} + +; Inlining a byval struct should NOT cause an explicit copy +; into an alloca if the function is readonly + +define internal i32 @f2(%struct.ss* byval %b) nounwind readonly { +entry: + %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; [#uses=2] + %tmp1 = load i32* %tmp, align 4 ; [#uses=1] + %tmp2 = add i32 %tmp1, 1 ; [#uses=1] + ret i32 %tmp2 +} + +define i32 @test2() nounwind { +entry: + %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] + %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] + store i32 1, i32* %tmp1, align 8 + %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; [#uses=1] + store i64 2, i64* %tmp4, align 4 + %X = call i32 @f2( %struct.ss* byval %S ) nounwind + ret i32 %X +; CHECK: @test2() +; CHECK: %S = alloca %struct.ss +; CHECK-NOT: call void @llvm.memcpy +; CHECK: ret i32 } Removed: llvm/trunk/test/Transforms/Inline/byval2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval2.ll?rev=122232&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval2.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval2.ll (removed) @@ -1,28 +0,0 @@ -; RUN: opt < %s -inline -S | not grep {llvm.memcpy} - -; Inlining a byval struct should NOT cause an explicit copy -; into an alloca if the function is readonly - - %struct.ss = type { i32, i64 } - at .str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1] - -define internal i32 @f(%struct.ss* byval %b) nounwind readonly { -entry: - %tmp = getelementptr %struct.ss* %b, i32 0, i32 0 ; [#uses=2] - %tmp1 = load i32* %tmp, align 4 ; [#uses=1] - %tmp2 = add i32 %tmp1, 1 ; [#uses=1] - ret i32 %tmp2 -} - -declare i32 @printf(i8*, ...) nounwind - -define i32 @main() nounwind { -entry: - %S = alloca %struct.ss ; <%struct.ss*> [#uses=4] - %tmp1 = getelementptr %struct.ss* %S, i32 0, i32 0 ; [#uses=1] - store i32 1, i32* %tmp1, align 8 - %tmp4 = getelementptr %struct.ss* %S, i32 0, i32 1 ; [#uses=1] - store i64 2, i64* %tmp4, align 4 - %X = call i32 @f( %struct.ss* byval %S ) nounwind - ret i32 %X -} From sabre at nondot.org Mon Dec 20 01:45:28 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 07:45:28 -0000 Subject: [llvm-commits] [llvm] r122234 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll Message-ID: <20101220074528.DCD1E2A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 01:45:28 2010 New Revision: 122234 URL: http://llvm.org/viewvc/llvm-project?rev=122234&view=rev Log: fix PR8769, a miscompilation by inliner when inlining a function with a byval argument. The generated alloca has to have at least the alignment of the byval, if not, the client may be making assumptions that the new alloca won't satisfy. Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=122234&r1=122233&r2=122234&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Dec 20 01:45:28 2010 @@ -252,7 +252,6 @@ CalledFunc->isDeclaration() || // call, or call to a vararg function! CalledFunc->getFunctionType()->isVarArg()) return false; - // If the call to the callee is not a tail call, we must clear the 'tail' // flags on any calls that we inline. bool MustClearTailCallFlags = @@ -308,14 +307,19 @@ if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal) && !CalledFunc->onlyReadsMemory()) { const Type *AggTy = cast(I->getType())->getElementType(); - const Type *VoidPtrTy = - Type::getInt8PtrTy(Context); + const Type *VoidPtrTy = Type::getInt8PtrTy(Context); // Create the alloca. If we have TargetData, use nice alignment. unsigned Align = 1; - if (IFI.TD) Align = IFI.TD->getPrefTypeAlignment(AggTy); - Value *NewAlloca = new AllocaInst(AggTy, 0, Align, - I->getName(), + if (IFI.TD) + Align = IFI.TD->getPrefTypeAlignment(AggTy); + + // If the byval had an alignment specified, we *must* use at least that + // alignment, as it is required by the byval argument (and uses of the + // pointer inside the callee). + Align = std::max(Align, CalledFunc->getParamAlignment(ArgNo+1)); + + Value *NewAlloca = new AllocaInst(AggTy, 0, Align, I->getName(), &*Caller->begin()->begin()); // Emit a memcpy. const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)}; Modified: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=122234&r1=122233&r2=122234&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval.ll Mon Dec 20 01:45:28 2010 @@ -56,3 +56,27 @@ ; CHECK-NOT: call void @llvm.memcpy ; CHECK: ret i32 } + + +; Inlining a byval with an explicit alignment needs to use *at least* that +; alignment on the generated alloca. +; PR8769 +declare void @g3(%struct.ss* %p) + +define internal void @f3(%struct.ss* byval align 64 %b) nounwind { + call void @g3(%struct.ss* %b) ;; Could make alignment assumptions! + ret void +} + +define void @test3() nounwind { +entry: + %S = alloca %struct.ss, align 1 ;; May not be aligned. + call void @f3( %struct.ss* byval align 64 %S) nounwind + ret void +; CHECK: @test3() +; CHECK: %b = alloca %struct.ss, align 64 +; CHECK: %S = alloca %struct.ss +; CHECK: call void @llvm.memcpy +; CHECK: call void @g3(%struct.ss* %b) +; CHECK: ret void +} From sabre at nondot.org Mon Dec 20 01:57:41 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 07:57:41 -0000 Subject: [llvm-commits] [llvm] r122235 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll Message-ID: <20101220075742.087C42A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 01:57:41 2010 New Revision: 122235 URL: http://llvm.org/viewvc/llvm-project?rev=122235&view=rev Log: pull byval processing out to its own helper function. Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=122235&r1=122234&r2=122235&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Dec 20 01:57:41 2010 @@ -229,6 +229,71 @@ CallerNode->removeCallEdgeFor(CS); } +static Value *HandleByValArgument(Value *Arg, Instruction *TheCall, + const Function *CalledFunc, + InlineFunctionInfo &IFI, + unsigned ByValAlignment) { + if (CalledFunc->onlyReadsMemory()) + return Arg; + + LLVMContext &Context = Arg->getContext(); + + + const Type *AggTy = cast(Arg->getType())->getElementType(); + const Type *VoidPtrTy = Type::getInt8PtrTy(Context); + + // Create the alloca. If we have TargetData, use nice alignment. + unsigned Align = 1; + if (IFI.TD) + Align = IFI.TD->getPrefTypeAlignment(AggTy); + + // If the byval had an alignment specified, we *must* use at least that + // alignment, as it is required by the byval argument (and uses of the + // pointer inside the callee). + Align = std::max(Align, ByValAlignment); + + Function *Caller = TheCall->getParent()->getParent(); + + Value *NewAlloca = new AllocaInst(AggTy, 0, Align, Arg->getName(), + &*Caller->begin()->begin()); + // Emit a memcpy. + const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)}; + Function *MemCpyFn = Intrinsic::getDeclaration(Caller->getParent(), + Intrinsic::memcpy, + Tys, 3); + Value *DestCast = new BitCastInst(NewAlloca, VoidPtrTy, "tmp", TheCall); + Value *SrcCast = new BitCastInst(Arg, VoidPtrTy, "tmp", TheCall); + + Value *Size; + if (IFI.TD == 0) + Size = ConstantExpr::getSizeOf(AggTy); + else + Size = ConstantInt::get(Type::getInt64Ty(Context), + IFI.TD->getTypeStoreSize(AggTy)); + + // Always generate a memcpy of alignment 1 here because we don't know + // the alignment of the src pointer. Other optimizations can infer + // better alignment. + Value *CallArgs[] = { + DestCast, SrcCast, Size, + ConstantInt::get(Type::getInt32Ty(Context), 1), + ConstantInt::getFalse(Context) // isVolatile + }; + CallInst *TheMemCpy = + CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall); + + // If we have a call graph, update it. + if (CallGraph *CG = IFI.CG) { + CallGraphNode *MemCpyCGN = CG->getOrInsertFunction(MemCpyFn); + CallGraphNode *CallerNode = (*CG)[Caller]; + CallerNode->addCalledFunction(TheMemCpy, MemCpyCGN); + } + + // Uses of the argument in the function should use our new alloca + // instead. + return NewAlloca; +} + // InlineFunction - This function inlines the called function into the basic // block of the caller. This returns false if it is not possible to inline this // call. The program is still in a well defined state if this occurs though. @@ -304,63 +369,14 @@ // by them explicit. However, we don't do this if the callee is readonly // or readnone, because the copy would be unneeded: the callee doesn't // modify the struct. - if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal) && - !CalledFunc->onlyReadsMemory()) { - const Type *AggTy = cast(I->getType())->getElementType(); - const Type *VoidPtrTy = Type::getInt8PtrTy(Context); - - // Create the alloca. If we have TargetData, use nice alignment. - unsigned Align = 1; - if (IFI.TD) - Align = IFI.TD->getPrefTypeAlignment(AggTy); - - // If the byval had an alignment specified, we *must* use at least that - // alignment, as it is required by the byval argument (and uses of the - // pointer inside the callee). - Align = std::max(Align, CalledFunc->getParamAlignment(ArgNo+1)); - - Value *NewAlloca = new AllocaInst(AggTy, 0, Align, I->getName(), - &*Caller->begin()->begin()); - // Emit a memcpy. - const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)}; - Function *MemCpyFn = Intrinsic::getDeclaration(Caller->getParent(), - Intrinsic::memcpy, - Tys, 3); - Value *DestCast = new BitCastInst(NewAlloca, VoidPtrTy, "tmp", TheCall); - Value *SrcCast = new BitCastInst(*AI, VoidPtrTy, "tmp", TheCall); - - Value *Size; - if (IFI.TD == 0) - Size = ConstantExpr::getSizeOf(AggTy); - else - Size = ConstantInt::get(Type::getInt64Ty(Context), - IFI.TD->getTypeStoreSize(AggTy)); - - // Always generate a memcpy of alignment 1 here because we don't know - // the alignment of the src pointer. Other optimizations can infer - // better alignment. - Value *CallArgs[] = { - DestCast, SrcCast, Size, - ConstantInt::get(Type::getInt32Ty(Context), 1), - ConstantInt::getFalse(Context) // isVolatile - }; - CallInst *TheMemCpy = - CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall); - - // If we have a call graph, update it. - if (CallGraph *CG = IFI.CG) { - CallGraphNode *MemCpyCGN = CG->getOrInsertFunction(MemCpyFn); - CallGraphNode *CallerNode = (*CG)[Caller]; - CallerNode->addCalledFunction(TheMemCpy, MemCpyCGN); - } - - // Uses of the argument in the function should use our new alloca - // instead. - ActualArg = NewAlloca; - + if (CalledFunc->paramHasAttr(ArgNo+1, Attribute::ByVal)) { + ActualArg = HandleByValArgument(ActualArg, TheCall, CalledFunc, IFI, + CalledFunc->getParamAlignment(ArgNo+1)); + // Calls that we inline may use the new alloca, so we need to clear - // their 'tail' flags. - MustClearTailCallFlags = true; + // their 'tail' flags if HandleByValArgument introduced a new alloca and + // the callee has calls. + MustClearTailCallFlags |= ActualArg != *AI; } VMap[I] = ActualArg; Modified: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=122235&r1=122234&r2=122235&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval.ll Mon Dec 20 01:57:41 2010 @@ -26,7 +26,8 @@ call void @f( %struct.ss* byval %S ) nounwind ret i32 0 ; CHECK: @test1() -; CHECK: %b = alloca %struct.ss +; CHECK: %S1 = alloca %struct.ss +; CHECK: %S = alloca %struct.ss ; CHECK: call void @llvm.memcpy ; CHECK: ret i32 0 } @@ -74,9 +75,9 @@ call void @f3( %struct.ss* byval align 64 %S) nounwind ret void ; CHECK: @test3() -; CHECK: %b = alloca %struct.ss, align 64 +; CHECK: %S1 = alloca %struct.ss, align 64 ; CHECK: %S = alloca %struct.ss ; CHECK: call void @llvm.memcpy -; CHECK: call void @g3(%struct.ss* %b) +; CHECK: call void @g3(%struct.ss* %S1) ; CHECK: ret void } From sabre at nondot.org Mon Dec 20 02:10:40 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 08:10:40 -0000 Subject: [llvm-commits] [llvm] r122236 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll Message-ID: <20101220081040.8A5EF2A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 02:10:40 2010 New Revision: 122236 URL: http://llvm.org/viewvc/llvm-project?rev=122236&view=rev Log: when eliding a byval copy due to inlining a readonly function, we have to make sure that the reused alloca has sufficient alignment. Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/test/Transforms/Inline/byval.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=122236&r1=122235&r2=122236&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Dec 20 02:10:40 2010 @@ -229,17 +229,56 @@ CallerNode->removeCallEdgeFor(CS); } +/// HandleByValArgument - When inlining a call site that has a byval argument, +/// we have to make the implicit memcpy explicit by adding it. static Value *HandleByValArgument(Value *Arg, Instruction *TheCall, const Function *CalledFunc, InlineFunctionInfo &IFI, unsigned ByValAlignment) { - if (CalledFunc->onlyReadsMemory()) - return Arg; + const Type *AggTy = cast(Arg->getType())->getElementType(); + + // If the called function is readonly, then it could not mutate the caller's + // copy of the byval'd memory. In this case, it is safe to elide the copy and + // temporary. + if (CalledFunc->onlyReadsMemory()) { + // If the byval argument has a specified alignment that is greater than the + // passed in pointer, then we either have to round up the input pointer or + // give up on this transformation. + if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment. + return Arg; + + // See if the argument is a (bitcasted) pointer to an alloca. If so, we can + // round up the alloca if needed. + if (AllocaInst *AI = dyn_cast(Arg->stripPointerCasts())) { + unsigned AIAlign = AI->getAlignment(); + + // If the alloca is known at least aligned as much as the byval, we can do + // this optimization. + if (AIAlign >= ByValAlignment) + return Arg; + + // If the alloca has a specified alignment that is less than the byval, + // then we can safely bump it up. + if (AIAlign) { + AI->setAlignment(ByValAlignment); + return Arg; + } + + // If the alignment has an unspecified alignment, then we can only modify + // it if we have TD information. Doing so without TD info could end up + // with us rounding the alignment *down* accidentally, which is badness. + if (IFI.TD) { + AIAlign = std::max(ByValAlignment, IFI.TD->getPrefTypeAlignment(AggTy)); + AI->setAlignment(AIAlign); + return Arg; + } + } + + // Otherwise, we have to make a memcpy to get a safe alignment, pretty lame. + } LLVMContext &Context = Arg->getContext(); - - const Type *AggTy = cast(Arg->getType())->getElementType(); const Type *VoidPtrTy = Type::getInt8PtrTy(Context); // Create the alloca. If we have TargetData, use nice alignment. Modified: llvm/trunk/test/Transforms/Inline/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/byval.ll?rev=122236&r1=122235&r2=122236&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/byval.ll (original) +++ llvm/trunk/test/Transforms/Inline/byval.ll Mon Dec 20 02:10:40 2010 @@ -81,3 +81,26 @@ ; CHECK: call void @g3(%struct.ss* %S1) ; CHECK: ret void } + + +; Inlining a byval struct should NOT cause an explicit copy +; into an alloca if the function is readonly, but should increase an alloca's +; alignment to satisfy an explicit alignment request. + +define internal i32 @f4(%struct.ss* byval align 64 %b) nounwind readonly { + call void @g3(%struct.ss* %b) + ret i32 4 +} + +define i32 @test4() nounwind { +entry: + %S = alloca %struct.ss, align 2 ; <%struct.ss*> [#uses=4] + %X = call i32 @f4( %struct.ss* byval align 64 %S ) nounwind + ret i32 %X +; CHECK: @test4() +; CHECK: %S = alloca %struct.ss, align 64 +; CHECK-NOT: call void @llvm.memcpy +; CHECK: call void @g3 +; CHECK: ret i32 4 +} + From sabre at nondot.org Mon Dec 20 02:25:06 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 08:25:06 -0000 Subject: [llvm-commits] [llvm] r122237 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Message-ID: <20101220082506.3646E2A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 02:25:06 2010 New Revision: 122237 URL: http://llvm.org/viewvc/llvm-project?rev=122237&view=rev Log: various cleanups for transformConstExprCastCall Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122237&r1=122236&r2=122237&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Dec 20 02:25:06 2010 @@ -852,11 +852,11 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { bool Changed = false; - // If the callee is a constexpr cast of a function, attempt to move the cast - // to the arguments of the call/invoke. - if (transformConstExprCastCall(CS)) return 0; - + // If the callee is a pointer to a function, attempt to move any casts to the + // arguments of the call/invoke. Value *Callee = CS.getCalledValue(); + if (!isa(Callee) && transformConstExprCastCall(CS)) + return 0; if (Function *CalleeF = dyn_cast(Callee)) // If the call and callee calling conventions don't match, this call must @@ -950,12 +950,10 @@ // attempt to move the cast to the arguments of the call/invoke. // bool InstCombiner::transformConstExprCastCall(CallSite CS) { - if (!isa(CS.getCalledValue())) return false; - ConstantExpr *CE = cast(CS.getCalledValue()); - if (CE->getOpcode() != Instruction::BitCast || - !isa(CE->getOperand(0))) + Function *Callee = + dyn_cast(CS.getCalledValue()->stripPointerCasts()); + if (Callee == 0) return false; - Function *Callee = cast(CE->getOperand(0)); Instruction *Caller = CS.getInstruction(); const AttrListPtr &CallerPAL = CS.getAttributes(); @@ -1142,8 +1140,8 @@ Value *NV = NC; if (OldRetTy != NV->getType() && !Caller->use_empty()) { if (!NV->getType()->isVoidTy()) { - Instruction::CastOps opcode = CastInst::getCastOpcode(NC, false, - OldRetTy, false); + Instruction::CastOps opcode = + CastInst::getCastOpcode(NC, false, OldRetTy, false); NV = NC = CastInst::Create(opcode, NC, OldRetTy, "tmp"); // If this is an invoke instruction, we should insert it after the first @@ -1152,7 +1150,7 @@ BasicBlock::iterator I = II->getNormalDest()->getFirstNonPHI(); InsertNewInstBefore(NC, *I); } else { - // Otherwise, it's a call, just insert cast right after the call instr + // Otherwise, it's a call, just insert cast right after the call. InsertNewInstBefore(NC, *Caller); } Worklist.AddUsersToWorkList(*Caller); @@ -1161,7 +1159,6 @@ } } - if (!Caller->use_empty()) Caller->replaceAllUsesWith(NV); From sabre at nondot.org Mon Dec 20 02:36:38 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Dec 2010 08:36:38 -0000 Subject: [llvm-commits] [llvm] r122238 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/crash.ll Message-ID: <20101220083639.0792A2A6C12D@llvm.org> Author: lattner Date: Mon Dec 20 02:36:38 2010 New Revision: 122238 URL: http://llvm.org/viewvc/llvm-project?rev=122238&view=rev Log: fix PR8807 by making transformConstExprCastCall aware of byval arguments. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/test/Transforms/InstCombine/crash.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=122238&r1=122237&r2=122238&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Dec 20 02:36:38 2010 @@ -1015,9 +1015,22 @@ if (!CastInst::isCastable(ActTy, ParamTy)) return false; // Cannot transform this parameter value. - if (CallerPAL.getParamAttributes(i + 1) - & Attribute::typeIncompatible(ParamTy)) + unsigned Attrs = CallerPAL.getParamAttributes(i + 1); + if (Attrs & Attribute::typeIncompatible(ParamTy)) return false; // Attribute not compatible with transformed value. + + // If the parameter is passed as a byval argument, then we have to have a + // sized type and the sized type has to have the same size as the old type. + if (ParamTy != ActTy && (Attrs & Attribute::ByVal)) { + const PointerType *ParamPTy = dyn_cast(ParamTy); + if (ParamPTy == 0 || !ParamPTy->getElementType()->isSized() || TD == 0) + return false; + + const Type *CurElTy = cast(ActTy)->getElementType(); + if (TD->getTypeAllocSize(CurElTy) != + TD->getTypeAllocSize(ParamPTy->getElementType())) + return false; + } // Converting from one pointer type to another or between a pointer and an // integer of the same size is safe even if we do not have a body. Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=122238&r1=122237&r2=122238&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/crash.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/crash.ll Mon Dec 20 02:36:38 2010 @@ -285,3 +285,16 @@ store i32 %19, i32* undef, align 8 unreachable } + + +; PR8807 +declare i32 @test14f(i8* (i8*)*) nounwind + +define void @test14() nounwind readnone { +entry: + %tmp = bitcast i32 (i8* (i8*)*)* @test14f to i32 (i32*)* + %call10 = call i32 %tmp(i32* byval undef) + ret void +} + + From baldrick at free.fr Mon Dec 20 03:13:28 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 10:13:28 +0100 Subject: [llvm-commits] [llvm] r122221 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp In-Reply-To: <20101220020539.C07D52A6C12C@llvm.org> References: <20101220020539.C07D52A6C12C@llvm.org> Message-ID: <4D0F1E38.9070607@free.fr> Hi Chris, > --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Sun Dec 19 20:05:39 2010 > @@ -548,6 +548,54 @@ > return Res; > } > > + > +SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) { > + // Promote the overflow bit trivially. > + if (ResNo == 1) > + return PromoteIntRes_Overflow(N); > + > + SDValue LHS = N->getOperand(0), RHS = N->getOperand(1); > + DebugLoc DL = N->getDebugLoc(); > + unsigned SmallSize = LHS.getValueType().getSizeInBits(); > + > + // To determine if the result overflowed in a larger type, we extend the input > + // to the larger type, do the multiply, then check the high bits of the result > + // to see if the overflow happened. > + if (N->getOpcode() == ISD::SMULO) { > + LHS = SExtPromotedInteger(LHS); > + RHS = SExtPromotedInteger(RHS); > + } else { > + LHS = ZExtPromotedInteger(LHS); > + RHS = ZExtPromotedInteger(RHS); > + } > + > + SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS); > + > + > + // For an unsigned overflow, we check to see if the high part is != 0; > + SDValue Overflow; > + if (N->getOpcode() == ISD::UMULO) { > + SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul, > + DAG.getIntPtrConstant(SmallSize)); > + // Overflowed if and only if this is not equal to Res. ^ Should say "is not equal to zero." > + Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi, > + DAG.getConstant(0, Hi.getValueType()), ISD::SETNE); > + } else { > + // Signed multiply overflowed if the high part is not 0 and not -1. Actually it overflows iff the high part does not sign extend the low part (just as in the unsigned case the high part should zero extend the low part), which is not exactly the same thing. Eg: a signed i8 multiply of 64 by 2 overflows, but the high part is zero. Eg: a signed i8 multiple of -128 by 2 overflows, but the high part is all ones. Ciao, Duncan. > + SDValue Hi = DAG.getNode(ISD::SRA, DL, Mul.getValueType(), Mul, > + DAG.getIntPtrConstant(SmallSize)); > + Hi = DAG.getNode(ISD::ADD, DL, Hi.getValueType(), Hi, > + DAG.getConstant(1, Hi.getValueType())); > + Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi, > + DAG.getConstant(1, Hi.getValueType()), ISD::SETUGT); > + } > + > + // Use the calculated overflow everywhere. > + ReplaceValueWith(SDValue(N, 1), Overflow); > + return Mul; > +} > + > + > SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { > // Zero extend the input. > SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); > @@ -601,11 +649,6 @@ > return Res; > } > > -SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) { > - assert(ResNo == 1&& "Only boolean result promotion currently supported!"); > - return PromoteIntRes_Overflow(N); > -} > - > //===----------------------------------------------------------------------===// > // Integer Operand Promotion > //===----------------------------------------------------------------------===// > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ofv at wanadoo.es Mon Dec 20 03:47:08 2010 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 20 Dec 2010 09:47:08 -0000 Subject: [llvm-commits] [llvm] r122239 - /llvm/trunk/cmake/modules/LLVMLibDeps.cmake Message-ID: <20101220094708.45BB22A6C12C@llvm.org> Author: ofv Date: Mon Dec 20 03:47:08 2010 New Revision: 122239 URL: http://llvm.org/viewvc/llvm-project?rev=122239&view=rev Log: Update cmake library dependencies. Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=122239&r1=122238&r2=122239&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Mon Dec 20 03:47:08 2010 @@ -48,7 +48,7 @@ set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCAsmPrinter LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcInfo LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMSupport ) From ofv at wanadoo.es Mon Dec 20 03:47:13 2010 From: ofv at wanadoo.es (Oscar Fuentes) Date: Mon, 20 Dec 2010 09:47:13 -0000 Subject: [llvm-commits] [llvm] r122240 - in /llvm/trunk: CMakeLists.txt docs/CMake.html Message-ID: <20101220094713.9A9652A6C12D@llvm.org> Author: ofv Date: Mon Dec 20 03:47:13 2010 New Revision: 122240 URL: http://llvm.org/viewvc/llvm-project?rev=122240&view=rev Log: New cmake option LLVM_APPEND_VC_REV for controlling when the VC revision id is appended to the LLVM version string. Defaults to OFF. Until now the VC revision id was always appended to the revision string whenever cmake was invoked (either explicitly or implicitly because a cmake source file changed). This was causing massive recompilations because config.h are reconfigured with the new contents of PACKAGE_VERSION. Modified: llvm/trunk/CMakeLists.txt llvm/trunk/docs/CMake.html Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=122240&r1=122239&r2=122240&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Mon Dec 20 03:47:13 2010 @@ -11,8 +11,15 @@ ) set(PACKAGE_VERSION "2.9") + include(VersionFromVCS) -add_version_info_from_vcs(PACKAGE_VERSION) + +option(LLVM_APPEND_VC_REV + "Append the version control system revision id to LLVM version" OFF) + +if( LLVM_APPEND_VC_REV ) + add_version_info_from_vcs(PACKAGE_VERSION) +endif() set(PACKAGE_NAME llvm) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") Modified: llvm/trunk/docs/CMake.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CMake.html?rev=122240&r1=122239&r2=122240&view=diff ============================================================================== --- llvm/trunk/docs/CMake.html (original) +++ llvm/trunk/docs/CMake.html Mon Dec 20 03:47:13 2010 @@ -286,6 +286,12 @@ ON. You can use that option for disabling the generation of build targets for the LLVM unit tests. +
LLVM_APPEND_VC_REV:BOOL
+
Append version control revision info (svn revision number or git + revision id) to LLVM version string (stored in the PACKAGE_VERSION + macro). For this to work cmake must be invoked before the + build. Defaults to OFF.
+
LLVM_ENABLE_THREADS:BOOL
Build with threads support, if available. Defaults to ON.
From baldrick at free.fr Mon Dec 20 04:57:01 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 10:57:01 -0000 Subject: [llvm-commits] [llvm] r122241 - /llvm/trunk/include/llvm/GlobalValue.h Message-ID: <20101220105701.7E9CB2A6C12C@llvm.org> Author: baldrick Date: Mon Dec 20 04:57:01 2010 New Revision: 122241 URL: http://llvm.org/viewvc/llvm-project?rev=122241&view=rev Log: Discourage people from using isWeakForLinker when they should be using mayBeOverridden. Modified: llvm/trunk/include/llvm/GlobalValue.h Modified: llvm/trunk/include/llvm/GlobalValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=122241&r1=122240&r2=122241&view=diff ============================================================================== --- llvm/trunk/include/llvm/GlobalValue.h (original) +++ llvm/trunk/include/llvm/GlobalValue.h Mon Dec 20 04:57:01 2010 @@ -173,7 +173,9 @@ } /// isWeakForLinker - Whether the definition of this global may be replaced at - /// link time. + /// link time. NB: Using this method outside of the code generators is almost + /// always a mistake: when working at the IR level use mayBeOverridden instead + /// as it knows about ODR semantics. static bool isWeakForLinker(LinkageTypes Linkage) { return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage || From fvbommel at gmail.com Mon Dec 20 05:33:43 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 20 Dec 2010 12:33:43 +0100 Subject: [llvm-commits] [llvm] r122236 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll In-Reply-To: <20101220081040.8A5EF2A6C12C@llvm.org> References: <20101220081040.8A5EF2A6C12C@llvm.org> Message-ID: On Mon, Dec 20, 2010 at 9:10 AM, Chris Lattner wrote: > + ? ?// See if the argument is a (bitcasted) pointer to an alloca. ?If so, we can > + ? ?// round up the alloca if needed. > + ? ?if (AllocaInst *AI = dyn_cast(Arg->stripPointerCasts())) { > + ? ? ?unsigned AIAlign = AI->getAlignment(); > + > + ? ? ?// If the alloca is known at least aligned as much as the byval, we can do > + ? ? ?// this optimization. > + ? ? ?if (AIAlign >= ByValAlignment) > + ? ? ? ?return Arg; > + > + ? ? ?// If the alloca has a specified alignment that is less than the byval, > + ? ? ?// then we can safely bump it up. > + ? ? ?if (AIAlign) { > + ? ? ? ?AI->setAlignment(ByValAlignment); > + ? ? ? ?return Arg; > + ? ? ?} > + > + ? ? ?// If the alignment has an unspecified alignment, then we can only modify > + ? ? ?// it if we have TD information. ?Doing so without TD info could end up > + ? ? ?// with us rounding the alignment *down* accidentally, which is badness. > + ? ? ?if (IFI.TD) { > + ? ? ? ?AIAlign = std::max(ByValAlignment, IFI.TD->getPrefTypeAlignment(AggTy)); > + ? ? ? ?AI->setAlignment(AIAlign); > + ? ? ? ?return Arg; > + ? ? ?} > + ? ?} -instcombine has a method that does much the same thing, except more aggressively, in InstCombineCalls.cpp (InstCombiner::GetOrEnforceKnownAlignment()). Maybe this should be factored out and placed somewhere in Transforms/Util/ so it can be used here too? Then you could replace the quoted code with: if (GetOrEnforceKnownAlignment(Arg, ByValAlignment) >= ByValAlignment) return Arg; From fvbommel at gmail.com Mon Dec 20 05:35:23 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 20 Dec 2010 12:35:23 +0100 Subject: [llvm-commits] [llvm] r122236 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/byval.ll In-Reply-To: References: <20101220081040.8A5EF2A6C12C@llvm.org> Message-ID: On Mon, Dec 20, 2010 at 12:33 PM, Frits van Bommel wrote: > Then you could replace the quoted code with: > ?if (GetOrEnforceKnownAlignment(Arg, ByValAlignment) >= ByValAlignment) > ? ?return Arg; Of course, it'd need an extra TD argument then, so it'd be more like if (GetOrEnforceKnownAlignment(Arg, ByValAlignment, IFI.TD) >= ByValAlignment) return Arg; From baldrick at free.fr Mon Dec 20 07:10:24 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 13:10:24 -0000 Subject: [llvm-commits] [llvm] r122242 - in /llvm/trunk: include/llvm/Instruction.h lib/VMCore/ConstantFold.cpp lib/VMCore/Instruction.cpp Message-ID: <20101220131024.168FE2A6C12C@llvm.org> Author: baldrick Date: Mon Dec 20 07:10:23 2010 New Revision: 122242 URL: http://llvm.org/viewvc/llvm-project?rev=122242&view=rev Log: There is no need for isAssociative to take the type as an argument anymore. Modified: llvm/trunk/include/llvm/Instruction.h llvm/trunk/lib/VMCore/ConstantFold.cpp 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=122242&r1=122241&r2=122242&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Mon Dec 20 07:10:23 2010 @@ -200,11 +200,10 @@ /// /// Associative operators satisfy: x op (y op z) === (x op y) op z /// - /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative, when - /// not applied to floating point types. + /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// - bool isAssociative() const { return isAssociative(getOpcode(), getType()); } - static bool isAssociative(unsigned op, const Type *Ty); + bool isAssociative() const { return isAssociative(getOpcode()); } + static bool isAssociative(unsigned op); /// isCommutative - Return true if the instruction is commutative: /// Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=122242&r1=122241&r2=122242&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Mon Dec 20 07:10:23 2010 @@ -1338,8 +1338,7 @@ // Given ((a + b) + c), if (b + c) folds to something interesting, return // (a + (b + c)). - if (Instruction::isAssociative(Opcode, C1->getType()) && - CE1->getOpcode() == Opcode) { + if (Instruction::isAssociative(Opcode) && CE1->getOpcode() == Opcode) { Constant *T = ConstantExpr::get(Opcode, CE1->getOperand(1), C2); if (!isa(T) || cast(T)->getOpcode() != Opcode) return ConstantExpr::get(Opcode, CE1->getOperand(0), T); Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=122242&r1=122241&r2=122242&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Mon Dec 20 07:10:23 2010 @@ -348,7 +348,7 @@ /// /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// -bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) { +bool Instruction::isAssociative(unsigned Opcode) { return Opcode == And || Opcode == Or || Opcode == Xor || Opcode == Add || Opcode == Mul; } From bigcheesegs at gmail.com Mon Dec 20 07:30:28 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 20 Dec 2010 13:30:28 -0000 Subject: [llvm-commits] [llvm] r122243 - /llvm/trunk/lib/Support/PathV2.cpp Message-ID: <20101220133028.A767B2A6C12C@llvm.org> Author: mspencer Date: Mon Dec 20 07:30:28 2010 New Revision: 122243 URL: http://llvm.org/viewvc/llvm-project?rev=122243&view=rev Log: Support/PathV2: Add missing has_relative_path impl. Modified: llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=122243&r1=122242&r2=122243&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Mon Dec 20 07:30:28 2010 @@ -502,6 +502,13 @@ return !root_path(p).empty(); } +bool has_relative_path(const Twine &path) { + SmallString<128> path_storage; + StringRef p = path.toStringRef(path_storage); + + return !relative_path(p).empty(); +} + bool has_filename(const Twine &path) { SmallString<128> path_storage; StringRef p = path.toStringRef(path_storage); From bigcheesegs at gmail.com Mon Dec 20 07:30:37 2010 From: bigcheesegs at gmail.com (Michael J. Spencer) Date: Mon, 20 Dec 2010 13:30:37 -0000 Subject: [llvm-commits] [llvm] r122244 - /llvm/trunk/include/llvm/Support/PathV1.h Message-ID: <20101220133037.951CA2A6C12C@llvm.org> Author: mspencer Date: Mon Dec 20 07:30:37 2010 New Revision: 122244 URL: http://llvm.org/viewvc/llvm-project?rev=122244&view=rev Log: Fix spelling. Modified: llvm/trunk/include/llvm/Support/PathV1.h Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122244&r1=122243&r2=122244&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Mon Dec 20 07:30:37 2010 @@ -106,7 +106,7 @@ /// cannot be created, the function will throw an exception. /// @returns an invalid path (empty) on error /// @param ErrMsg Optional place for an error message if an error occurs - /// @brief Constrct a path to an new, unique, existing temporary + /// @brief Construct a path to an new, unique, existing temporary /// directory. static Path GetTemporaryDirectory(std::string* ErrMsg = 0); @@ -260,7 +260,7 @@ bool isEmpty() const { return path.empty(); } /// This function returns the last component of the path name. The last - /// component is the file or directory name occuring after the last + /// component is the file or directory name occurring after the last /// directory separator. If no directory separator is present, the entire /// path name is returned (i.e. same as toString). /// @returns StringRef containing the last component of the path name. From baldrick at free.fr Mon Dec 20 08:47:04 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 14:47:04 -0000 Subject: [llvm-commits] [llvm] r122245 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstCombine/2010-11-01-lshr-mask.ll Message-ID: <20101220144704.6069F2A6C12C@llvm.org> Author: baldrick Date: Mon Dec 20 08:47:04 2010 New Revision: 122245 URL: http://llvm.org/viewvc/llvm-project?rev=122245&view=rev Log: Have SimplifyBinOp dispatch Xor, Add and Sub to the corresponding methods (they had just been forgotten before). Adding Xor causes "main" in the existing testcase 2010-11-01-lshr-mask.ll to be hugely more simplified. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122245&r1=122244&r2=122245&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Dec 20 08:47:04 2010 @@ -11,7 +11,9 @@ // that do not require creating new instructions. This does constant folding // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either // returning a constant ("and i32 %x, 0" -> "0") or an already existing value -// ("and i32 %x, %x" -> "%x"). +// ("and i32 %x, %x" -> "%x"). All operands are assumed to have already been +// simplified: This is usually true and assuming it simplifies the logic (if +// they have not been simplified then results are correct but maybe suboptimal). // //===----------------------------------------------------------------------===// @@ -229,8 +231,9 @@ /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. -Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const TargetData *TD, const DominatorTree *) { +static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) { if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -252,6 +255,7 @@ // X + (Y - X) -> Y // (Y - X) + X -> Y + // Eg: X + -X -> 0 Value *Y = 0; if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) || match(Op0, m_Sub(m_Value(Y), m_Specific(Op1)))) @@ -274,10 +278,16 @@ return 0; } +Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit); +} + /// SimplifySubInst - Given operands for a Sub, see if we can /// fold the result. If not, this returns null. -Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const TargetData *TD, const DominatorTree *) { +static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *, + unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -317,6 +327,11 @@ return 0; } +Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit); +} + /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, @@ -826,6 +841,13 @@ switch (Opcode) { case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse); case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Xor: return SimplifyXorInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Add: return SimplifyAddInst(LHS, RHS, /* isNSW */ false, + /* isNUW */ false, TD, DT, + MaxRecurse); + case Instruction::Sub: return SimplifySubInst(LHS, RHS, /* isNSW */ false, + /* isNUW */ false, TD, DT, + MaxRecurse); default: if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) { Modified: llvm/trunk/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll?rev=122245&r1=122244&r2=122245&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll Mon Dec 20 08:47:04 2010 @@ -5,14 +5,16 @@ define i32 @main(i32 %argc) nounwind ssp { entry: %tmp3151 = trunc i32 %argc to i8 +; CHECK: %tmp3162 = shl i8 %tmp3151, 5 +; CHECK: and i8 %tmp3162, 64 +; CHECK-NOT: shl +; CHECK-NOT: shr %tmp3161 = or i8 %tmp3151, -17 %tmp3162 = and i8 %tmp3151, 122 %tmp3163 = xor i8 %tmp3162, -17 %tmp4114 = shl i8 %tmp3163, 6 %tmp4115 = xor i8 %tmp4114, %tmp3163 %tmp4120 = xor i8 %tmp3161, %tmp4115 -; CHECK: lshr i8 %tmp4115, 1 -; CHECK-NOT: shl i8 %tmp4126, 6 %tmp4126 = lshr i8 %tmp4120, 7 %tmp4127 = mul i8 %tmp4126, 64 %tmp4086 = zext i8 %tmp4127 to i32 From daniel at zuster.org Mon Dec 20 09:07:39 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 20 Dec 2010 15:07:39 -0000 Subject: [llvm-commits] [llvm] r122246 - in /llvm/trunk/lib/Target/X86: CMakeLists.txt X86.h X86AsmBackend.cpp X86MachObjectWriter.cpp Message-ID: <20101220150739.8C3222A6C12C@llvm.org> Author: ddunbar Date: Mon Dec 20 09:07:39 2010 New Revision: 122246 URL: http://llvm.org/viewvc/llvm-project?rev=122246&view=rev Log: X86/MC/Mach-O: Split out createX86MachObjectWriter(). Added: llvm/trunk/lib/Target/X86/X86MachObjectWriter.cpp Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt llvm/trunk/lib/Target/X86/X86.h llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/lib/Target/X86/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/CMakeLists.txt?rev=122246&r1=122245&r2=122246&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/X86/CMakeLists.txt Mon Dec 20 09:07:39 2010 @@ -29,6 +29,7 @@ X86ISelLowering.cpp X86InstrInfo.cpp X86JITInfo.cpp + X86MachObjectWriter.cpp X86MCAsmInfo.cpp X86MCCodeEmitter.cpp X86MCInstLower.cpp Modified: llvm/trunk/lib/Target/X86/X86.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.h?rev=122246&r1=122245&r2=122246&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86.h (original) +++ llvm/trunk/lib/Target/X86/X86.h Mon Dec 20 09:07:39 2010 @@ -23,11 +23,13 @@ class JITCodeEmitter; class MCCodeEmitter; class MCContext; +class MCObjectWriter; class MachineCodeEmitter; class Target; class TargetAsmBackend; class X86TargetMachine; class formatted_raw_ostream; +class raw_ostream; /// createX86ISelDag - This pass converts a legalized DAG into a /// X86-specific DAG, ready for instruction scheduling. @@ -74,6 +76,13 @@ /// FunctionPass *createX86MaxStackAlignmentHeuristicPass(); + +/// createX86MachObjectWriter - Construct an X86 Mach-O object writer. +MCObjectWriter *createX86MachObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint32_t CPUType, + uint32_t CPUSubtype); + extern Target TheX86_32Target, TheX86_64Target; } // End llvm namespace Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=122246&r1=122245&r2=122246&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Mon Dec 20 09:07:39 2010 @@ -46,13 +46,6 @@ } namespace { -class X86MachObjectWriter : public MCMachObjectTargetWriter { -public: - X86MachObjectWriter(bool Is64Bit, uint32_t CPUType, - uint32_t CPUSubtype) - : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, - /*UseAggressiveSymbolFolding=*/Is64Bit) {} -}; class X86ELFObjectWriter : public MCELFObjectTargetWriter { public: @@ -357,11 +350,9 @@ : DarwinX86AsmBackend(T) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createMachObjectWriter(new X86MachObjectWriter( - /*Is64Bit=*/false, - object::mach::CTM_i386, - object::mach::CSX86_ALL), - OS, /*IsLittleEndian=*/true); + return createX86MachObjectWriter(OS, /*Is64Bit=*/false, + object::mach::CTM_i386, + object::mach::CSX86_ALL); } }; @@ -373,11 +364,9 @@ } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createMachObjectWriter(new X86MachObjectWriter( - /*Is64Bit=*/true, - object::mach::CTM_x86_64, - object::mach::CSX86_ALL), - OS, /*IsLittleEndian=*/true); + return createX86MachObjectWriter(OS, /*Is64Bit=*/true, + object::mach::CTM_x86_64, + object::mach::CSX86_ALL); } virtual bool doesSectionRequireSymbols(const MCSection &Section) const { Added: llvm/trunk/lib/Target/X86/X86MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachObjectWriter.cpp?rev=122246&view=auto ============================================================================== --- llvm/trunk/lib/Target/X86/X86MachObjectWriter.cpp (added) +++ llvm/trunk/lib/Target/X86/X86MachObjectWriter.cpp Mon Dec 20 09:07:39 2010 @@ -0,0 +1,32 @@ +//===-- X86MachObjectWriter.cpp - X86 Mach-O Writer -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "X86.h" +#include "llvm/MC/MCMachObjectWriter.h" +using namespace llvm; + +namespace { +class X86MachObjectWriter : public MCMachObjectTargetWriter { +public: + X86MachObjectWriter(bool Is64Bit, uint32_t CPUType, + uint32_t CPUSubtype) + : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, + /*UseAggressiveSymbolFolding=*/Is64Bit) {} +}; +} + +MCObjectWriter *llvm::createX86MachObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint32_t CPUType, + uint32_t CPUSubtype) { + return createMachObjectWriter(new X86MachObjectWriter(Is64Bit, + CPUType, + CPUSubtype), + OS, /*IsLittleEndian=*/true); +} From daniel at zuster.org Mon Dec 20 09:45:51 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 20 Dec 2010 15:45:51 -0000 Subject: [llvm-commits] [llvm] r122247 - /llvm/trunk/lib/Target/X86/X86.h Message-ID: <20101220154552.031CB2A6C12C@llvm.org> Author: ddunbar Date: Mon Dec 20 09:45:51 2010 New Revision: 122247 URL: http://llvm.org/viewvc/llvm-project?rev=122247&view=rev Log: Add header... Modified: llvm/trunk/lib/Target/X86/X86.h Modified: llvm/trunk/lib/Target/X86/X86.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.h?rev=122247&r1=122246&r2=122247&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86.h (original) +++ llvm/trunk/lib/Target/X86/X86.h Mon Dec 20 09:45:51 2010 @@ -15,6 +15,7 @@ #ifndef TARGET_X86_H #define TARGET_X86_H +#include "llvm/Support/DataTypes.h" #include "llvm/Target/TargetMachine.h" namespace llvm { From benny.kra at googlemail.com Mon Dec 20 10:18:51 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 20 Dec 2010 16:18:51 -0000 Subject: [llvm-commits] [llvm] r122248 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp test/Transforms/InstCombine/or.ll Message-ID: <20101220161851.67BB52A6C12C@llvm.org> Author: d0k Date: Mon Dec 20 10:18:51 2010 New Revision: 122248 URL: http://llvm.org/viewvc/llvm-project?rev=122248&view=rev Log: Teach InstCombine to merge (icmp ult (X + CA), C1) | (icmp eq X, C2) into (icmp ult (X + CA), C1 + 1) if C2 + CA == C1. InstCombine creates these so now we compile x == 23 || x == 24 || x == 25 to %x.off = add i32 %x, -23 %1 = icmp ult i32 %x.off, 3 instead of %x.off = add i32 %x, -23 %1 = icmp ult i32 %x.off, 2 %cmp3 = icmp eq i32 %x, 25 %ret2 = or i1 %1, %cmp3 Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/trunk/test/Transforms/InstCombine/or.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=122248&r1=122247&r2=122248&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon Dec 20 10:18:51 2010 @@ -1450,7 +1450,16 @@ return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } } - + + // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ult (X + CA), C1 + 1) + // iff C2 + CA == C1. + if (LHSCC == ICmpInst::ICMP_ULT) { + ConstantInt *AddCst; + if (match(Val, m_Add(m_Specific(Val2), m_ConstantInt(AddCst)))) + if (RHSCst->getValue() + AddCst->getValue() == LHSCst->getValue()) + return Builder->CreateICmp(LHSCC, Val, AddOne(LHSCst)); + } + // From here on, we only handle: // (icmp1 A, C1) | (icmp2 A, C2) --> something simpler. if (Val != Val2) return 0; Modified: llvm/trunk/test/Transforms/InstCombine/or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or.ll?rev=122248&r1=122247&r2=122248&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/or.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/or.ll Mon Dec 20 10:18:51 2010 @@ -376,3 +376,17 @@ ; CHECK-NEXT: or i32 %a, %b ; CHECK-NEXT: or i32 %1, 1135 } + +define i1 @test36(i32 %x) { + %cmp1 = icmp eq i32 %x, 23 + %cmp2 = icmp eq i32 %x, 24 + %ret1 = or i1 %cmp1, %cmp2 + %cmp3 = icmp eq i32 %x, 25 + %ret2 = or i1 %ret1, %cmp3 + ret i1 %ret2 +; CHECK: @test36 +; CHECK-NEXT: %x.off = add i32 %x, -23 +; CHECK-NEXT: icmp ult i32 %x.off, 3 +; CHECK-NEXT: ret i1 +} + From benny.kra at googlemail.com Mon Dec 20 10:21:59 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 20 Dec 2010 16:21:59 -0000 Subject: [llvm-commits] [llvm] r122249 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Message-ID: <20101220162200.035F92A6C12C@llvm.org> Author: d0k Date: Mon Dec 20 10:21:59 2010 New Revision: 122249 URL: http://llvm.org/viewvc/llvm-project?rev=122249&view=rev Log: Reduce indentation. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=122249&r1=122248&r2=122249&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon Dec 20 10:21:59 2010 @@ -1429,13 +1429,11 @@ return getICmpValue(isSigned, Code, Op0, Op1, Builder); } } - - { - // handle (roughly): - // (icmp ne (A & B), C) | (icmp ne (A & D), E) - Value* fold = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_NE, Builder); - if (fold) return fold; - } + + // handle (roughly): + // (icmp ne (A & B), C) | (icmp ne (A & D), E) + if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_NE, Builder)) + return V; // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0); From fvbommel at gmail.com Mon Dec 20 12:13:37 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 20 Dec 2010 19:13:37 +0100 Subject: [llvm-commits] [llvm] r122248 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp test/Transforms/InstCombine/or.ll In-Reply-To: <20101220161851.67BB52A6C12C@llvm.org> References: <20101220161851.67BB52A6C12C@llvm.org> Message-ID: On Mon, Dec 20, 2010 at 5:18 PM, Benjamin Kramer wrote: > Teach InstCombine to merge (icmp ult (X + CA), C1) | (icmp eq X, C2) into (icmp ult (X + CA), C1 + 1) if C2 + CA == C1. Shouldn't it turn it into (icmp ule (X + CA), C1), to guard against the case where C1 + 1 overflows? (i.e. C1 is the maximum unsigned value, aka -1) And does this already happen for predicates other than ult? (e.g. slt, sgt, ugt, ...) From resistor at mac.com Mon Dec 20 12:18:16 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 18:18:16 -0000 Subject: [llvm-commits] [llvm] r122254 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20101220181816.567102A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 12:18:16 2010 New Revision: 122254 URL: http://llvm.org/viewvc/llvm-project?rev=122254&view=rev Log: Reuse the reference into the LVI cache throughout the solver subsystem. This is much easier to verify as being safe thanks its recent de-recursivization. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122254&r1=122253&r2=122254&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Dec 20 12:18:16 2010 @@ -329,9 +329,12 @@ // returned means that the work item was not completely processed and must // be revisited after going through the new items. bool solveBlockValue(Value *Val, BasicBlock *BB); - bool solveBlockValueNonLocal(Value *Val, BasicBlock *BB); - bool solveBlockValuePHINode(PHINode *PN, BasicBlock *BB); - bool solveBlockValueConstantRange(Instruction *BBI, BasicBlock *BB); + bool solveBlockValueNonLocal(LVILatticeVal &BBLV, + Value *Val, BasicBlock *BB); + bool solveBlockValuePHINode(LVILatticeVal &BBLV, + PHINode *PN, BasicBlock *BB); + bool solveBlockValueConstantRange(LVILatticeVal &BBLV, + Instruction *BBI, BasicBlock *BB); void solve(); @@ -455,11 +458,11 @@ Instruction *BBI = dyn_cast(Val); if (BBI == 0 || BBI->getParent() != BB) { - return solveBlockValueNonLocal(Val, BB); + return solveBlockValueNonLocal(BBLV, Val, BB); } if (PHINode *PN = dyn_cast(BBI)) { - return solveBlockValuePHINode(PN, BB); + return solveBlockValuePHINode(BBLV, PN, BB); } // We can only analyze the definitions of certain classes of instructions @@ -469,8 +472,7 @@ !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); - Result.markOverdefined(); - setBlockValue(Val, BB, Result, Cache); + BBLV.markOverdefined(); return true; } @@ -481,12 +483,11 @@ DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); - Result.markOverdefined(); - setBlockValue(Val, BB, Result, Cache); + BBLV.markOverdefined(); return true; } - return solveBlockValueConstantRange(BBI, BB); + return solveBlockValueConstantRange(BBLV, BBI, BB); } static bool InstructionDereferencesPointer(Instruction *I, Value *Ptr) { @@ -504,7 +505,8 @@ return false; } -bool LazyValueInfoCache::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) { +bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, + Value *Val, BasicBlock *BB) { LVILatticeVal Result; // Start Undefined. // If this is a pointer, and there's a load from that pointer in this BB, @@ -529,7 +531,7 @@ } else { Result.markOverdefined(); } - setBlockValue(Val, BB, Result); + BBLV = Result; return true; } @@ -555,7 +557,8 @@ const PointerType *PTy = cast(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } - setBlockValue(Val, BB, Result); + + BBLV = Result; return true; } } @@ -564,11 +567,12 @@ // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined()); - setBlockValue(Val, BB, Result); + BBLV = Result; return true; } -bool LazyValueInfoCache::solveBlockValuePHINode(PHINode *PN, BasicBlock *BB) { +bool LazyValueInfoCache::solveBlockValuePHINode(LVILatticeVal &BBLV, + PHINode *PN, BasicBlock *BB) { LVILatticeVal Result; // Start Undefined. // Loop over all of our predecessors, merging what we know from them into @@ -589,7 +593,8 @@ if (Result.isOverdefined()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because of pred.\n"); - setBlockValue(PN, BB, Result); + + BBLV = Result; return true; } } @@ -598,11 +603,12 @@ // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined() && "Possible PHI in entry block?"); - setBlockValue(PN, BB, Result); + BBLV = Result; return true; } -bool LazyValueInfoCache::solveBlockValueConstantRange(Instruction *BBI, +bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, + Instruction *BBI, BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. if (!hasBlockValue(BBI->getOperand(0), BB)) { @@ -610,11 +616,9 @@ return false; } - LVILatticeVal Result; LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); if (!LHSVal.isConstantRange()) { - Result.markOverdefined(); - setBlockValue(BBI, BB, Result); + BBLV.markOverdefined(); return true; } @@ -625,8 +629,7 @@ if (ConstantInt *RHS = dyn_cast(BBI->getOperand(1))) { RHSRange = ConstantRange(RHS->getValue()); } else { - Result.markOverdefined(); - setBlockValue(BBI, BB, Result); + BBLV.markOverdefined(); return true; } } @@ -634,6 +637,7 @@ // NOTE: We're currently limited by the set of operations that ConstantRange // can evaluate symbolically. Enhancing that set will allows us to analyze // more definitions. + LVILatticeVal Result; switch (BBI->getOpcode()) { case Instruction::Add: Result.markConstantRange(LHSRange.add(RHSRange)); @@ -680,7 +684,7 @@ break; } - setBlockValue(BBI, BB, Result); + BBLV = Result; return true; } From gohman at apple.com Mon Dec 20 12:54:40 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 20 Dec 2010 10:54:40 -0800 Subject: [llvm-commits] [llvm] r122170 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/critical-edge-split-2.ll In-Reply-To: <4C148651-8777-4184-BC9E-EE746893C005@nondot.org> References: <20101219045857.D53B42A6C12C@llvm.org> <17985F09-30C1-417A-A29C-65F2BE81C797@2pi.dk> <4C148651-8777-4184-BC9E-EE746893C005@nondot.org> Message-ID: <5DB97C7B-B207-421E-A7F7-903A9285FECF@apple.com> On Dec 18, 2010, at 11:30 PM, Chris Lattner wrote: > > On Dec 18, 2010, at 11:19 PM, Jakob Stoklund Olesen wrote: > >> >> On Dec 18, 2010, at 8:58 PM, Chris Lattner wrote: >> >>> Author: lattner >>> Date: Sat Dec 18 22:58:57 2010 >>> New Revision: 122170 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122170&view=rev >>> Log: >>> fix PR8642: if a critical edge has a PHI value that can trap, >>> isel is *required* to split the edge. PHI values get evaluated >>> on the edge, not in their predecessor block. >> >> What happens if the predecessor block is terminated by indirectbr, so the edge can't be split? > > Huh, good question... I don't see a really robust answer... Why does LLVM need the concept of trapping constants? Prohibiting them would be a robust answer, at seemingly little practical cost. Dan From resistor at mac.com Mon Dec 20 13:33:42 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 19:33:42 -0000 Subject: [llvm-commits] [llvm] r122256 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20101220193342.129C62A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 13:33:41 2010 New Revision: 122256 URL: http://llvm.org/viewvc/llvm-project?rev=122256&view=rev Log: More LVI cleanups, including trying to simplify the process of maintaining the OverDefinedCache. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122256&r1=122255&r2=122256&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Dec 20 13:33:41 2010 @@ -310,6 +310,25 @@ deleted(); } }; + + /// OverDefinedCacheUpdater - A helper object that ensures that the + /// OverDefinedCache is updated whenever solveBlockValue returns. + struct OverDefinedCacheUpdater { + LazyValueInfoCache *Parent; + Value *Val; + BasicBlock *BB; + LVILatticeVal &BBLV; + + OverDefinedCacheUpdater(Value *V, BasicBlock *B, LVILatticeVal &LV, + LazyValueInfoCache *P) + : Parent(P), Val(V), BB(B), BBLV(LV) { } + + bool markResult(bool changed) { + if (changed && BBLV.isOverdefined()) + Parent->OverDefinedCache.insert(std::make_pair(BB, Val)); + return changed; + } + }; /// ValueCache - This is all of the cached information for all values, /// mapped from Value* to key information. @@ -342,21 +361,7 @@ return ValueCache[LVIValueHandle(V, this)]; } - LVILatticeVal setBlockValue(Value *V, BasicBlock *BB, LVILatticeVal L, - ValueCacheEntryTy &Cache) { - if (L.isOverdefined()) OverDefinedCache.insert(std::make_pair(BB, V)); - return Cache[BB] = L; - } - LVILatticeVal setBlockValue(Value *V, BasicBlock *BB, LVILatticeVal L) { - return setBlockValue(V, BB, L, lookup(V)); - } - - struct BlockStackEntry { - BlockStackEntry(Value *Val, BasicBlock *BB) : Val(Val), BB(BB) {} - Value *Val; - BasicBlock *BB; - }; - std::stack block_value_stack; + std::stack > block_value_stack; public: /// getValueInBlock - This is the query interface to determine the lattice @@ -416,8 +421,8 @@ void LazyValueInfoCache::solve() { while (!block_value_stack.empty()) { - BlockStackEntry &e = block_value_stack.top(); - if (solveBlockValue(e.Val, e.BB)) + std::pair &e = block_value_stack.top(); + if (solveBlockValue(e.second, e.first)) block_value_stack.pop(); } } @@ -444,10 +449,21 @@ ValueCacheEntryTy &Cache = lookup(Val); LVILatticeVal &BBLV = Cache[BB]; + + // OverDefinedCacheUpdater is a helper object that will update + // the OverDefinedCache for us when this method exits. Make sure to + // call markResult on it as we exist, passing a bool to indicate if the + // cache needs updating, i.e. if we have solve a new value or not. + OverDefinedCacheUpdater ODCacheUpdater(Val, BB, BBLV, this); // If we've already computed this block's value, return it. if (!BBLV.isUndefined()) { DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n'); + + // Since we're reusing a cached value here, we don't need to update the + // OverDefinedCahce. The cache will have been properly updated + // whenever the cached value was inserted. + ODCacheUpdater.markResult(false); return true; } @@ -458,11 +474,11 @@ Instruction *BBI = dyn_cast(Val); if (BBI == 0 || BBI->getParent() != BB) { - return solveBlockValueNonLocal(BBLV, Val, BB); + return ODCacheUpdater.markResult(solveBlockValueNonLocal(BBLV, Val, BB)); } if (PHINode *PN = dyn_cast(BBI)) { - return solveBlockValuePHINode(BBLV, PN, BB); + return ODCacheUpdater.markResult(solveBlockValuePHINode(BBLV, PN, BB)); } // We can only analyze the definitions of certain classes of instructions @@ -473,7 +489,7 @@ DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); BBLV.markOverdefined(); - return true; + return ODCacheUpdater.markResult(true); } // FIXME: We're currently limited to binops with a constant RHS. This should @@ -484,10 +500,10 @@ << "' - overdefined because inst def found.\n"); BBLV.markOverdefined(); - return true; + return ODCacheUpdater.markResult(true); } - return solveBlockValueConstantRange(BBLV, BBI, BB); + return ODCacheUpdater.markResult(solveBlockValueConstantRange(BBLV, BBI, BB)); } static bool InstructionDereferencesPointer(Instruction *I, Value *Ptr) { @@ -612,7 +628,7 @@ BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. if (!hasBlockValue(BBI->getOperand(0), BB)) { - block_value_stack.push(BlockStackEntry(BBI->getOperand(0), BB)); + block_value_stack.push(std::make_pair(BB, BBI->getOperand(0))); return false; } @@ -791,7 +807,7 @@ Result = getBlockValue(Val, BBFrom); return true; } - block_value_stack.push(BlockStackEntry(Val, BBFrom)); + block_value_stack.push(std::make_pair(BBFrom, Val)); return false; } @@ -799,7 +815,7 @@ DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" << BB->getName() << "'\n"); - block_value_stack.push(BlockStackEntry(V, BB)); + block_value_stack.push(std::make_pair(BB, V)); solve(); LVILatticeVal Result = getBlockValue(V, BB); From dalej at apple.com Mon Dec 20 13:39:48 2010 From: dalej at apple.com (dalej) Date: Mon, 20 Dec 2010 11:39:48 -0800 Subject: [llvm-commits] [llvm] r122090 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/x86_64-mul-by-const.ll In-Reply-To: References: <20101217214549.686D72A6C12C@llvm.org> Message-ID: <92C5A763-DF29-4FF2-9D30-DD0A7A7B3138@apple.com> On Dec 18, 2010, at 1:53 PM, Chris Lattner wrote: >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Dec 17 15:45:49 2010 >> @@ -3171,6 +3171,26 @@ >> DAG.getConstant(c1 + c2, N1.getValueType())); >> } >> >> + // fold (srl (trunc (srl x, c1)), c2) -> 0 or (trunc (srl x, (add c1, c2))) >> + // This is only valid if the OpSizeInBits + c1 = size of inner shift > > Please end the comment with a ".". Do we already do this for arithmetic shifts, and shift left (with extension instead of trunc) as well? It is not valid for arithmetic right shifts; the trunc is ANDing off sign bits, not zeroes. It is not done for shift left; I can add that. Although I'm not sure how it could arise from real code. >> + if (N1C && N0.getOpcode() == ISD::TRUNCATE && >> + N0.getOperand(0).getOpcode() == ISD::SRL && >> + N0.getOperand(0)->getOperand(1).getOpcode() == ISD::Constant) { > > Please use isa(N0.getOperand(0)->getOperand(1)) which makes the cast<> more obviously right. OK, but this is following other code in the area. >> + uint64_t c1 = >> + cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); >> + uint64_t c2 = N1C->getZExtValue(); > > This can break if the value is > i64. Instead of doing this on getZExtValue(), I'd suggest doing the math on APInt's. These are shift counts, not the value being shifted. I think it's reasonable to assume number of bits per word is less than 18446744073709551616. There is lots of nearby code that does so. >> + EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType(); >> + uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); >> + if (c1 + OpSizeInBits == InnerShiftSize) { >> + if (c1 + c2 >= InnerShiftSize) >> + return DAG.getConstant(0, VT); >> + return DAG.getNode(ISD::TRUNCATE, N0->getDebugLoc(), VT, > > Please add a short comment explaining what you're doing here. What is the "c1 + OpSizeInBits == InnerShiftSize" check doing? The comment without the period explains it. I'll move it down, I guess. >> +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s >> +; Formerly there were two shifts. 8771012. > > Please add a rdar:// prefix so that grep will pick it up, thanks! > > -Chris > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101220/7800ac55/attachment.html From benny.kra at googlemail.com Mon Dec 20 14:00:31 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 20 Dec 2010 20:00:31 -0000 Subject: [llvm-commits] [llvm] r122258 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Message-ID: <20101220200031.C46642A6C12C@llvm.org> Author: d0k Date: Mon Dec 20 14:00:31 2010 New Revision: 122258 URL: http://llvm.org/viewvc/llvm-project?rev=122258&view=rev Log: Add a check missing from my last commit and avoid a potential overflow situation. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=122258&r1=122257&r2=122258&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon Dec 20 14:00:31 2010 @@ -1449,13 +1449,13 @@ } } - // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ult (X + CA), C1 + 1) + // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1) // iff C2 + CA == C1. - if (LHSCC == ICmpInst::ICMP_ULT) { + if (LHSCC == ICmpInst::ICMP_ULT && RHSCC == ICmpInst::ICMP_EQ) { ConstantInt *AddCst; if (match(Val, m_Add(m_Specific(Val2), m_ConstantInt(AddCst)))) if (RHSCst->getValue() + AddCst->getValue() == LHSCst->getValue()) - return Builder->CreateICmp(LHSCC, Val, AddOne(LHSCst)); + return Builder->CreateICmpULE(Val, LHSCst); } // From here on, we only handle: From dalej at apple.com Mon Dec 20 14:10:50 2010 From: dalej at apple.com (Dale Johannesen) Date: Mon, 20 Dec 2010 20:10:50 -0000 Subject: [llvm-commits] [llvm] r122259 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/x86_64-mul-by-const.ll Message-ID: <20101220201050.AE81E2A6C12C@llvm.org> Author: johannes Date: Mon Dec 20 14:10:50 2010 New Revision: 122259 URL: http://llvm.org/viewvc/llvm-project?rev=122259&view=rev Log: Cosmetic changes. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/x86_64-mul-by-const.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122259&r1=122258&r2=122259&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Dec 20 14:10:50 2010 @@ -3172,15 +3172,15 @@ } // fold (srl (trunc (srl x, c1)), c2) -> 0 or (trunc (srl x, (add c1, c2))) - // This is only valid if the OpSizeInBits + c1 = size of inner shift if (N1C && N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getOpcode() == ISD::SRL && - N0.getOperand(0)->getOperand(1).getOpcode() == ISD::Constant) { + isa(N0.getOperand(0)->getOperand(1))) { uint64_t c1 = cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType(); uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); + // This is only valid if the OpSizeInBits + c1 = size of inner shift. if (c1 + OpSizeInBits == InnerShiftSize) { if (c1 + c2 >= InnerShiftSize) return DAG.getConstant(0, VT); Modified: llvm/trunk/test/CodeGen/X86/x86_64-mul-by-const.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86_64-mul-by-const.ll?rev=122259&r1=122258&r2=122259&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/x86_64-mul-by-const.ll (original) +++ llvm/trunk/test/CodeGen/X86/x86_64-mul-by-const.ll Mon Dec 20 14:10:50 2010 @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -; Formerly there were two shifts. 8771012. +; Formerly there were two shifts. rdar://8771012. define i32 @f9188_mul365384439_shift27(i32 %A) nounwind { ; CHECK: imulq $365384439, From benny.kra at googlemail.com Mon Dec 20 14:17:35 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 20 Dec 2010 21:17:35 +0100 Subject: [llvm-commits] [llvm] r122248 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp test/Transforms/InstCombine/or.ll In-Reply-To: References: <20101220161851.67BB52A6C12C@llvm.org> Message-ID: <2D075F15-D9E7-4E06-B5AC-048DAF22986B@gmail.com> On 20.12.2010, at 19:13, Frits van Bommel wrote: > On Mon, Dec 20, 2010 at 5:18 PM, Benjamin Kramer > wrote: >> Teach InstCombine to merge (icmp ult (X + CA), C1) | (icmp eq X, C2) into (icmp ult (X + CA), C1 + 1) if C2 + CA == C1. > > Shouldn't it turn it into (icmp ule (X + CA), C1), to guard against > the case where C1 + 1 overflows? (i.e. C1 is the maximum unsigned > value, aka -1) fixed. Thanks for spotting this. > > And does this already happen for predicates other than ult? (e.g. slt, > sgt, ugt, ...) No, the transformation should be generalized somehow, the commuted variant isn't caught either. It'll need some more thought though, I don't want to duplicate this code 8 times. From peckw at wesleypeck.com Mon Dec 20 14:43:25 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Mon, 20 Dec 2010 20:43:25 -0000 Subject: [llvm-commits] [llvm] r122261 - in /llvm/trunk: lib/Target/MBlaze/MBlazeInstrInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.cpp lib/Target/MBlaze/MBlazeRegisterInfo.h lib/Target/MBlaze/MBlazeRegisterInfo.td test/MC/MBlaze/mblaze_special.s Message-ID: <20101220204325.30D482A6C12C@llvm.org> Author: peckw Date: Mon Dec 20 14:43:24 2010 New Revision: 122261 URL: http://llvm.org/viewvc/llvm-project?rev=122261&view=rev Log: Teach the MBlaze asm parser how to parse special purpose register names. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.h llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td llvm/trunk/test/MC/MBlaze/mblaze_special.s Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122261&r1=122260&r2=122261&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Mon Dec 20 14:43:24 2010 @@ -83,7 +83,6 @@ def calltarget : Operand; def simm16 : Operand; def uimm5 : Operand; -def uimm14 : Operand; def uimm15 : Operand; def fimm : Operand; @@ -600,11 +599,11 @@ //===----------------------------------------------------------------------===// // Misc. instructions //===----------------------------------------------------------------------===// -def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins uimm14:$rg), - "mfs $dst, $rg", [], IIAlu>; +def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins SPR:$src), + "mfs $dst, $src", [], IIAlu>; -def MTS : SPC<0x25, 0x3, (outs), (ins uimm14:$dst, GPR:$rg), - "mts $dst, $rg", [], IIAlu>; +def MTS : SPC<0x25, 0x3, (outs SPR:$dst), (ins GPR:$src), + "mts $dst, $src", [], IIAlu>; def MSRSET : MSR<0x25, 0x20, (outs GPR:$dst), (ins uimm15:$set), "msrset $dst, $set", [], IIAlu>; Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp?rev=122261&r1=122260&r2=122261&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.cpp Mon Dec 20 14:43:24 2010 @@ -48,38 +48,62 @@ /// MBlaze::R0, return the number that it corresponds to (e.g. 0). unsigned MBlazeRegisterInfo::getRegisterNumbering(unsigned RegEnum) { switch (RegEnum) { - case MBlaze::R0 : return 0; - case MBlaze::R1 : return 1; - case MBlaze::R2 : return 2; - case MBlaze::R3 : return 3; - case MBlaze::R4 : return 4; - case MBlaze::R5 : return 5; - case MBlaze::R6 : return 6; - case MBlaze::R7 : return 7; - case MBlaze::R8 : return 8; - case MBlaze::R9 : return 9; - case MBlaze::R10 : return 10; - case MBlaze::R11 : return 11; - case MBlaze::R12 : return 12; - case MBlaze::R13 : return 13; - case MBlaze::R14 : return 14; - case MBlaze::R15 : return 15; - case MBlaze::R16 : return 16; - case MBlaze::R17 : return 17; - case MBlaze::R18 : return 18; - case MBlaze::R19 : return 19; - case MBlaze::R20 : return 20; - case MBlaze::R21 : return 21; - case MBlaze::R22 : return 22; - case MBlaze::R23 : return 23; - case MBlaze::R24 : return 24; - case MBlaze::R25 : return 25; - case MBlaze::R26 : return 26; - case MBlaze::R27 : return 27; - case MBlaze::R28 : return 28; - case MBlaze::R29 : return 29; - case MBlaze::R30 : return 30; - case MBlaze::R31 : return 31; + case MBlaze::R0 : return 0; + case MBlaze::R1 : return 1; + case MBlaze::R2 : return 2; + case MBlaze::R3 : return 3; + case MBlaze::R4 : return 4; + case MBlaze::R5 : return 5; + case MBlaze::R6 : return 6; + case MBlaze::R7 : return 7; + case MBlaze::R8 : return 8; + case MBlaze::R9 : return 9; + case MBlaze::R10 : return 10; + case MBlaze::R11 : return 11; + case MBlaze::R12 : return 12; + case MBlaze::R13 : return 13; + case MBlaze::R14 : return 14; + case MBlaze::R15 : return 15; + case MBlaze::R16 : return 16; + case MBlaze::R17 : return 17; + case MBlaze::R18 : return 18; + case MBlaze::R19 : return 19; + case MBlaze::R20 : return 20; + case MBlaze::R21 : return 21; + case MBlaze::R22 : return 22; + case MBlaze::R23 : return 23; + case MBlaze::R24 : return 24; + case MBlaze::R25 : return 25; + case MBlaze::R26 : return 26; + case MBlaze::R27 : return 27; + case MBlaze::R28 : return 28; + case MBlaze::R29 : return 29; + case MBlaze::R30 : return 30; + case MBlaze::R31 : return 31; + case MBlaze::RPC : return 0x0000; + case MBlaze::RMSR : return 0x0001; + case MBlaze::REAR : return 0x0003; + case MBlaze::RESR : return 0x0005; + case MBlaze::RFSR : return 0x0007; + case MBlaze::RBTR : return 0x000B; + case MBlaze::REDR : return 0x000D; + case MBlaze::RPID : return 0x1000; + case MBlaze::RZPR : return 0x1001; + case MBlaze::RTLBX : return 0x1002; + case MBlaze::RTLBLO : return 0x1003; + case MBlaze::RTLBHI : return 0x1004; + case MBlaze::RPVR0 : return 0x2000; + case MBlaze::RPVR1 : return 0x2001; + case MBlaze::RPVR2 : return 0x2002; + case MBlaze::RPVR3 : return 0x2003; + case MBlaze::RPVR4 : return 0x2004; + case MBlaze::RPVR5 : return 0x2005; + case MBlaze::RPVR6 : return 0x2006; + case MBlaze::RPVR7 : return 0x2007; + case MBlaze::RPVR8 : return 0x2008; + case MBlaze::RPVR9 : return 0x2009; + case MBlaze::RPVR10 : return 0x200A; + case MBlaze::RPVR11 : return 0x200B; default: llvm_unreachable("Unknown register number!"); } return 0; // Not reached @@ -126,6 +150,37 @@ return 0; // Not reached } +unsigned MBlazeRegisterInfo::getSpecialRegisterFromNumbering(unsigned Reg) { + switch (Reg) { + case 0x0000 : return MBlaze::RPC; + case 0x0001 : return MBlaze::RMSR; + case 0x0003 : return MBlaze::REAR; + case 0x0005 : return MBlaze::RESR; + case 0x0007 : return MBlaze::RFSR; + case 0x000B : return MBlaze::RBTR; + case 0x000D : return MBlaze::REDR; + case 0x1000 : return MBlaze::RPID; + case 0x1001 : return MBlaze::RZPR; + case 0x1002 : return MBlaze::RTLBX; + case 0x1003 : return MBlaze::RTLBLO; + case 0x1004 : return MBlaze::RTLBHI; + case 0x2000 : return MBlaze::RPVR0; + case 0x2001 : return MBlaze::RPVR1; + case 0x2002 : return MBlaze::RPVR2; + case 0x2003 : return MBlaze::RPVR3; + case 0x2004 : return MBlaze::RPVR4; + case 0x2005 : return MBlaze::RPVR5; + case 0x2006 : return MBlaze::RPVR6; + case 0x2007 : return MBlaze::RPVR7; + case 0x2008 : return MBlaze::RPVR8; + case 0x2009 : return MBlaze::RPVR9; + case 0x200A : return MBlaze::RPVR10; + case 0x200B : return MBlaze::RPVR11; + default: llvm_unreachable("Unknown register number!"); + } + return 0; // Not reached +} + unsigned MBlazeRegisterInfo::getPICCallReg() { return MBlaze::R20; } Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.h?rev=122261&r1=122260&r2=122261&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.h (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.h Mon Dec 20 14:43:24 2010 @@ -44,6 +44,7 @@ /// MBlaze::RA, return the number that it corresponds to (e.g. 31). static unsigned getRegisterNumbering(unsigned RegEnum); static unsigned getRegisterFromNumbering(unsigned RegEnum); + static unsigned getSpecialRegisterFromNumbering(unsigned RegEnum); /// Get PIC indirect call register static unsigned getPICCallReg(); Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td?rev=122261&r1=122260&r2=122261&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Mon Dec 20 14:43:24 2010 @@ -82,7 +82,7 @@ def REDR : MBlazeSPRReg<0x000D, "redr">, DwarfRegNum<[38]>; def RPID : MBlazeSPRReg<0x1000, "rpid">, DwarfRegNum<[39]>; def RZPR : MBlazeSPRReg<0x1001, "rzpr">, DwarfRegNum<[40]>; - def RTLBX : MBlazeSPRReg<0x0002, "rtlbx">, DwarfRegNum<[41]>; + def RTLBX : MBlazeSPRReg<0x1002, "rtlbx">, DwarfRegNum<[41]>; def RTLBLO : MBlazeSPRReg<0x1003, "rtlblo">, DwarfRegNum<[42]>; def RTLBHI : MBlazeSPRReg<0x1004, "rtlbhi">, DwarfRegNum<[43]>; def RPVR0 : MBlazeSPRReg<0x2000, "rpvr0">, DwarfRegNum<[44]>; @@ -138,3 +138,44 @@ } }]; } + +def SPR : RegisterClass<"MBlaze", [i32], 32, + [ + // Reserved + RPC, + RMSR, + REAR, + RESR, + RFSR, + RBTR, + REDR, + RPID, + RZPR, + RTLBX, + RTLBLO, + RTLBHI, + RPVR0, + RPVR1, + RPVR2, + RPVR3, + RPVR4, + RPVR5, + RPVR6, + RPVR7, + RPVR8, + RPVR9, + RPVR10, + RPVR11 + ]> +{ + let MethodProtos = [{ + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + SPRClass::iterator + SPRClass::allocation_order_end(const MachineFunction &MF) const { + // None of the special purpose registers are allocatable. + return end()-24; + } + }]; +} Modified: llvm/trunk/test/MC/MBlaze/mblaze_special.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MBlaze/mblaze_special.s?rev=122261&r1=122260&r2=122261&view=diff ============================================================================== --- llvm/trunk/test/MC/MBlaze/mblaze_special.s (original) +++ llvm/trunk/test/MC/MBlaze/mblaze_special.s Mon Dec 20 14:43:24 2010 @@ -1,7 +1,7 @@ # RUN: llvm-mc -triple mblaze-unknown-unknown -show-encoding %s | FileCheck %s -# Test to ensure that all FPU instructions can be parsed by the -# assembly parser correctly. +# Test to ensure that all special instructions and special registers can be +# parsed by the assembly parser correctly. # TYPE A: OPCODE RD RA RB FLAGS # BINARY: 011011 00000 00000 00000 00000000000 @@ -9,7 +9,7 @@ # CHECK: mfs # BINARY: 100101 00000 00000 10000 00000000000 # CHECK: encoding: [0x94,0x00,0x80,0x00] - mfs r0, 0x0 + mfs r0, rpc # CHECK: msrclr # BINARY: 100101 00000 100010 000000000000000 @@ -24,7 +24,7 @@ # CHECK: mts # BINARY: 100101 00000 00000 11 00000000000000 # CHECK: encoding: [0x94,0x00,0xc0,0x00] - mts 0x0 , r0 + mts rpc, r0 # CHECK: wdc # BINARY: 100100 00000 00000 00001 00001100100 @@ -45,3 +45,123 @@ # BINARY: 100100 00000 00000 00001 00001101000 # CHECK: encoding: [0x90,0x00,0x08,0x68] wic r0, r1 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000000000 +# CHECK: encoding: [0x94,0x20,0x80,0x00] + mfs r1, rpc + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000000001 +# CHECK: encoding: [0x94,0x20,0x80,0x01] + mfs r1, rmsr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000000011 +# CHECK: encoding: [0x94,0x20,0x80,0x03] + mfs r1, rear + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000000101 +# CHECK: encoding: [0x94,0x20,0x80,0x05] + mfs r1, resr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000000111 +# CHECK: encoding: [0x94,0x20,0x80,0x07] + mfs r1, rfsr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000001011 +# CHECK: encoding: [0x94,0x20,0x80,0x0b] + mfs r1, rbtr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10000 00000001101 +# CHECK: encoding: [0x94,0x20,0x80,0x0d] + mfs r1, redr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10010 00000000000 +# CHECK: encoding: [0x94,0x20,0x90,0x00] + mfs r1, rpid + +# CHECK: mfs +# BINARY: 100101 00001 00000 10010 00000000001 +# CHECK: encoding: [0x94,0x20,0x90,0x01] + mfs r1, rzpr + +# CHECK: mfs +# BINARY: 100101 00001 00000 10010 00000000010 +# CHECK: encoding: [0x94,0x20,0x90,0x02] + mfs r1, rtlbx + +# CHECK: mfs +# BINARY: 100101 00001 00000 10010 00000000100 +# CHECK: encoding: [0x94,0x20,0x90,0x04] + mfs r1, rtlbhi + +# CHECK: mfs +# BINARY: 100101 00001 00000 10010 00000000011 +# CHECK: encoding: [0x94,0x20,0x90,0x03] + mfs r1, rtlblo + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000000 +# CHECK: encoding: [0x94,0x20,0xa0,0x00] + mfs r1, rpvr0 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000001 +# CHECK: encoding: [0x94,0x20,0xa0,0x01] + mfs r1, rpvr1 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000010 +# CHECK: encoding: [0x94,0x20,0xa0,0x02] + mfs r1, rpvr2 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000011 +# CHECK: encoding: [0x94,0x20,0xa0,0x03] + mfs r1, rpvr3 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000100 +# CHECK: encoding: [0x94,0x20,0xa0,0x04] + mfs r1, rpvr4 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000101 +# CHECK: encoding: [0x94,0x20,0xa0,0x05] + mfs r1, rpvr5 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000110 +# CHECK: encoding: [0x94,0x20,0xa0,0x06] + mfs r1, rpvr6 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000000111 +# CHECK: encoding: [0x94,0x20,0xa0,0x07] + mfs r1, rpvr7 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000001000 +# CHECK: encoding: [0x94,0x20,0xa0,0x08] + mfs r1, rpvr8 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000001001 +# CHECK: encoding: [0x94,0x20,0xa0,0x09] + mfs r1, rpvr9 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000001010 +# CHECK: encoding: [0x94,0x20,0xa0,0x0a] + mfs r1, rpvr10 + +# CHECK: mfs +# BINARY: 100101 00001 00000 10100 00000001011 +# CHECK: encoding: [0x94,0x20,0xa0,0x0b] + mfs r1, rpvr11 From rdivacky at freebsd.org Mon Dec 20 14:49:43 2010 From: rdivacky at freebsd.org (Roman Divacky) Date: Mon, 20 Dec 2010 20:49:43 -0000 Subject: [llvm-commits] [llvm] r122263 - in /llvm/trunk/test: MC/ELF/abs.s MC/ELF/alias-reloc.s MC/ELF/alias.s MC/ELF/comdat.s MC/ELF/common.s MC/ELF/file.s MC/ELF/local-reloc.s MC/ELF/pic-diff.s MC/ELF/rename.s MC/ELF/set.s MC/ELF/symref.s MC/ELF/tls.s MC/ELF/type.s MC/ELF/undef.s MC/ELF/weak.s MC/ELF/weakref-reloc.s MC/ELF/weakref.s Scripts/elf-dump Message-ID: <20101220204943.ED0E82A6C12C@llvm.org> Author: rdivacky Date: Mon Dec 20 14:49:43 2010 New Revision: 122263 URL: http://llvm.org/viewvc/llvm-project?rev=122263&view=rev Log: Print all 64bits for st_value and st_size. Adjust tests accordingly. Modified: llvm/trunk/test/MC/ELF/abs.s llvm/trunk/test/MC/ELF/alias-reloc.s llvm/trunk/test/MC/ELF/alias.s llvm/trunk/test/MC/ELF/comdat.s llvm/trunk/test/MC/ELF/common.s llvm/trunk/test/MC/ELF/file.s llvm/trunk/test/MC/ELF/local-reloc.s llvm/trunk/test/MC/ELF/pic-diff.s llvm/trunk/test/MC/ELF/rename.s llvm/trunk/test/MC/ELF/set.s llvm/trunk/test/MC/ELF/symref.s llvm/trunk/test/MC/ELF/tls.s llvm/trunk/test/MC/ELF/type.s llvm/trunk/test/MC/ELF/undef.s llvm/trunk/test/MC/ELF/weak.s llvm/trunk/test/MC/ELF/weakref-reloc.s llvm/trunk/test/MC/ELF/weakref.s llvm/trunk/test/Scripts/elf-dump Modified: llvm/trunk/test/MC/ELF/abs.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/abs.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/abs.s (original) +++ llvm/trunk/test/MC/ELF/abs.s Mon Dec 20 14:49:43 2010 @@ -12,5 +12,5 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x0000fff1) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) Modified: llvm/trunk/test/MC/ELF/alias-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/alias-reloc.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/alias-reloc.s (original) +++ llvm/trunk/test/MC/ELF/alias-reloc.s Mon Dec 20 14:49:43 2010 @@ -23,8 +23,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: # Symbol 0x00000006 @@ -33,8 +33,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000004) -// CHECK-NEXT: ('st_value', 0x00000005) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000005) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: # Relocation 0x00000000 Modified: llvm/trunk/test/MC/ELF/alias.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/alias.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/alias.s (original) +++ llvm/trunk/test/MC/ELF/alias.s Mon Dec 20 14:49:43 2010 @@ -22,8 +22,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x0000001d) # 'bar4' @@ -31,8 +31,8 @@ // CHECK-NEXT: ('st_type', 0x00000002) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000003 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' @@ -40,8 +40,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000004 // CHECK-NEXT: (('st_name', 0x0000000e) # 'foo3' @@ -49,8 +49,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x00000018) # 'foo4' @@ -58,8 +58,8 @@ // CHECK-NEXT: ('st_type', 0x00000002) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000006 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -73,13 +73,13 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK: # Symbol 0x0000000a // CHECK-NEXT: (('st_name', 0x00000009) # 'bar2' // CHECK-NEXT: ('st_bind', 0x00000001) // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) Modified: llvm/trunk/test/MC/ELF/comdat.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/comdat.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/comdat.s (original) +++ llvm/trunk/test/MC/ELF/comdat.s Mon Dec 20 14:49:43 2010 @@ -48,8 +48,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000007) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x00000004) # 'g2' @@ -57,8 +57,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000002) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: # Symbol 0x0000000d @@ -67,8 +67,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/common.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/common.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/common.s (original) +++ llvm/trunk/test/MC/ELF/common.s Mon Dec 20 14:49:43 2010 @@ -13,8 +13,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000001) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000001) // Same as common1, but with directives in a different order. @@ -27,8 +27,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', -// CHECK-NEXT: ('st_value', 0x00000001) -// CHECK-NEXT: ('st_size', 0x00000001) +// CHECK-NEXT: ('st_value', 0x0000000000000001) +// CHECK-NEXT: ('st_size', 0x0000000000000001) .local common6 .comm common6,8,16 @@ -39,8 +39,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000003) -// CHECK-NEXT: ('st_value', 0x00000010) -// CHECK-NEXT: ('st_size', 0x00000008) +// CHECK-NEXT: ('st_value', 0x0000000000000010) +// CHECK-NEXT: ('st_size', 0x0000000000000008) // CHECK-NEXT: ), // Test that without an explicit .local we produce a global. @@ -52,8 +52,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x0000fff2) -// CHECK-NEXT: ('st_value', 0x00000004) -// CHECK-NEXT: ('st_size', 0x00000004) +// CHECK-NEXT: ('st_value', 0x0000000000000004) +// CHECK-NEXT: ('st_size', 0x0000000000000004) // Test that without an explicit .local we produce a global, even if the first @@ -72,8 +72,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x0000fff2) -// CHECK-NEXT: ('st_value', 0x00000010) -// CHECK-NEXT: ('st_size', 0x00000028) +// CHECK-NEXT: ('st_value', 0x0000000000000010) +// CHECK-NEXT: ('st_size', 0x0000000000000028) .comm common5,4,4 @@ -83,6 +83,6 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x0000fff2) -// CHECK-NEXT: ('st_value', 0x00000004) -// CHECK-NEXT: ('st_size', 0x00000004) +// CHECK-NEXT: ('st_value', 0x0000000000000004) +// CHECK-NEXT: ('st_size', 0x0000000000000004) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/file.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/file.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/file.s (original) +++ llvm/trunk/test/MC/ELF/file.s Mon Dec 20 14:49:43 2010 @@ -10,8 +10,8 @@ // CHECK-NEXT: ('st_type', 0x00000004) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x0000fff1) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x00000005) # 'foa' @@ -19,5 +19,5 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) Modified: llvm/trunk/test/MC/ELF/local-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/local-reloc.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/local-reloc.s (original) +++ llvm/trunk/test/MC/ELF/local-reloc.s Mon Dec 20 14:49:43 2010 @@ -17,8 +17,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // Relocation refers to symbol number 2 // CHECK: ('_relocations', [ Modified: llvm/trunk/test/MC/ELF/pic-diff.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/pic-diff.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/pic-diff.s (original) +++ llvm/trunk/test/MC/ELF/pic-diff.s Mon Dec 20 14:49:43 2010 @@ -6,8 +6,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: ('_relocations', [ Modified: llvm/trunk/test/MC/ELF/rename.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/rename.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/rename.s (original) +++ llvm/trunk/test/MC/ELF/rename.s Mon Dec 20 14:49:43 2010 @@ -35,8 +35,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // The relocation uses symbol 2 // CHECK: # Relocation 0x00000000 Modified: llvm/trunk/test/MC/ELF/set.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/set.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/set.s (original) +++ llvm/trunk/test/MC/ELF/set.s Mon Dec 20 14:49:43 2010 @@ -16,6 +16,6 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/symref.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/symref.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/symref.s (original) +++ llvm/trunk/test/MC/ELF/symref.s Mon Dec 20 14:49:43 2010 @@ -28,8 +28,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x00000025) # 'bar3@@zed' @@ -37,8 +37,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000003 // CHECK-NEXT: (('st_name', 0x0000002f) # 'bar5@@zed' @@ -46,8 +46,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000004 // CHECK-NEXT: (('st_name', 0x00000001) # 'defined1' @@ -55,8 +55,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x0000000a) # 'defined2' @@ -64,8 +64,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000006 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -73,8 +73,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000007 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -82,8 +82,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000002) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000008 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -91,8 +91,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000003) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000009 // CHECK-NEXT: (('st_name', 0x0000004a) # 'g1@@zed' @@ -100,8 +100,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000014) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000014) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000a // CHECK-NEXT: (('st_name', 0x00000042) # 'global1' @@ -109,8 +109,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000014) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000014) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000b // CHECK-NEXT: (('st_name', 0x0000001c) # 'bar2 at zed' @@ -118,8 +118,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000c // CHECK-NEXT: (('st_name', 0x00000039) # 'bar6 at zed' @@ -127,8 +127,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT:]) Modified: llvm/trunk/test/MC/ELF/tls.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/tls.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/tls.s (original) +++ llvm/trunk/test/MC/ELF/tls.s Mon Dec 20 14:49:43 2010 @@ -15,8 +15,8 @@ // CHECK-NEXT: ('st_type', 0x00000006) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000004) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: # Symbol 0x00000007 @@ -25,8 +25,8 @@ // CHECK-NEXT: ('st_type', 0x00000006) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000008 // CHECK-NEXT: (('st_name', 0x00000006) # 'foo2' @@ -34,8 +34,8 @@ // CHECK-NEXT: ('st_type', 0x00000006) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000009 // CHECK-NEXT: (('st_name', 0x0000000b) # 'foo3' @@ -43,6 +43,6 @@ // CHECK-NEXT: ('st_type', 0x00000006) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/type.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/type.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/type.s (original) +++ llvm/trunk/test/MC/ELF/type.s Mon Dec 20 14:49:43 2010 @@ -18,8 +18,8 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' @@ -27,6 +27,6 @@ // CHECK-NEXT: ('st_type', 0x00000002) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/undef.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/undef.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/undef.s (original) +++ llvm/trunk/test/MC/ELF/undef.s Mon Dec 20 14:49:43 2010 @@ -40,7 +40,7 @@ // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) Modified: llvm/trunk/test/MC/ELF/weak.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/weak.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/weak.s (original) +++ llvm/trunk/test/MC/ELF/weak.s Mon Dec 20 14:49:43 2010 @@ -15,8 +15,8 @@ //CHECK-NEXT: ('st_type', 0x00000000) //CHECK-NEXT: ('st_other', 0x00000000) //CHECK-NEXT: ('st_shndx', 0x00000001) -//CHECK-NEXT: ('st_value', 0x00000004) -//CHECK-NEXT: ('st_size', 0x00000000) +//CHECK-NEXT: ('st_value', 0x0000000000000004) +//CHECK-NEXT: ('st_size', 0x0000000000000000) //CHECK-NEXT: ), //CHECK-NEXT: # Symbol 0x00000005 //CHECK: (('st_name', 0x00000001) # 'foo' @@ -24,7 +24,7 @@ //CHECK-NEXT: ('st_type', 0x00000000) //CHECK-NEXT: ('st_other', 0x00000000) //CHECK-NEXT: ('st_shndx', 0x00000000) -//CHECK-NEXT: ('st_value', 0x00000000) -//CHECK-NEXT: ('st_size', 0x00000000) +//CHECK-NEXT: ('st_value', 0x0000000000000000) +//CHECK-NEXT: ('st_size', 0x0000000000000000) //CHECK-NEXT: ), //CHECK-NEXT: ]) Modified: llvm/trunk/test/MC/ELF/weakref-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/weakref-reloc.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/weakref-reloc.s (original) +++ llvm/trunk/test/MC/ELF/weakref-reloc.s Mon Dec 20 14:49:43 2010 @@ -13,8 +13,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' @@ -22,8 +22,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000006 // CHECK-NEXT: (('st_name', 0x00000005) # 'zed' @@ -31,8 +31,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK: # Relocation 0x00000000 Modified: llvm/trunk/test/MC/ELF/weakref.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/weakref.s?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/weakref.s (original) +++ llvm/trunk/test/MC/ELF/weakref.s Mon Dec 20 14:49:43 2010 @@ -75,8 +75,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000001 // CHECK-NEXT: (('st_name', 0x00000015) # 'bar6' @@ -84,8 +84,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000018) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000018) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x0000001a) # 'bar7' @@ -93,8 +93,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000018) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000018) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000003 // CHECK-NEXT: (('st_name', 0x0000001f) # 'bar8' @@ -102,8 +102,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x0000001c) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x000000000000001c) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000004 // CHECK-NEXT: (('st_name', 0x00000024) # 'bar9' @@ -111,8 +111,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000020) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000020) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -120,8 +120,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000006 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -129,8 +129,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000002) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000007 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -138,8 +138,8 @@ // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000003) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000008 // CHECK-NEXT: (('st_name', 0x00000029) # 'bar10' @@ -147,8 +147,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000028) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000028) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000009 // CHECK-NEXT: (('st_name', 0x0000002f) # 'bar11' @@ -156,8 +156,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000030) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000030) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000a // CHECK-NEXT: (('st_name', 0x00000035) # 'bar12' @@ -165,8 +165,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000030) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000030) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000b // CHECK-NEXT: (('st_name', 0x0000003b) # 'bar13' @@ -174,8 +174,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000034) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000034) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000c // CHECK-NEXT: (('st_name', 0x00000041) # 'bar14' @@ -183,8 +183,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000038) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000038) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000d // CHECK-NEXT: (('st_name', 0x00000047) # 'bar15' @@ -192,8 +192,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x00000040) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000040) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000e // CHECK-NEXT: (('st_name', 0x00000001) # 'bar2' @@ -201,8 +201,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x0000000f // CHECK-NEXT: (('st_name', 0x00000006) # 'bar3' @@ -210,8 +210,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000010 // CHECK-NEXT: (('st_name', 0x0000000b) # 'bar4' @@ -219,8 +219,8 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000011 // CHECK-NEXT: (('st_name', 0x00000010) # 'bar5' @@ -228,7 +228,7 @@ // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) Modified: llvm/trunk/test/Scripts/elf-dump URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Scripts/elf-dump?rev=122263&r1=122262&r2=122263&view=diff ============================================================================== --- llvm/trunk/test/Scripts/elf-dump (original) +++ llvm/trunk/test/Scripts/elf-dump Mon Dec 20 14:49:43 2010 @@ -121,8 +121,8 @@ print " ('st_other', %s)" % common_dump.HexDump(f.read8()) print " ('st_shndx', %s)" % common_dump.HexDump(f.read16()) if f.is64Bit: - print " ('st_value', %s)" % common_dump.HexDump(f.read64()) - print " ('st_size', %s)" % common_dump.HexDump(f.read64()) + print " ('st_value', %s)" % common_dump.HexDump(f.read64(), 64) + print " ('st_size', %s)" % common_dump.HexDump(f.read64(), 64) print " )," def dumpRel(f, section, dumprela = False): From baldrick at free.fr Mon Dec 20 14:54:37 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 20:54:37 -0000 Subject: [llvm-commits] [llvm] r122264 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Utils/CMakeLists.txt lib/Transforms/Utils/Utils.cpp Message-ID: <20101220205437.585452A6C12C@llvm.org> Author: baldrick Date: Mon Dec 20 14:54:37 2010 New Revision: 122264 URL: http://llvm.org/viewvc/llvm-project?rev=122264&view=rev Log: Add a new convenience pass for testing InstructionSimplify. Previously it could only be tested indirectly, via instcombine, gvn or some other pass that makes use of InstructionSimplify, which means that testcases had to be carefully contrived to dance around any other transformations that that pass did. Modified: llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Transforms/Utils/CMakeLists.txt llvm/trunk/lib/Transforms/Utils/Utils.cpp Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122264&r1=122263&r2=122264&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Mon Dec 20 14:54:37 2010 @@ -217,6 +217,7 @@ void initializeUnreachableMachineBlockElimPass(PassRegistry&); void initializeVerifierPass(PassRegistry&); void initializeVirtRegMapPass(PassRegistry&); +void initializeInstSimplifierPass(PassRegistry&); } Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=122264&r1=122263&r2=122264&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Dec 20 14:54:37 2010 @@ -147,6 +147,7 @@ (void) llvm::createLowerAtomicPass(); (void) llvm::createCorrelatedValuePropagationPass(); (void) llvm::createMemDepPrinter(); + (void) llvm::createInstructionSimplifierPass(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=122264&r1=122263&r2=122264&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Dec 20 14:54:37 2010 @@ -322,6 +322,13 @@ // Pass *createCorrelatedValuePropagationPass(); +//===----------------------------------------------------------------------===// +// +// InstructionSimplifier - Remove redundant instructions. +// +FunctionPass *createInstructionSimplifierPass(); +extern char &InstructionSimplifierID; + } // End llvm namespace #endif Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=122264&r1=122263&r2=122264&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Mon Dec 20 14:54:37 2010 @@ -21,6 +21,7 @@ PromoteMemoryToRegister.cpp SSAUpdater.cpp SimplifyCFG.cpp + SimplifyInstructions.cpp UnifyFunctionExitNodes.cpp Utils.cpp ValueMapper.cpp Modified: llvm/trunk/lib/Transforms/Utils/Utils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Utils.cpp?rev=122264&r1=122263&r2=122264&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Utils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Utils.cpp Mon Dec 20 14:54:37 2010 @@ -28,6 +28,7 @@ initializeLowerSwitchPass(Registry); initializePromotePassPass(Registry); initializeUnifyFunctionExitNodesPass(Registry); + initializeInstSimplifierPass(Registry); } /// LLVMInitializeTransformUtils - C binding for initializeTransformUtilsPasses. From baldrick at free.fr Mon Dec 20 15:07:43 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Dec 2010 21:07:43 -0000 Subject: [llvm-commits] [llvm] r122265 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20101220210743.1BDBA2A6C12C@llvm.org> Author: baldrick Date: Mon Dec 20 15:07:42 2010 New Revision: 122265 URL: http://llvm.org/viewvc/llvm-project?rev=122265&view=rev Log: Oops, forgot to add the pass itself! Added: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Added: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122265&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (added) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Mon Dec 20 15:07:42 2010 @@ -0,0 +1,69 @@ +//===------ SimplifyInstructions.cpp - Remove redundant instructions ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a utility pass used for testing the InstructionSimplify analysis. +// The analysis is applied to every instruction, and if it simplifies then the +// instruction is replaced by the simplification. If you are looking for a pass +// that performs serious instruction folding, use the instcombine pass instead. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "instsimplify" +#include "llvm/Function.h" +#include "llvm/Pass.h" +#include "llvm/Type.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Scalar.h" +using namespace llvm; + +STATISTIC(NumSimplified, "Number of redundant instructions removed"); + +namespace { + struct InstSimplifier : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + InstSimplifier() : FunctionPass(ID) { + initializeInstSimplifierPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + } + + /// runOnFunction - Remove instructions that simplify. + bool runOnFunction(Function &F) { + bool Changed = false; + const TargetData *TD = getAnalysisIfAvailable(); + const DominatorTree *DT = getAnalysisIfAvailable(); + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { + Instruction *I = BI++; + if (Value *V = SimplifyInstruction(I, TD, DT)) { + I->replaceAllUsesWith(V); + I->eraseFromParent(); + Changed = true; + ++NumSimplified; + } + } + return Changed; + } + }; +} + +char InstSimplifier::ID = 0; +INITIALIZE_PASS(InstSimplifier, "instsimplify", "Remove redundant instructions", + false, false) +char &llvm::InstructionSimplifierID = InstSimplifier::ID; + +// Public interface to the simplify instructions pass. +FunctionPass *llvm::createInstructionSimplifierPass() { + return new InstSimplifier(); +} From isanbard at gmail.com Mon Dec 20 15:14:19 2010 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 20 Dec 2010 21:14:19 -0000 Subject: [llvm-commits] [llvm] r122267 - /llvm/trunk/include/llvm/Support/PathV1.h Message-ID: <20101220211419.0B1682A6C12C@llvm.org> Author: void Date: Mon Dec 20 15:14:18 2010 New Revision: 122267 URL: http://llvm.org/viewvc/llvm-project?rev=122267&view=rev Log: This is still used and issuing an annoying warning. Don't deprecate something in the library unless *all* uses have been converted over to the new form. Modified: llvm/trunk/include/llvm/Support/PathV1.h Modified: llvm/trunk/include/llvm/Support/PathV1.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PathV1.h?rev=122267&r1=122266&r2=122267&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PathV1.h (original) +++ llvm/trunk/include/llvm/Support/PathV1.h Mon Dec 20 15:14:18 2010 @@ -311,9 +311,9 @@ /// This function determines if the path name is absolute, as opposed to /// relative. /// @brief Determine if the path is absolute. - LLVM_ATTRIBUTE_DEPRECATED( - bool isAbsolute() const, - LLVMV_PATH_DEPRECATED_MSG(path::is_absolute)); +//FIXME: LLVM_ATTRIBUTE_DEPRECATED( + bool isAbsolute() const; +//FIXME: LLVMV_PATH_DEPRECATED_MSG(path::is_absolute)); /// This function determines if the path name is absolute, as opposed to /// relative. From rdivacky at freebsd.org Mon Dec 20 15:14:39 2010 From: rdivacky at freebsd.org (Roman Divacky) Date: Mon, 20 Dec 2010 21:14:39 -0000 Subject: [llvm-commits] [llvm] r122268 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/MC/ELF/set.s Message-ID: <20101220211439.C5E902A6C12C@llvm.org> Author: rdivacky Date: Mon Dec 20 15:14:39 2010 New Revision: 122268 URL: http://llvm.org/viewvc/llvm-project?rev=122268&view=rev Log: Set the value of absolute symbols. Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/test/MC/ELF/set.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122268&r1=122267&r2=122268&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Dec 20 15:14:39 2010 @@ -518,6 +518,15 @@ return Data.getCommonAlignment(); const MCSymbol &Symbol = Data.getSymbol(); + + if (Symbol.isAbsolute() && Symbol.isVariable()) { + if (const MCExpr *Value = Symbol.getVariableValue()) { + int64_t IntValue; + if (Value->EvaluateAsAbsolute(IntValue, Layout)) + return (uint64_t)IntValue; + } + } + if (!Symbol.isInSection()) return 0; Modified: llvm/trunk/test/MC/ELF/set.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/set.s?rev=122268&r1=122267&r2=122268&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/set.s (original) +++ llvm/trunk/test/MC/ELF/set.s Mon Dec 20 15:14:39 2010 @@ -1,5 +1,18 @@ // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s +// Test that we emit the correct value. + +.set kernbase,0xffffffff80000000 + +// CHECK: (('st_name', 0x00000001) # 'kernbase' +// CHECK-NEXT: ('st_bind', 0x00000000) +// CHECK-NEXT: ('st_type', 0x00000000) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x0000fff1) +// CHECK-NEXT: ('st_value', 0xffffffff80000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) +// CHECK-NEXT: ), + // Test that we accept .set of a symbol after it has been used in a statement. jmp foo @@ -11,7 +24,7 @@ .set foo2,bar2 // Test that there is an undefined reference to bar -// CHECK: (('st_name', 0x00000001) # 'bar' +// CHECK: (('st_name', 0x0000000a) # 'bar' // CHECK-NEXT: ('st_bind', 0x00000001) // CHECK-NEXT: ('st_type', 0x00000000) // CHECK-NEXT: ('st_other', 0x00000000) From peckw at wesleypeck.com Mon Dec 20 15:18:04 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Mon, 20 Dec 2010 21:18:04 -0000 Subject: [llvm-commits] [llvm] r122269 - in /llvm/trunk: lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp lib/Target/MBlaze/MBlazeInstrInfo.td test/MC/Disassembler/MBlaze/mblaze_special.txt Message-ID: <20101220211804.3BEED2A6C12C@llvm.org> Author: peckw Date: Mon Dec 20 15:18:04 2010 New Revision: 122269 URL: http://llvm.org/viewvc/llvm-project?rev=122269&view=rev Log: Teach the MBlaze disassembler to disassemble special purpose registers. Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td llvm/trunk/test/MC/Disassembler/MBlaze/mblaze_special.txt Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=122269&r1=122268&r2=122269&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon Dec 20 15:18:04 2010 @@ -69,8 +69,7 @@ } static int64_t getRS(uint32_t insn) { - int16_t val = (insn & 0x3FFF); - return val; + return MBlazeRegisterInfo::getSpecialRegisterFromNumbering(insn&0x3FFF); } static int64_t getIMM(uint32_t insn) { @@ -606,12 +605,12 @@ case MBlazeII::FRCS: instr.addOperand(MCOperand::CreateReg(getRD(insn))); - instr.addOperand(MCOperand::CreateImm(getRS(insn))); + instr.addOperand(MCOperand::CreateReg(getRS(insn))); break; case MBlazeII::FCRCS: + instr.addOperand(MCOperand::CreateReg(getRS(insn))); instr.addOperand(MCOperand::CreateReg(getRA(insn))); - instr.addOperand(MCOperand::CreateImm(getRS(insn))); break; case MBlazeII::FCRCX: Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122269&r1=122268&r2=122269&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Mon Dec 20 15:18:04 2010 @@ -599,11 +599,15 @@ //===----------------------------------------------------------------------===// // Misc. instructions //===----------------------------------------------------------------------===// -def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins SPR:$src), - "mfs $dst, $src", [], IIAlu>; +let Form=FRCS in { + def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins SPR:$src), + "mfs $dst, $src", [], IIAlu>; +} -def MTS : SPC<0x25, 0x3, (outs SPR:$dst), (ins GPR:$src), - "mts $dst, $src", [], IIAlu>; +let Form=FCRCS in { + def MTS : SPC<0x25, 0x3, (outs SPR:$dst), (ins GPR:$src), + "mts $dst, $src", [], IIAlu>; +} def MSRSET : MSR<0x25, 0x20, (outs GPR:$dst), (ins uimm15:$set), "msrset $dst, $set", [], IIAlu>; Modified: llvm/trunk/test/MC/Disassembler/MBlaze/mblaze_special.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/MBlaze/mblaze_special.txt?rev=122269&r1=122268&r2=122269&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/MBlaze/mblaze_special.txt (original) +++ llvm/trunk/test/MC/Disassembler/MBlaze/mblaze_special.txt Mon Dec 20 15:18:04 2010 @@ -4,7 +4,7 @@ # Special instructions ################################################################################ -# CHECK: mfs r0, 0 +# CHECK: mfs r0, rpc 0x94 0x00 0x80 0x00 # CHECK: msrclr r0, 0 @@ -13,7 +13,7 @@ # CHECK: msrset r0, 0 0x94 0x10 0x00 0x00 -# CHECK: mts 0, r0 +# CHECK: mts rpc, r0 0x94 0x00 0xc0 0x00 # CHECK: wdc r0, r1 @@ -27,3 +27,79 @@ # CHECK: wic r0, r1 0x90 0x00 0x08 0x68 + +################################################################################ +# Special registers +################################################################################ + +# CHECK: mfs r1, rpc +0x94 0x20 0x80 0x00 + +# CHECK: mfs r1, rmsr +0x94 0x20 0x80 0x01 + +# CHECK: mfs r1, rear +0x94 0x20 0x80 0x03 + +# CHECK: mfs r1, resr +0x94 0x20 0x80 0x05 + +# CHECK: mfs r1, rfsr +0x94 0x20 0x80 0x07 + +# CHECK: mfs r1, rbtr +0x94 0x20 0x80 0x0b + +# CHECK: mfs r1, redr +0x94 0x20 0x80 0x0d + +# CHECK: mfs r1, rpid +0x94 0x20 0x90 0x00 + +# CHECK: mfs r1, rzpr +0x94 0x20 0x90 0x01 + +# CHECK: mfs r1, rtlbx +0x94 0x20 0x90 0x02 + +# CHECK: mfs r1, rtlbhi +0x94 0x20 0x90 0x04 + +# CHECK: mfs r1, rtlblo +0x94 0x20 0x90 0x03 + +# CHECK: mfs r1, rpvr0 +0x94 0x20 0xa0 0x00 + +# CHECK: mfs r1, rpvr1 +0x94 0x20 0xa0 0x01 + +# CHECK: mfs r1, rpvr2 +0x94 0x20 0xa0 0x02 + +# CHECK: mfs r1, rpvr3 +0x94 0x20 0xa0 0x03 + +# CHECK: mfs r1, rpvr4 +0x94 0x20 0xa0 0x04 + +# CHECK: mfs r1, rpvr5 +0x94 0x20 0xa0 0x05 + +# CHECK: mfs r1, rpvr6 +0x94 0x20 0xa0 0x06 + +# CHECK: mfs r1, rpvr7 +0x94 0x20 0xa0 0x07 + +# CHECK: mfs r1, rpvr8 +0x94 0x20 0xa0 0x08 + +# CHECK: mfs r1, rpvr9 +0x94 0x20 0xa0 0x09 + +# CHECK: mfs r1, rpvr10 +0x94 0x20 0xa0 0x0a + +# CHECK: mfs r1, rpvr11 +0x94 0x20 0xa0 0x0b From resistor at mac.com Mon Dec 20 15:30:54 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 21:30:54 -0000 Subject: [llvm-commits] [llvm] r122273 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20101220213054.BD6C32A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 15:30:54 2010 New Revision: 122273 URL: http://llvm.org/viewvc/llvm-project?rev=122273&view=rev Log: Convert one of LVI's primary maps to a DenseMap, now that we know are more assured of iterator stability. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122273&r1=122272&r2=122273&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Dec 20 15:30:54 2010 @@ -287,6 +287,21 @@ //===----------------------------------------------------------------------===// namespace { + /// LVIValueHandle - A callback value handle update the cache when + /// values are erased. + class LazyValueInfoCache; + struct LVIValueHandle : public CallbackVH { + LazyValueInfoCache *Parent; + + LVIValueHandle(Value *V, LazyValueInfoCache *P) + : CallbackVH(V), Parent(P) { } + + void deleted(); + void allUsesReplacedWith(Value *V) { + deleted(); + } + }; + /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { @@ -297,19 +312,7 @@ typedef std::map, LVILatticeVal> ValueCacheEntryTy; private: - /// LVIValueHandle - A callback value handle update the cache when - /// values are erased. - struct LVIValueHandle : public CallbackVH { - LazyValueInfoCache *Parent; - - LVIValueHandle(Value *V, LazyValueInfoCache *P) - : CallbackVH(V), Parent(P) { } - - void deleted(); - void allUsesReplacedWith(Value *V) { - deleted(); - } - }; + friend struct LVIValueHandle; /// OverDefinedCacheUpdater - A helper object that ensures that the /// OverDefinedCache is updated whenever solveBlockValue returns. @@ -332,7 +335,7 @@ /// ValueCache - This is all of the cached information for all values, /// mapped from Value* to key information. - std::map ValueCache; + DenseMap ValueCache; /// OverDefinedCache - This tracks, on a per-block basis, the set of /// values that are over-defined at the end of that block. This is required @@ -389,7 +392,28 @@ }; } // end anonymous namespace -void LazyValueInfoCache::LVIValueHandle::deleted() { +namespace llvm { + template<> + struct DenseMapInfo { + typedef DenseMapInfo PointerInfo; + static inline LVIValueHandle getEmptyKey() { + return LVIValueHandle(PointerInfo::getEmptyKey(), + static_cast(0)); + } + static inline LVIValueHandle getTombstoneKey() { + return LVIValueHandle(PointerInfo::getTombstoneKey(), + static_cast(0)); + } + static unsigned getHashValue(const LVIValueHandle &Val) { + return PointerInfo::getHashValue(Val); + } + static bool isEqual(const LVIValueHandle &LHS, const LVIValueHandle &RHS) { + return LHS == RHS; + } + }; +} + +void LVIValueHandle::deleted() { for (std::set, Value*> >::iterator I = Parent->OverDefinedCache.begin(), E = Parent->OverDefinedCache.end(); @@ -414,7 +438,7 @@ OverDefinedCache.erase(tmp); } - for (std::map::iterator + for (DenseMap::iterator I = ValueCache.begin(), E = ValueCache.end(); I != E; ++I) I->second.erase(BB); } From gkistanova at gmail.com Mon Dec 20 15:43:45 2010 From: gkistanova at gmail.com (Galina Kistanova) Date: Mon, 20 Dec 2010 13:43:45 -0800 Subject: [llvm-commits] Llvm-gcc windows slaves are back to work now. Message-ID: Hello, Slaves llvm-gcc-native-mingw32 and llvm-gcc-mingw32-win7 are back to normal work now. Thanks Galina From peckw at wesleypeck.com Mon Dec 20 15:54:50 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Mon, 20 Dec 2010 21:54:50 -0000 Subject: [llvm-commits] [llvm] r122276 - /llvm/trunk/docs/CodeGenerator.html Message-ID: <20101220215451.2F3542A6C12C@llvm.org> Author: peckw Date: Mon Dec 20 15:54:50 2010 New Revision: 122276 URL: http://llvm.org/viewvc/llvm-project?rev=122276&view=rev Log: Update the target feature matrix to reflect some new features in the MBlaze backend. 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=122276&r1=122275&r2=122276&view=diff ============================================================================== --- llvm/trunk/docs/CodeGenerator.html (original) +++ llvm/trunk/docs/CodeGenerator.html Mon Dec 20 15:54:50 2010 @@ -2122,7 +2122,7 @@ - + @@ -2139,7 +2139,7 @@ - + @@ -2156,7 +2156,7 @@ - + @@ -2190,7 +2190,7 @@ - + From natebegeman at mac.com Mon Dec 20 16:04:25 2010 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 20 Dec 2010 22:04:25 -0000 Subject: [llvm-commits] [llvm] r122277 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86ISelLowering.h X86InstrFragmentsSIMD.td X86InstrSSE.td Message-ID: <20101220220425.541E22A6C12C@llvm.org> Author: sampo Date: Mon Dec 20 16:04:24 2010 New Revision: 122277 URL: http://llvm.org/viewvc/llvm-project?rev=122277&view=rev Log: Implement feedback from Bruno on making pblendvb an x86-specific ISD node in addition to being an intrinsic, and convert lowering to use it. Hopefully the pattern fragment is doing the right thing with XMM0, looks correct in testing. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122277&r1=122276&r2=122277&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 20 16:04:24 2010 @@ -8398,9 +8398,7 @@ M = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), M, DAG.getConstant(4, MVT::i32)); - R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, - DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), - R, M, Op); + R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, R, M, Op); // a += a Op = DAG.getNode(ISD::ADD, dl, VT, Op, Op); @@ -8415,15 +8413,12 @@ M = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), M, DAG.getConstant(2, MVT::i32)); - R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, - DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), - R, M, Op); + R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, R, M, Op); // a += a Op = DAG.getNode(ISD::ADD, dl, VT, Op, Op); // return pblendv(r, r+r, a); - R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, - DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), + R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, R, DAG.getNode(ISD::ADD, dl, VT, R, R), Op); return R; } @@ -8897,6 +8892,7 @@ case X86ISD::PSIGNB: return "X86ISD::PSIGNB"; case X86ISD::PSIGNW: return "X86ISD::PSIGNW"; case X86ISD::PSIGND: return "X86ISD::PSIGND"; + case X86ISD::PBLENDVB: return "X86ISD::PBLENDVB"; case X86ISD::FMAX: return "X86ISD::FMAX"; case X86ISD::FMIN: return "X86ISD::FMIN"; case X86ISD::FRSQRT: return "X86ISD::FRSQRT"; @@ -11209,12 +11205,10 @@ if (!Subtarget->hasSSE41()) return SDValue(); - unsigned IID = Intrinsic::x86_sse41_pblendvb; X = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, X); Y = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Y); Mask = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Mask); - Mask = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v16i8, - DAG.getConstant(IID, MVT::i32), X, Y, Mask); + Mask = DAG.getNode(X86ISD::PBLENDVB, DL, MVT::v16i8, X, Y, Mask); return DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Mask); } } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=122277&r1=122276&r2=122277&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec 20 16:04:24 2010 @@ -166,6 +166,9 @@ /// PSIGNB/W/D - Copy integer sign. PSIGNB, PSIGNW, PSIGND, + /// PBLENDVB - Variable blend + PBLENDVB, + /// FMAX, FMIN - Floating point max and min. /// FMAX, FMIN, Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=122277&r1=122276&r2=122277&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Mon Dec 20 16:04:24 2010 @@ -55,6 +55,9 @@ def X86psignd : SDNode<"X86ISD::PSIGND", SDTypeProfile<1, 2, [SDTCisVT<0, v4i32>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]>>; +def X86pblendv : SDNode<"X86ISD::PBLENDVB", + SDTypeProfile<1, 3, [SDTCisVT<0, v16i8>, SDTCisSameAs<0,1>, + SDTCisSameAs<0,2>, SDTCisSameAs<0,3>]>>; def X86pextrb : SDNode<"X86ISD::PEXTRB", SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisPtrTy<2>]>>; def X86pextrw : SDNode<"X86ISD::PEXTRW", Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=122277&r1=122276&r2=122277&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Dec 20 16:04:24 2010 @@ -4855,6 +4855,9 @@ defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", int_x86_sse41_blendvps>; defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", int_x86_sse41_pblendvb>; +def : Pat<(X86pblendv VR128:$src1, VR128:$src2, XMM0), + (PBLENDVBrr0 VR128:$src1, VR128:$src2)>; + let isAsmParserOnly = 1, Predicates = [HasAVX] in def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}", From fvbommel at gmail.com Mon Dec 20 16:19:13 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 20 Dec 2010 23:19:13 +0100 Subject: [llvm-commits] [llvm] r122265 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <20101220210743.1BDBA2A6C12C@llvm.org> References: <20101220210743.1BDBA2A6C12C@llvm.org> Message-ID: On Mon, Dec 20, 2010 at 10:07 PM, Duncan Sands wrote: > + ? ?bool runOnFunction(Function &F) { > + ? ? ?bool Changed = false; > + ? ? ?const TargetData *TD = getAnalysisIfAvailable(); > + ? ? ?const DominatorTree *DT = getAnalysisIfAvailable(); > + ? ? ?for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) > + ? ? ? ?for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { > + ? ? ? ? ?Instruction *I = BI++; > + ? ? ? ? ?if (Value *V = SimplifyInstruction(I, TD, DT)) { > + ? ? ? ? ? ?I->replaceAllUsesWith(V); > + ? ? ? ? ? ?I->eraseFromParent(); > + ? ? ? ? ? ?Changed = true; > + ? ? ? ? ? ?++NumSimplified; > + ? ? ? ? ?} > + ? ? ? ?} > + ? ? ?return Changed; > + ? ?} I know this is intended primarily for testing, but maybe this should iterate until no changes were made just to be thorough? Or use a worklist so users of replaced values are re-examined later? Currently this pass depends on basic blocks order; IIRC SimplifyInstruction assumes the operands have already been simplified, which currently isn't necessarily the case if blocks don't happen to be topologically sorted (with respect to domination). From resistor at mac.com Mon Dec 20 16:28:04 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 22:28:04 -0000 Subject: [llvm-commits] [llvm] r122279 - in /llvm/trunk: include/llvm/Support/ValueHandle.h include/llvm/Value.h lib/VMCore/Value.cpp Message-ID: <20101220222804.19E602A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 16:28:03 2010 New Revision: 122279 URL: http://llvm.org/viewvc/llvm-project?rev=122279&view=rev Log: Revert r122114 (CallbackVH observing use-list changes) because it caused severe slowdowns on the Linux self-host configuration. Modified: llvm/trunk/include/llvm/Support/ValueHandle.h llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/include/llvm/Support/ValueHandle.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ValueHandle.h?rev=122279&r1=122278&r2=122279&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ValueHandle.h (original) +++ llvm/trunk/include/llvm/Support/ValueHandle.h Mon Dec 20 16:28:03 2010 @@ -105,7 +105,6 @@ // Callbacks made from Value. static void ValueIsDeleted(Value *V); static void ValueIsRAUWd(Value *Old, Value *New); - static void ValueAddedUse(Use &U); // Internal implementation details. ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); } @@ -390,11 +389,6 @@ /// implemented as a CallbackVH, it would use this method to call /// setValPtr(new_value). AssertingVH would do nothing in this method. virtual void allUsesReplacedWith(Value *) {} - - /// Called when a new Use is added to the use-list of this->getValPtr(), - /// after the Use has been appended to the list. Other VH kinds would ignore - /// this callback, but clients can use it to trigger re-analysis of Values. - virtual void addedUse(Use &) {} }; // Specialize simplify_type to allow CallbackVH to participate in Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=122279&r1=122278&r2=122279&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Mon Dec 20 16:28:03 2010 @@ -195,7 +195,7 @@ /// addUse - This method should only be used by the Use class. /// - void addUse(Use &U); + void addUse(Use &U) { U.addToList(&UseList); } /// An enumeration for keeping track of the concrete subclass of Value that /// is actually instantiated. Values of this enumeration are kept in the Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=122279&r1=122278&r2=122279&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Mon Dec 20 16:28:03 2010 @@ -281,16 +281,6 @@ } -/// addUse - This method should only be used by the Use class. -/// -void Value::addUse(Use &U) { - U.addToList(&UseList); - - // Notify all ValueHandles (if present) that this value added a Use. - if (HasValueHandle) - ValueHandleBase::ValueAddedUse(U); -} - // uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith, // except that it doesn't have all of the asserts. The asserts fail because we // are half-way done resolving types, which causes some types to exist as two @@ -579,34 +569,6 @@ } } -void ValueHandleBase::ValueAddedUse(Use &U) { - assert(U->HasValueHandle && "Should only be called if ValueHandles present"); - - // Get the linked list base, which is guaranteed to exist since the - // HasValueHandle flag is set. - LLVMContextImpl *pImpl = U->getContext().pImpl; - ValueHandleBase *Entry = pImpl->ValueHandles[U.get()]; - - assert(Entry && "Value bit set but no entries exist"); - - // We use a local ValueHandleBase as an iterator so that - // ValueHandles can add and remove themselves from the list without - // breaking our iteration. This is not really an AssertingVH; we - // just have to give ValueHandleBase some kind. - for (ValueHandleBase Iterator(Assert, *Entry); Entry; Entry = Iterator.Next) { - Iterator.RemoveFromUseList(); - Iterator.AddToExistingUseListAfter(Entry); - assert(Entry->Next == &Iterator && "Loop invariant broken."); - - switch (Entry->getKind()) { - default: - break; - case Callback: - static_cast(Entry)->addedUse(U); - break; - } - } -} void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { assert(Old->HasValueHandle &&"Should only be called if ValueHandles present"); From resistor at mac.com Mon Dec 20 17:23:18 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 23:23:18 -0000 Subject: [llvm-commits] [llvm] r122288 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20101220232318.8CAE72A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 17:23:18 2010 New Revision: 122288 URL: http://llvm.org/viewvc/llvm-project?rev=122288&view=rev Log: Attempt to appease the DragonEgg buildbots. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122288&r1=122287&r2=122288&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Dec 20 17:23:18 2010 @@ -301,7 +301,30 @@ deleted(); } }; - +} + +namespace llvm { + template<> + struct DenseMapInfo { + typedef DenseMapInfo PointerInfo; + static inline LVIValueHandle getEmptyKey() { + return LVIValueHandle(PointerInfo::getEmptyKey(), + static_cast(0)); + } + static inline LVIValueHandle getTombstoneKey() { + return LVIValueHandle(PointerInfo::getTombstoneKey(), + static_cast(0)); + } + static unsigned getHashValue(const LVIValueHandle &Val) { + return PointerInfo::getHashValue(Val); + } + static bool isEqual(const LVIValueHandle &LHS, const LVIValueHandle &RHS) { + return LHS == RHS; + } + }; +} + +namespace { /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { @@ -392,27 +415,6 @@ }; } // end anonymous namespace -namespace llvm { - template<> - struct DenseMapInfo { - typedef DenseMapInfo PointerInfo; - static inline LVIValueHandle getEmptyKey() { - return LVIValueHandle(PointerInfo::getEmptyKey(), - static_cast(0)); - } - static inline LVIValueHandle getTombstoneKey() { - return LVIValueHandle(PointerInfo::getTombstoneKey(), - static_cast(0)); - } - static unsigned getHashValue(const LVIValueHandle &Val) { - return PointerInfo::getHashValue(Val); - } - static bool isEqual(const LVIValueHandle &LHS, const LVIValueHandle &RHS) { - return LHS == RHS; - } - }; -} - void LVIValueHandle::deleted() { for (std::set, Value*> >::iterator I = Parent->OverDefinedCache.begin(), From resistor at mac.com Mon Dec 20 17:53:19 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 20 Dec 2010 23:53:19 -0000 Subject: [llvm-commits] [llvm] r122291 - /llvm/trunk/lib/Analysis/LazyValueInfo.cpp Message-ID: <20101220235319.ADFDC2A6C12C@llvm.org> Author: resistor Date: Mon Dec 20 17:53:19 2010 New Revision: 122291 URL: http://llvm.org/viewvc/llvm-project?rev=122291&view=rev Log: Speculatively revert the use of DenseMap in LazyValueInfo, which may be causing Linux self-host failures. Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=122291&r1=122290&r2=122291&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Dec 20 17:53:19 2010 @@ -287,44 +287,6 @@ //===----------------------------------------------------------------------===// namespace { - /// LVIValueHandle - A callback value handle update the cache when - /// values are erased. - class LazyValueInfoCache; - struct LVIValueHandle : public CallbackVH { - LazyValueInfoCache *Parent; - - LVIValueHandle(Value *V, LazyValueInfoCache *P) - : CallbackVH(V), Parent(P) { } - - void deleted(); - void allUsesReplacedWith(Value *V) { - deleted(); - } - }; -} - -namespace llvm { - template<> - struct DenseMapInfo { - typedef DenseMapInfo PointerInfo; - static inline LVIValueHandle getEmptyKey() { - return LVIValueHandle(PointerInfo::getEmptyKey(), - static_cast(0)); - } - static inline LVIValueHandle getTombstoneKey() { - return LVIValueHandle(PointerInfo::getTombstoneKey(), - static_cast(0)); - } - static unsigned getHashValue(const LVIValueHandle &Val) { - return PointerInfo::getHashValue(Val); - } - static bool isEqual(const LVIValueHandle &LHS, const LVIValueHandle &RHS) { - return LHS == RHS; - } - }; -} - -namespace { /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { @@ -335,7 +297,19 @@ typedef std::map, LVILatticeVal> ValueCacheEntryTy; private: - friend struct LVIValueHandle; + /// LVIValueHandle - A callback value handle update the cache when + /// values are erased. + struct LVIValueHandle : public CallbackVH { + LazyValueInfoCache *Parent; + + LVIValueHandle(Value *V, LazyValueInfoCache *P) + : CallbackVH(V), Parent(P) { } + + void deleted(); + void allUsesReplacedWith(Value *V) { + deleted(); + } + }; /// OverDefinedCacheUpdater - A helper object that ensures that the /// OverDefinedCache is updated whenever solveBlockValue returns. @@ -358,7 +332,7 @@ /// ValueCache - This is all of the cached information for all values, /// mapped from Value* to key information. - DenseMap ValueCache; + std::map ValueCache; /// OverDefinedCache - This tracks, on a per-block basis, the set of /// values that are over-defined at the end of that block. This is required @@ -415,7 +389,7 @@ }; } // end anonymous namespace -void LVIValueHandle::deleted() { +void LazyValueInfoCache::LVIValueHandle::deleted() { for (std::set, Value*> >::iterator I = Parent->OverDefinedCache.begin(), E = Parent->OverDefinedCache.end(); @@ -440,7 +414,7 @@ OverDefinedCache.erase(tmp); } - for (DenseMap::iterator + for (std::map::iterator I = ValueCache.begin(), E = ValueCache.end(); I != E; ++I) I->second.erase(BB); } From stoklund at 2pi.dk Mon Dec 20 18:04:46 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 21 Dec 2010 00:04:46 -0000 Subject: [llvm-commits] [llvm] r122293 - in /llvm/trunk: include/llvm/ADT/IntEqClasses.h lib/Support/CMakeLists.txt lib/Support/IntEqClasses.cpp unittests/ADT/IntEqClassesTest.cpp unittests/CMakeLists.txt Message-ID: <20101221000446.E44EB2A6C12C@llvm.org> Author: stoklund Date: Mon Dec 20 18:04:46 2010 New Revision: 122293 URL: http://llvm.org/viewvc/llvm-project?rev=122293&view=rev Log: Add ADT/IntEqClasses.h as a light-weight implementation of EquivalenceClasses.h. This implementation already exists as ConnectedVNInfoEqClasses in LiveInterval.cpp, and it seems to be generally useful to have a light-weight way of forming equivalence classes of small integers. IntEqClasses doesn't allow enumeration of the elements in a class. Added: llvm/trunk/include/llvm/ADT/IntEqClasses.h llvm/trunk/lib/Support/IntEqClasses.cpp llvm/trunk/unittests/ADT/IntEqClassesTest.cpp Modified: llvm/trunk/lib/Support/CMakeLists.txt llvm/trunk/unittests/CMakeLists.txt Added: llvm/trunk/include/llvm/ADT/IntEqClasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntEqClasses.h?rev=122293&view=auto ============================================================================== --- llvm/trunk/include/llvm/ADT/IntEqClasses.h (added) +++ llvm/trunk/include/llvm/ADT/IntEqClasses.h Mon Dec 20 18:04:46 2010 @@ -0,0 +1,81 @@ +//===-- llvm/ADT/IntEqClasses.h - Equiv. Classes of Integers ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Equivalence classes for small integers. This is a mapping of the integers +// 0 .. N-1 into M equivalence classes numbered 0 .. M-1. +// +// Initially each integer has its own equivalence class. Classes are joined by +// passing a representative member of each class to join(). +// +// Once the classes are built, compress() will number them 0 .. M-1 and prevent +// further changes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_INTEQCLASSES_H +#define LLVM_ADT_INTEQCLASSES_H + +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +class IntEqClasses { + /// EC - When uncompressed, map each integer to a smaller member of its + /// equivalence class. The class leader is the smallest member and maps to + /// itself. + /// + /// When compressed, EC[i] is the equivalence class of i. + SmallVector EC; + + /// NumClasses - The number of equivalence classes when compressed, or 0 when + /// uncompressed. + unsigned NumClasses; + +public: + /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1. + IntEqClasses(unsigned N) : NumClasses(0) { grow(N); } + + /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique + /// equivalence classes. + /// This requires an uncompressed map. + void grow(unsigned N); + + /// join - Join the equivalence classes of a and b. After joining classes, + /// findLeader(a) == findLeader(b). + /// This requires an uncompressed map. + void join(unsigned a, unsigned b); + + /// findLeader - Compute the leader of a's equivalence class. This is the + /// smallest member of the class. + /// This requires an uncompressed map. + unsigned findLeader(unsigned a) const; + + /// compress - Compress equivalence classes by numbering them 0 .. M. + /// This makes the equivalence class map immutable. + void compress(); + + /// getNumClasses - Return the number of equivalence classes after compress() + /// was called. + unsigned getNumClasses() const { return NumClasses; } + + /// operator[] - Return a's equivalence class number, 0 .. getNumClasses()-1. + /// This requires a compressed map. + unsigned operator[](unsigned a) const { + assert(NumClasses && "operator[] called before compress()"); + return EC[a]; + } + + /// uncompress - Change back to the uncompressed representation that allows + /// editing. + void uncompress(); +}; + +} // End llvm namespace + +#endif Modified: llvm/trunk/lib/Support/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=122293&r1=122292&r2=122293&view=diff ============================================================================== --- llvm/trunk/lib/Support/CMakeLists.txt (original) +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Dec 20 18:04:46 2010 @@ -22,6 +22,7 @@ FoldingSet.cpp FormattedStream.cpp GraphWriter.cpp + IntEqClasses.cpp IntervalMap.cpp IsInf.cpp IsNAN.cpp Added: llvm/trunk/lib/Support/IntEqClasses.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/IntEqClasses.cpp?rev=122293&view=auto ============================================================================== --- llvm/trunk/lib/Support/IntEqClasses.cpp (added) +++ llvm/trunk/lib/Support/IntEqClasses.cpp Mon Dec 20 18:04:46 2010 @@ -0,0 +1,69 @@ +//===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Equivalence classes for small integers. This is a mapping of the integers +// 0 .. N-1 into M equivalence classes numbered 0 .. M-1. +// +// Initially each integer has its own equivalence class. Classes are joined by +// passing a representative member of each class to join(). +// +// Once the classes are built, compress() will number them 0 .. M-1 and prevent +// further changes. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/IntEqClasses.h" + +using namespace llvm; + +void IntEqClasses::grow(unsigned N) { + assert(NumClasses == 0 && "grow() called after compress()."); + while (EC.size() < N) + EC.push_back(EC.size()); +} + +void IntEqClasses::join(unsigned a, unsigned b) { + assert(NumClasses == 0 && "join() called after compress()."); + unsigned eca = EC[a]; + unsigned ecb = EC[b]; + // Update pointers while searching for the leaders, compressing the paths + // incrementally. The larger leader will eventually be updated, joining the + // classes. + while (eca != ecb) + if (eca < ecb) + EC[b] = eca, b = ecb, ecb = EC[b]; + else + EC[a] = ecb, a = eca, eca = EC[a]; +} + +unsigned IntEqClasses::findLeader(unsigned a) const { + assert(NumClasses == 0 && "findLeader() called after compress()."); + while (a != EC[a]) + a = EC[a]; + return a; +} + +void IntEqClasses::compress() { + if (NumClasses) + return; + for (unsigned i = 0, e = EC.size(); i != e; ++i) + EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]]; +} + +void IntEqClasses::uncompress() { + if (!NumClasses) + return; + SmallVector Leader; + for (unsigned i = 0, e = EC.size(); i != e; ++i) + if (EC[i] < Leader.size()) + EC[i] = Leader[EC[i]]; + else + Leader.push_back(EC[i] = i); + NumClasses = 0; +} Added: llvm/trunk/unittests/ADT/IntEqClassesTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IntEqClassesTest.cpp?rev=122293&view=auto ============================================================================== --- llvm/trunk/unittests/ADT/IntEqClassesTest.cpp (added) +++ llvm/trunk/unittests/ADT/IntEqClassesTest.cpp Mon Dec 20 18:04:46 2010 @@ -0,0 +1,107 @@ +//===---- ADT/IntEqClassesTest.cpp - IntEqClasses unit tests ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/IntEqClasses.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +TEST(IntEqClasses, Simple) { + IntEqClasses ec(10); + + ec.join(0, 1); + ec.join(3, 2); + ec.join(4, 5); + ec.join(7, 6); + + EXPECT_EQ(0u, ec.findLeader(0)); + EXPECT_EQ(0u, ec.findLeader(1)); + EXPECT_EQ(2u, ec.findLeader(2)); + EXPECT_EQ(2u, ec.findLeader(3)); + EXPECT_EQ(4u, ec.findLeader(4)); + EXPECT_EQ(4u, ec.findLeader(5)); + EXPECT_EQ(6u, ec.findLeader(6)); + EXPECT_EQ(6u, ec.findLeader(7)); + EXPECT_EQ(8u, ec.findLeader(8)); + EXPECT_EQ(9u, ec.findLeader(9)); + + // join two non-leaders. + ec.join(1, 3); + + EXPECT_EQ(0u, ec.findLeader(0)); + EXPECT_EQ(0u, ec.findLeader(1)); + EXPECT_EQ(0u, ec.findLeader(2)); + EXPECT_EQ(0u, ec.findLeader(3)); + EXPECT_EQ(4u, ec.findLeader(4)); + EXPECT_EQ(4u, ec.findLeader(5)); + EXPECT_EQ(6u, ec.findLeader(6)); + EXPECT_EQ(6u, ec.findLeader(7)); + EXPECT_EQ(8u, ec.findLeader(8)); + EXPECT_EQ(9u, ec.findLeader(9)); + + // join two leaders. + ec.join(4, 8); + + EXPECT_EQ(0u, ec.findLeader(0)); + EXPECT_EQ(0u, ec.findLeader(1)); + EXPECT_EQ(0u, ec.findLeader(2)); + EXPECT_EQ(0u, ec.findLeader(3)); + EXPECT_EQ(4u, ec.findLeader(4)); + EXPECT_EQ(4u, ec.findLeader(5)); + EXPECT_EQ(6u, ec.findLeader(6)); + EXPECT_EQ(6u, ec.findLeader(7)); + EXPECT_EQ(4u, ec.findLeader(8)); + EXPECT_EQ(9u, ec.findLeader(9)); + + // join mixed. + ec.join(9, 1); + + EXPECT_EQ(0u, ec.findLeader(0)); + EXPECT_EQ(0u, ec.findLeader(1)); + EXPECT_EQ(0u, ec.findLeader(2)); + EXPECT_EQ(0u, ec.findLeader(3)); + EXPECT_EQ(4u, ec.findLeader(4)); + EXPECT_EQ(4u, ec.findLeader(5)); + EXPECT_EQ(6u, ec.findLeader(6)); + EXPECT_EQ(6u, ec.findLeader(7)); + EXPECT_EQ(4u, ec.findLeader(8)); + EXPECT_EQ(0u, ec.findLeader(9)); + + // compressed map. + ec.compress(); + EXPECT_EQ(3u, ec.getNumClasses()); + + EXPECT_EQ(0u, ec[0]); + EXPECT_EQ(0u, ec[1]); + EXPECT_EQ(0u, ec[2]); + EXPECT_EQ(0u, ec[3]); + EXPECT_EQ(1u, ec[4]); + EXPECT_EQ(1u, ec[5]); + EXPECT_EQ(2u, ec[6]); + EXPECT_EQ(2u, ec[7]); + EXPECT_EQ(1u, ec[8]); + EXPECT_EQ(0u, ec[9]); + + // uncompressed map. + ec.uncompress(); + EXPECT_EQ(0u, ec.findLeader(0)); + EXPECT_EQ(0u, ec.findLeader(1)); + EXPECT_EQ(0u, ec.findLeader(2)); + EXPECT_EQ(0u, ec.findLeader(3)); + EXPECT_EQ(4u, ec.findLeader(4)); + EXPECT_EQ(4u, ec.findLeader(5)); + EXPECT_EQ(6u, ec.findLeader(6)); + EXPECT_EQ(6u, ec.findLeader(7)); + EXPECT_EQ(4u, ec.findLeader(8)); + EXPECT_EQ(0u, ec.findLeader(9)); +} + +} // end anonymous namespace Modified: llvm/trunk/unittests/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CMakeLists.txt?rev=122293&r1=122292&r2=122293&view=diff ============================================================================== --- llvm/trunk/unittests/CMakeLists.txt (original) +++ llvm/trunk/unittests/CMakeLists.txt Mon Dec 20 18:04:46 2010 @@ -54,6 +54,7 @@ ADT/FoldingSet.cpp ADT/ilistTest.cpp ADT/ImmutableSetTest.cpp + ADT/IntEqClassesTest.cpp ADT/IntervalMapTest.cpp ADT/SmallBitVectorTest.cpp ADT/SmallStringTest.cpp From stoklund at 2pi.dk Mon Dec 20 18:48:17 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 21 Dec 2010 00:48:17 -0000 Subject: [llvm-commits] [llvm] r122296 - in /llvm/trunk: include/llvm/ADT/IntEqClasses.h include/llvm/CodeGen/LiveInterval.h lib/CodeGen/LiveInterval.cpp lib/Support/IntEqClasses.cpp Message-ID: <20101221004817.CE7452A6C12C@llvm.org> Author: stoklund Date: Mon Dec 20 18:48:17 2010 New Revision: 122296 URL: http://llvm.org/viewvc/llvm-project?rev=122296&view=rev Log: Use IntEqClasses to compute connected components of live intervals. Modified: llvm/trunk/include/llvm/ADT/IntEqClasses.h llvm/trunk/include/llvm/CodeGen/LiveInterval.h llvm/trunk/lib/CodeGen/LiveInterval.cpp llvm/trunk/lib/Support/IntEqClasses.cpp Modified: llvm/trunk/include/llvm/ADT/IntEqClasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntEqClasses.h?rev=122296&r1=122295&r2=122296&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/IntEqClasses.h (original) +++ llvm/trunk/include/llvm/ADT/IntEqClasses.h Mon Dec 20 18:48:17 2010 @@ -39,13 +39,20 @@ public: /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1. - IntEqClasses(unsigned N) : NumClasses(0) { grow(N); } + IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); } /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique /// equivalence classes. /// This requires an uncompressed map. void grow(unsigned N); + /// clear - Clear all classes so that grow() will assign a unique class to + /// every integer. + void clear() { + EC.clear(); + NumClasses = 0; + } + /// join - Join the equivalence classes of a and b. After joining classes, /// findLeader(a) == findLeader(b). /// This requires an uncompressed map. Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=122296&r1=122295&r2=122296&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Mon Dec 20 18:48:17 2010 @@ -21,7 +21,7 @@ #ifndef LLVM_CODEGEN_LIVEINTERVAL_H #define LLVM_CODEGEN_LIVEINTERVAL_H -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/IntEqClasses.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/AlignOf.h" #include "llvm/CodeGen/SlotIndexes.h" @@ -561,11 +561,7 @@ class ConnectedVNInfoEqClasses { LiveIntervals &lis_; - - // Map each value number to its equivalence class. - // The invariant is that EqClass[x] <= x. - // Two values are connected iff EqClass[x] == EqClass[b]. - SmallVector eqClass_; + IntEqClasses eqClass_; // Note that values a and b are connected. void Connect(unsigned a, unsigned b); Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=122296&r1=122295&r2=122296&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Mon Dec 20 18:48:17 2010 @@ -703,42 +703,10 @@ os << *this; } -/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a -/// LiveInterval into equivalence clases of connected components. A -/// LiveInterval that has multiple connected components can be broken into -/// multiple LiveIntervals. - -void ConnectedVNInfoEqClasses::Connect(unsigned a, unsigned b) { - while (eqClass_[a] != eqClass_[b]) { - if (eqClass_[a] > eqClass_[b]) - std::swap(a, b); - unsigned t = eqClass_[b]; - assert(t <= b && "Invariant broken"); - eqClass_[b] = eqClass_[a]; - b = t; - } -} - -unsigned ConnectedVNInfoEqClasses::Renumber() { - // Assign final class numbers. - // We use the fact that eqClass_[i] == i for class leaders. - // For others, eqClass_[i] points to an earlier value in the same class. - unsigned count = 0; - for (unsigned i = 0, e = eqClass_.size(); i != e; ++i) { - unsigned q = eqClass_[i]; - assert(q <= i && "Invariant broken"); - eqClass_[i] = q == i ? count++ : eqClass_[q]; - } - - return count; -} - unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { // Create initial equivalence classes. eqClass_.clear(); - eqClass_.reserve(LI->getNumValNums()); - for (unsigned i = 0, e = LI->getNumValNums(); i != e; ++i) - eqClass_.push_back(i); + eqClass_.grow(LI->getNumValNums()); const VNInfo *used = 0, *unused = 0; @@ -749,7 +717,7 @@ // Group all unused values into one class. if (VNI->isUnused()) { if (unused) - Connect(unused->id, VNI->id); + eqClass_.join(unused->id, VNI->id); unused = VNI; continue; } @@ -762,36 +730,28 @@ PE = MBB->pred_end(); PI != PE; ++PI) if (const VNInfo *PVNI = LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot())) - Connect(VNI->id, PVNI->id); + eqClass_.join(VNI->id, PVNI->id); } else { // Normal value defined by an instruction. Check for two-addr redef. // FIXME: This could be coincidental. Should we really check for a tied // operand constraint? - if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getUseIndex())) - Connect(VNI->id, UVNI->id); - - // Check for a tied operand constraint involving an early clobber def, - // where one VN ends right before the use index and the next VN is defined - // at the same use index. - if (VNI->def.isUse()) { - if (const VNInfo *PVNI = LI->getVNInfoAt(VNI->def.getLoadIndex())) - Connect(PVNI->id, VNI->id); - } + // Note that VNI->def may be a use slot for an early clobber def. + if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot())) + eqClass_.join(VNI->id, UVNI->id); } } // Lump all the unused values in with the last used value. if (used && unused) - Connect(used->id, unused->id); + eqClass_.join(used->id, unused->id); - return Renumber(); + eqClass_.compress(); + return eqClass_.getNumClasses(); } void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) { assert(LIV[0] && "LIV[0] must be set"); LiveInterval &LI = *LIV[0]; - // Check that they likely ran Classify() on LIV[0] first. - assert(eqClass_.size() == LI.getNumValNums() && "Bad classification data"); // First move runs to new intervals. LiveInterval::iterator J = LI.begin(), E = LI.end(); Modified: llvm/trunk/lib/Support/IntEqClasses.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/IntEqClasses.cpp?rev=122296&r1=122295&r2=122296&view=diff ============================================================================== --- llvm/trunk/lib/Support/IntEqClasses.cpp (original) +++ llvm/trunk/lib/Support/IntEqClasses.cpp Mon Dec 20 18:48:17 2010 @@ -24,6 +24,7 @@ void IntEqClasses::grow(unsigned N) { assert(NumClasses == 0 && "grow() called after compress()."); + EC.reserve(N); while (EC.size() < N) EC.push_back(EC.size()); } From aggarwa4 at illinois.edu Mon Dec 20 19:03:09 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 01:03:09 -0000 Subject: [llvm-commits] [poolalloc] r122298 - /poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <20101221010309.8D8442A6C12D@llvm.org> Author: aggarwa4 Date: Mon Dec 20 19:03:09 2010 New Revision: 122298 URL: http://llvm.org/viewvc/llvm-project?rev=122298&view=rev Log: A function might be visited multiple times, as we are creating FuncInfo using the call graph now. We must ensure, that we only count the args once. Hence, if a function already has a funcInfo, we do not modify it. Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=122298&r1=122297&r2=122298&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Mon Dec 20 19:03:09 2010 @@ -845,6 +845,12 @@ // for (unsigned index = 0; index < Functions.size(); ++index) { Function * F = (Function *) Functions[index]; + if (FunctionInfo.find (F) != FunctionInfo.end()) { + FuncInfo & FI = FunctionInfo.find(F)->second; + assert(FI.ArgNodes.size() == MarkedNodes.size()); + continue; + } + FuncInfo & FI = FunctionInfo.insert(std::make_pair(F, FuncInfo(*F))).first->second; // From aggarwa4 at illinois.edu Mon Dec 20 19:03:37 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 01:03:37 -0000 Subject: [llvm-commits] [poolalloc] r122299 - /poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Message-ID: <20101221010337.DE83A2A6C12D@llvm.org> Author: aggarwa4 Date: Mon Dec 20 19:03:37 2010 New Revision: 122299 URL: http://llvm.org/viewvc/llvm-project?rev=122299&view=rev Log: We must not attempt to poolallocate External or Unknown nodes. The runtime cannot handle this. Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp?rev=122299&r1=122298&r2=122299&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Mon Dec 20 19:03:37 2010 @@ -258,10 +258,7 @@ // Unknown nodes could be anything. // const DSNode *tmp = *Last; - if (!(tmp->isHeapNode() || - tmp->isExternalNode() || - tmp->isIncompleteNode() || - tmp->isUnknownNode())) + if (!(tmp->isHeapNode())) toRemove.push_back (tmp); } @@ -340,25 +337,6 @@ } // - // Scan through all the local graphs looking for DSNodes which may be - // reachable by a global. These nodes may not end up in the globals graph - // because of the fact that DSA doesn't actually know what is happening to - // them. - // - for (Module::iterator F = M->begin(); F != M->end(); ++F) { - if (F->isDeclaration()) continue; - DSGraph* G = Graphs->getDSGraph(*F); - for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end(); - I != E; - ++I) { - DSNode * Node = I; - if (Node->isExternalNode() || Node->isUnknownNode()) { - GlobalHeapNodes.insert (Node); - } - } - } - - // // Copy the values into the output container. Note that DenseSet has no // iterator traits (or whatever allows us to treat DenseSet has a generic // container), so we have to use a loop to copy values from the DenseSet into From bruno.cardoso at gmail.com Mon Dec 20 19:18:43 2010 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Mon, 20 Dec 2010 23:18:43 -0200 Subject: [llvm-commits] [llvm] r122277 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86ISelLowering.h X86InstrFragmentsSIMD.td X86InstrSSE.td In-Reply-To: <20101220220425.541E22A6C12C@llvm.org> References: <20101220220425.541E22A6C12C@llvm.org> Message-ID: Thanks Nate! :) On Mon, Dec 20, 2010 at 8:04 PM, Nate Begeman wrote: > Author: sampo > Date: Mon Dec 20 16:04:24 2010 > New Revision: 122277 > > URL: http://llvm.org/viewvc/llvm-project?rev=122277&view=rev > Log: > Implement feedback from Bruno on making pblendvb an x86-specific ISD node in addition to being an intrinsic, and convert > lowering to use it. ?Hopefully the pattern fragment is doing the right thing with XMM0, looks correct in testing. > > Modified: > ? ?llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > ? ?llvm/trunk/lib/Target/X86/X86ISelLowering.h > ? ?llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td > ? ?llvm/trunk/lib/Target/X86/X86InstrSSE.td > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122277&r1=122276&r2=122277&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 20 16:04:24 2010 > @@ -8398,9 +8398,7 @@ > ? ? M = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, > ? ? ? ? ? ? ? ? ? ? DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), M, > ? ? ? ? ? ? ? ? ? ? DAG.getConstant(4, MVT::i32)); > - ? ?R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, > - ? ? ? ? ? ? ? ? ? ?DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), > - ? ? ? ? ? ? ? ? ? ?R, M, Op); > + ? ?R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, R, M, Op); > ? ? // a += a > ? ? Op = DAG.getNode(ISD::ADD, dl, VT, Op, Op); > > @@ -8415,15 +8413,12 @@ > ? ? M = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, > ? ? ? ? ? ? ? ? ? ? DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), M, > ? ? ? ? ? ? ? ? ? ? DAG.getConstant(2, MVT::i32)); > - ? ?R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, > - ? ? ? ? ? ? ? ? ? ?DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), > - ? ? ? ? ? ? ? ? ? ?R, M, Op); > + ? ?R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, R, M, Op); > ? ? // a += a > ? ? Op = DAG.getNode(ISD::ADD, dl, VT, Op, Op); > > ? ? // return pblendv(r, r+r, a); > - ? ?R = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, > - ? ? ? ? ? ? ? ? ? ?DAG.getConstant(Intrinsic::x86_sse41_pblendvb, MVT::i32), > + ? ?R = DAG.getNode(X86ISD::PBLENDVB, dl, VT, > ? ? ? ? ? ? ? ? ? ? R, DAG.getNode(ISD::ADD, dl, VT, R, R), Op); > ? ? return R; > ? } > @@ -8897,6 +8892,7 @@ > ? case X86ISD::PSIGNB: ? ? ? ? ? ? return "X86ISD::PSIGNB"; > ? case X86ISD::PSIGNW: ? ? ? ? ? ? return "X86ISD::PSIGNW"; > ? case X86ISD::PSIGND: ? ? ? ? ? ? return "X86ISD::PSIGND"; > + ?case X86ISD::PBLENDVB: ? ? ? ? ? return "X86ISD::PBLENDVB"; > ? case X86ISD::FMAX: ? ? ? ? ? ? ? return "X86ISD::FMAX"; > ? case X86ISD::FMIN: ? ? ? ? ? ? ? return "X86ISD::FMIN"; > ? case X86ISD::FRSQRT: ? ? ? ? ? ? return "X86ISD::FRSQRT"; > @@ -11209,12 +11205,10 @@ > ? ? ? ? if (!Subtarget->hasSSE41()) > ? ? ? ? ? return SDValue(); > > - ? ? ? ?unsigned IID = Intrinsic::x86_sse41_pblendvb; > ? ? ? ? X = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, X); > ? ? ? ? Y = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Y); > ? ? ? ? Mask = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Mask); > - ? ? ? ?Mask = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v16i8, > - ? ? ? ? ? ? ? ? ? ? ? ? ? DAG.getConstant(IID, MVT::i32), X, Y, Mask); > + ? ? ? ?Mask = DAG.getNode(X86ISD::PBLENDVB, DL, MVT::v16i8, X, Y, Mask); > ? ? ? ? return DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Mask); > ? ? ? } > ? ? } > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=122277&r1=122276&r2=122277&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec 20 16:04:24 2010 > @@ -166,6 +166,9 @@ > ? ? ? /// PSIGNB/W/D - Copy integer sign. > ? ? ? PSIGNB, PSIGNW, PSIGND, > > + ? ? ?/// PBLENDVB - Variable blend > + ? ? ?PBLENDVB, > + > ? ? ? /// FMAX, FMIN - Floating point max and min. > ? ? ? /// > ? ? ? FMAX, FMIN, > > Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=122277&r1=122276&r2=122277&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Mon Dec 20 16:04:24 2010 > @@ -55,6 +55,9 @@ > ?def X86psignd ?: SDNode<"X86ISD::PSIGND", > ? ? ? ? ? ? ? ? ?SDTypeProfile<1, 2, [SDTCisVT<0, v4i32>, SDTCisSameAs<0,1>, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SDTCisSameAs<0,2>]>>; > +def X86pblendv : SDNode<"X86ISD::PBLENDVB", > + ? ? ? ? ? ? ? ? SDTypeProfile<1, 3, [SDTCisVT<0, v16i8>, SDTCisSameAs<0,1>, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SDTCisSameAs<0,2>, SDTCisSameAs<0,3>]>>; > ?def X86pextrb ?: SDNode<"X86ISD::PEXTRB", > ? ? ? ? ? ? ? ? ?SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisPtrTy<2>]>>; > ?def X86pextrw ?: SDNode<"X86ISD::PEXTRW", > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=122277&r1=122276&r2=122277&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Dec 20 16:04:24 2010 > @@ -4855,6 +4855,9 @@ > ?defm BLENDVPS ? ? : SS41I_ternary_int<0x14, "blendvps", int_x86_sse41_blendvps>; > ?defm PBLENDVB ? ? : SS41I_ternary_int<0x10, "pblendvb", int_x86_sse41_pblendvb>; > > +def : Pat<(X86pblendv VR128:$src1, VR128:$src2, XMM0), > + ? ? ? ? ?(PBLENDVBrr0 VR128:$src1, VR128:$src2)>; > + > ?let isAsmParserOnly = 1, Predicates = [HasAVX] in > ?def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vmovntdqa\t{$src, $dst|$dst, $src}", > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From sabre at nondot.org Mon Dec 20 19:31:33 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Dec 2010 01:31:33 -0000 Subject: [llvm-commits] [www] r122300 - /www/trunk/devmtg/2010-11/index.html Message-ID: <20101221013133.D5BDB2A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 19:31:33 2010 New Revision: 122300 URL: http://llvm.org/viewvc/llvm-project?rev=122300&view=rev Log: add the rest of the videos, with subtitles! Modified: www/trunk/devmtg/2010-11/index.html Modified: www/trunk/devmtg/2010-11/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/devmtg/2010-11/index.html?rev=122300&r1=122299&r2=122300&view=diff ============================================================================== --- www/trunk/devmtg/2010-11/index.html (original) +++ www/trunk/devmtg/2010-11/index.html Mon Dec 20 19:31:33 2010 @@ -68,8 +68,7 @@ [Slides] -

[Video] (Computer) -
[Videos] (Mobile)

+

[Video]

libclang: Thinking Beyond the Compiler
Doug Gregor, Apple Inc. @@ -80,8 +79,7 @@ [Slides] -

[Video] (Computer) -
[Videos] (Mobile)

+

[Video]

libc++: A Standard Library for C++0x
Howard Hinnant, Apple Inc. [Slides] @@ -91,19 +89,18 @@ [Slides] -

[Video] (Computer) -
[Video] (Mobile)

+

[Video]

The LLVM Assembler & Machine Code Infrastructure
Daniel Dunbar, Apple Inc. -[Slides] +[Slides]

[Video] (Computer)
[Video] (Mobile)

Creating cling, an interactive interpreter interface for clang
Axel Naumann, CERN -[Slides]
-[Video] (Computer)
[Videos] (Mobile) +[Slides] +

[Video] LLDB: Modular Debugging Infrastructure
Greg Clayton, Apple Inc. From stoklund at 2pi.dk Mon Dec 20 19:50:22 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 21 Dec 2010 01:50:22 -0000 Subject: [llvm-commits] [llvm] r122301 - in /llvm/trunk/lib/CodeGen: SplitKit.cpp SplitKit.h Message-ID: <20101221015022.238C72A6C12C@llvm.org> Author: stoklund Date: Mon Dec 20 19:50:21 2010 New Revision: 122301 URL: http://llvm.org/viewvc/llvm-project?rev=122301&view=rev Log: Add EdgeBundles to SplitKit. Edge bundles is an annotation on the CFG that turns it into a bipartite directed graph where each basic block is connected to an outgoing and an ingoing bundle. These bundles are useful for identifying regions of the CFG for live range splitting. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp llvm/trunk/lib/CodeGen/SplitKit.h Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=122301&r1=122300&r2=122301&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Mon Dec 20 19:50:21 2010 @@ -24,6 +24,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -35,6 +36,52 @@ cl::desc("Allow critical edge splitting during spilling")); //===----------------------------------------------------------------------===// +// Edge Bundles +//===----------------------------------------------------------------------===// + +/// compute - Compute the edge bundles for MF. Bundles depend only on the CFG. +void EdgeBundles::compute(const MachineFunction *mf) { + MF = mf; + EC.clear(); + EC.grow(2 * MF->size()); + + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; + ++I) { + const MachineBasicBlock &MBB = *I; + unsigned OutE = 2 * MBB.getNumber() + 1; + // Join the outgoing bundle with the ingoing bundles of all successors. + for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), + SE = MBB.succ_end(); SI != SE; ++SI) + EC.join(OutE, 2 * (*SI)->getNumber()); + } + EC.compress(); +} + +/// view - Visualize the annotated bipartite CFG with Graphviz. +void EdgeBundles::view() const { + ViewGraph(*this, "EdgeBundles"); +} + +/// Specialize WriteGraph, the standard implementation won't work. +raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G, + bool ShortNames, + const std::string &Title) { + const MachineFunction *MF = G.getMachineFunction(); + + O << "digraph {\n"; + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) { + unsigned BB = I->getNumber(); + O << "\t\"BB#" << BB << "\" [ shape=box ]\n" + << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n" + << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n'; + } + O << "}\n"; + return O; +} + + +//===----------------------------------------------------------------------===// // Split Analysis //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/SplitKit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.h?rev=122301&r1=122300&r2=122301&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.h (original) +++ llvm/trunk/lib/CodeGen/SplitKit.h Mon Dec 20 19:50:21 2010 @@ -12,10 +12,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntEqClasses.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/SlotIndexes.h" +#include + namespace llvm { class LiveInterval; @@ -36,6 +39,40 @@ template class DomTreeNodeBase; typedef DomTreeNodeBase MachineDomTreeNode; + +/// EdgeBundles - Group CFG edges into equivalence classes where registers must +/// be allocated identically. This annotates the CFG to form a bipartite graph +/// where each block is connected to an ingoing and an outgoing bundle. +/// Edge bundles are simply numbered, there is no object representation. +class EdgeBundles { + const MachineFunction *MF; + + /// EC - Each edge bundle is an equivalence class. The keys are: + /// 2*BB->getNumber() -> Ingoing bundle. + /// 2*BB->getNumber()+1 -> Outgoing bundle. + IntEqClasses EC; + +public: + /// compute - Compute the edge bundles for MF. Bundles depend only on the CFG. + void compute(const MachineFunction *MF); + + /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true) + /// bundle number for basic block #N + unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; } + + /// getMachineFunction - Return the last machine function computed. + const MachineFunction *getMachineFunction() const { return MF; } + + /// view - Visualize the annotated bipartite CFG with Graphviz. + void view() const; +}; + +/// Specialize WriteGraph, the standard implementation won't work. +raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G, + bool ShortNames = false, + const std::string &Title = ""); + + /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting /// opportunities. class SplitAnalysis { From isanbard at gmail.com Mon Dec 20 19:54:40 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Dec 2010 01:54:40 -0000 Subject: [llvm-commits] [llvm] r122302 - /llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <20101221015440.73F202A6C12C@llvm.org> Author: void Date: Mon Dec 20 19:54:40 2010 New Revision: 122302 URL: http://llvm.org/viewvc/llvm-project?rev=122302&view=rev Log: Comment cleanups. Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=122302&r1=122301&r2=122302&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 20 19:54:40 2010 @@ -1,4 +1,4 @@ -//===-- ARMConstantIslandPass.cpp - ARM constant islands --------*- C++ -*-===// +//===-- ARMConstantIslandPass.cpp - ARM constant islands ------------------===// // // The LLVM Compiler Infrastructure // @@ -482,7 +482,7 @@ HasInlineAsm = true; } - // Now go back through the instructions and build up our data structures + // Now go back through the instructions and build up our data structures. unsigned Offset = 0; for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end(); MBBI != E; ++MBBI) { From isanbard at gmail.com Mon Dec 20 19:57:15 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Dec 2010 01:57:15 -0000 Subject: [llvm-commits] [llvm] r122303 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Message-ID: <20101221015715.D31662A6C12C@llvm.org> Author: void Date: Mon Dec 20 19:57:15 2010 New Revision: 122303 URL: http://llvm.org/viewvc/llvm-project?rev=122303&view=rev Log: Fix a copy-pasto. When the tBR_JTr instruction was converted to using the tPseudoInst class, its size was changed from "special" to "2 bytes". This is incorrect because the jump table will no longer be taken into account when calculating branch offsets. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=122303&r1=122302&r2=122303&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Dec 20 19:57:15 2010 @@ -543,7 +543,7 @@ def tBR_JTr : tPseudoInst<(outs), (ins tGPR:$target, i32imm:$jt, i32imm:$id), - Size2Bytes, IIC_Br, + SizeSpecial, IIC_Br, [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]> { list Predicates = [IsThumb, IsThumb1Only]; } From sabre at nondot.org Mon Dec 20 20:07:03 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Dec 2010 02:07:03 -0000 Subject: [llvm-commits] [llvm] r122305 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <20101221020703.457862A6C12D@llvm.org> Author: lattner Date: Mon Dec 20 20:07:03 2010 New Revision: 122305 URL: http://llvm.org/viewvc/llvm-project?rev=122305&view=rev Log: improve "cannot yet select" errors a trivial amount: now they are just as useless, but at least a bit more gramatical Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122305&r1=122304&r2=122305&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Dec 20 20:07:03 2010 @@ -2726,7 +2726,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) { std::string msg; raw_string_ostream Msg(msg); - Msg << "Cannot yet select: "; + Msg << "Cannot select: "; if (N->getOpcode() != ISD::INTRINSIC_W_CHAIN && N->getOpcode() != ISD::INTRINSIC_WO_CHAIN && From clattner at apple.com Mon Dec 20 20:10:24 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 20 Dec 2010 18:10:24 -0800 Subject: [llvm-commits] [llvm] r122245 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstCombine/2010-11-01-lshr-mask.ll In-Reply-To: <20101220144704.6069F2A6C12C@llvm.org> References: <20101220144704.6069F2A6C12C@llvm.org> Message-ID: <8FD2A888-B702-4554-814E-EF38B11B2493@apple.com> On Dec 20, 2010, at 6:47 AM, Duncan Sands wrote: > Author: baldrick > Date: Mon Dec 20 08:47:04 2010 > New Revision: 122245 > > URL: http://llvm.org/viewvc/llvm-project?rev=122245&view=rev > Log: > Have SimplifyBinOp dispatch Xor, Add and Sub to the corresponding methods > (they had just been forgotten before). Adding Xor causes "main" in the > existing testcase 2010-11-01-lshr-mask.ll to be hugely more simplified. Wow, how'd we miss that, thanks! -Chris From clattner at apple.com Mon Dec 20 20:12:24 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 20 Dec 2010 18:12:24 -0800 Subject: [llvm-commits] [llvm] r122170 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/critical-edge-split-2.ll In-Reply-To: <5DB97C7B-B207-421E-A7F7-903A9285FECF@apple.com> References: <20101219045857.D53B42A6C12C@llvm.org> <17985F09-30C1-417A-A29C-65F2BE81C797@2pi.dk> <4C148651-8777-4184-BC9E-EE746893C005@nondot.org> <5DB97C7B-B207-421E-A7F7-903A9285FECF@apple.com> Message-ID: <7D6F7CDD-0766-4A3C-A58D-29FDD92DD038@apple.com> On Dec 20, 2010, at 10:54 AM, Dan Gohman wrote: >>>> fix PR8642: if a critical edge has a PHI value that can trap, >>>> isel is *required* to split the edge. PHI values get evaluated >>>> on the edge, not in their predecessor block. >>> >>> What happens if the predecessor block is terminated by indirectbr, so the edge can't be split? >> >> Huh, good question... I don't see a really robust answer... > > Why does LLVM need the concept of trapping constants? Prohibiting > them would be a robust answer, at seemingly little practical cost. It's a good question: the only real answer that I have is that ConstantExpr::get() is our current "constant folding API". Perhaps that's a bug, not a feature. What do you think about eliminating div and rem as valid constant exprs? -Chris From echristo at apple.com Mon Dec 20 20:12:07 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 21 Dec 2010 02:12:07 -0000 Subject: [llvm-commits] [llvm] r122307 - /llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Message-ID: <20101221021207.92E6F2A6C12C@llvm.org> Author: echristo Date: Mon Dec 20 20:12:07 2010 New Revision: 122307 URL: http://llvm.org/viewvc/llvm-project?rev=122307&view=rev Log: If we're not using reg+reg offset we're using reg+imm, set the opcode to be the one we want to use. bugpoint reduced testcase is a little large, I'll see if I can simplify it down more. Fixes part of rdar://8782207 Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=122307&r1=122306&r2=122307&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Mon Dec 20 20:12:07 2010 @@ -656,7 +656,7 @@ *this, dl); } - MI.setDesc(TII.get(ARM::tLDRr)); + MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); if (UseRR) // Use [reg, reg] addrmode. @@ -676,7 +676,7 @@ } else emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII, *this, dl); - MI.setDesc(TII.get(ARM::tSTRr)); + MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); MI.getOperand(i).ChangeToRegister(VReg, false, false, true); if (UseRR) // Use [reg, reg] addrmode. MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); From sabre at nondot.org Mon Dec 20 20:38:05 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Dec 2010 02:38:05 -0000 Subject: [llvm-commits] [llvm] r122310 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/Blackfin/ lib/Target/CellSPU/ lib/Target/MBlaze/ lib/Target/MSP430/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/SystemZ/ lib/Target/X86/ lib/Target/XCore/ lib/VMCore/ utils/TableGen/ Message-ID: <20101221023806.893822A6C12C@llvm.org> Author: lattner Date: Mon Dec 20 20:38:05 2010 New Revision: 122310 URL: http://llvm.org/viewvc/llvm-project?rev=122310&view=rev Log: rename MVT::Flag to MVT::Glue. "Flag" is a terrible name for something that just glues two nodes together, even if it is sometimes used for flags. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/include/llvm/CodeGen/ValueTypes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelDAGToDAG.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86SelectionDAGInfo.cpp llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp llvm/trunk/lib/VMCore/ValueTypes.cpp llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Dec 20 20:38:05 2010 @@ -402,7 +402,7 @@ // null) and that there should be a flag result. SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N, SDValue Flag) { - SDVTList VTs = getVTList(MVT::Other, MVT::Flag); + SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag }; return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3); } @@ -410,7 +410,7 @@ // Similar to last getCopyToReg() except parameter Reg is a SDValue SDValue getCopyToReg(SDValue Chain, DebugLoc dl, SDValue Reg, SDValue N, SDValue Flag) { - SDVTList VTs = getVTList(MVT::Other, MVT::Flag); + SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Reg, N, Flag }; return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3); } @@ -426,7 +426,7 @@ // null) and that there should be a flag result. SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT, SDValue Flag) { - SDVTList VTs = getVTList(VT, MVT::Other, MVT::Flag); + SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, VT), Flag }; return getNode(ISD::CopyFromReg, dl, VTs, Ops, Flag.getNode() ? 3 : 2); } @@ -465,7 +465,7 @@ /// a flag result (to ensure it's not CSE'd). CALLSEQ_START does not have a /// useful DebugLoc. SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) { - SDVTList VTs = getVTList(MVT::Other, MVT::Flag); + SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Op }; return getNode(ISD::CALLSEQ_START, DebugLoc(), VTs, Ops, 2); } @@ -475,7 +475,7 @@ /// a useful DebugLoc. SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InFlag) { - SDVTList NodeTys = getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Op1); Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Dec 20 20:38:05 2010 @@ -528,7 +528,7 @@ /// to which the flag operand points. Otherwise return NULL. SDNode *getFlaggedNode() const { if (getNumOperands() != 0 && - getOperand(getNumOperands()-1).getValueType() == MVT::Flag) + getOperand(getNumOperands()-1).getValueType() == MVT::Glue) return getOperand(getNumOperands()-1).getNode(); return 0; } @@ -553,7 +553,7 @@ /// the user (there is at most one). Otherwise return NULL. SDNode *getFlaggedUser() const { for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) - if (UI.getUse().get().getValueType() == MVT::Flag) + if (UI.getUse().get().getValueType() == MVT::Glue) return *UI; return 0; } Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Mon Dec 20 20:38:05 2010 @@ -79,7 +79,7 @@ x86mmx = 33, // This is an X86 MMX value - Flag = 34, // This glues nodes together during pre-RA sched + Glue = 34, // This glues nodes together during pre-RA sched isVoid = 35, // This has no value Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Dec 20 20:38:05 2010 @@ -1457,7 +1457,7 @@ if (N->hasNUsesOfValue(0, 1)) return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0), DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + N->getDebugLoc(), MVT::Glue)); // canonicalize constant to RHS. if (N0C && !N1C) @@ -1466,7 +1466,7 @@ // fold (addc x, 0) -> x + no carry out if (N1C && N1C->isNullValue()) return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + N->getDebugLoc(), MVT::Glue)); // fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share no bits. APInt LHSZero, LHSOne; @@ -1483,7 +1483,7 @@ (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask)) return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1), DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + N->getDebugLoc(), MVT::Glue)); } return SDValue(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Mon Dec 20 20:38:05 2010 @@ -35,7 +35,7 @@ /// not go into the resulting MachineInstr). unsigned InstrEmitter::CountResults(SDNode *Node) { unsigned N = Node->getNumValues(); - while (N && Node->getValueType(N - 1) == MVT::Flag) + while (N && Node->getValueType(N - 1) == MVT::Glue) --N; if (N && Node->getValueType(N - 1) == MVT::Other) --N; // Skip over chain result. @@ -48,7 +48,7 @@ /// MachineInstr. unsigned InstrEmitter::CountOperands(SDNode *Node) { unsigned N = Node->getNumOperands(); - while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) + while (N && Node->getOperand(N - 1).getValueType() == MVT::Glue) --N; if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) --N; // Ignore chain if it exists. @@ -96,7 +96,7 @@ if (Op.getNode() != Node || Op.getResNo() != ResNo) continue; EVT VT = Node->getValueType(Op.getResNo()); - if (VT == MVT::Other || VT == MVT::Flag) + if (VT == MVT::Other || VT == MVT::Glue) continue; Match = false; if (User->isMachineOpcode()) { @@ -264,7 +264,7 @@ DenseMap &VRBaseMap, bool IsDebug, bool IsClone, bool IsCloned) { assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && + Op.getValueType() != MVT::Glue && "Chain and flag operands should occur at end of operand list!"); // Get/emit the operand. unsigned VReg = getVR(Op, VRBaseMap); @@ -377,7 +377,7 @@ BA->getTargetFlags())); } else { assert(Op.getValueType() != MVT::Other && - Op.getValueType() != MVT::Flag && + Op.getValueType() != MVT::Glue && "Chain and flag operands should occur at end of operand list!"); AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap, IsDebug, IsClone, IsCloned); @@ -671,7 +671,7 @@ // The MachineInstr constructor adds implicit-def operands. Scan through // these to determine which are dead. if (MI->getNumOperands() != 0 && - Node->getValueType(Node->getNumValues()-1) == MVT::Flag) { + Node->getValueType(Node->getNumValues()-1) == MVT::Glue) { // First, collect all used registers. SmallVector UsedRegs; for (SDNode *F = Node->getFlaggedUser(); F; F = F->getFlaggedUser()) @@ -729,7 +729,7 @@ // MachineLICM/Sink can see that it's dead. Don't do this if the // node has a Flag value, for the benefit of targets still using // Flag for values in physregs. - else if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag) + else if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue) MI->addRegisterDead(Reg, TRI); } } @@ -737,7 +737,7 @@ // If the instruction has implicit defs and the node doesn't, mark the // implicit def as dead. If the node has any flag outputs, we don't do this // because we don't know what implicit defs are being used by flagged nodes. - if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag) + if (Node->getValueType(Node->getNumValues()-1) != MVT::Glue) if (const unsigned *IDList = II.getImplicitDefs()) { for (unsigned i = NumResults, e = II.getNumDefs()+II.getNumImplicitDefs(); i != e; ++i) @@ -793,7 +793,7 @@ case ISD::INLINEASM: { unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) + if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) --NumOps; // Ignore the flag operand. // Create the inline asm machine instruction. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Dec 20 20:38:05 2010 @@ -1085,7 +1085,7 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Do not try to legalize the target-specific arguments (#1+), except for // an optional flag input. - if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Flag){ + if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Glue){ if (Tmp1 != Node->getOperand(0)) { SmallVector Ops(Node->op_begin(), Node->op_end()); Ops[0] = Tmp1; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Dec 20 20:38:05 2010 @@ -1075,7 +1075,7 @@ TLI.isOperationLegalOrCustom(ISD::ADDC, TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) { // Emit this X << 1 as X+X. - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); + SDVTList VTList = DAG.getVTList(NVT, MVT::Glue); SDValue LoOps[2] = { InL, InL }; Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); SDValue HiOps[3] = { InH, InH, Lo.getValue(1) }; @@ -1310,7 +1310,7 @@ // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support // them. TODO: Teach operation legalization how to expand unsupported // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate - // a carry of type MVT::Flag, but there doesn't seem to be any way to + // a carry of type MVT::Glue, but there doesn't seem to be any way to // generate a value of this type in the expanded code sequence. bool hasCarry = TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ? @@ -1318,7 +1318,7 @@ TLI.getTypeToExpandTo(*DAG.getContext(), NVT)); if (hasCarry) { - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); + SDVTList VTList = DAG.getVTList(NVT, MVT::Glue); if (N->getOpcode() == ISD::ADD) { Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); @@ -1364,7 +1364,7 @@ DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue); SDValue LoOps[2] = { LHSL, RHSL }; SDValue HiOps[3] = { LHSH, RHSH }; @@ -1390,7 +1390,7 @@ DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue); SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; SDValue HiOps[3] = { LHSH, RHSH }; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Mon Dec 20 20:38:05 2010 @@ -216,7 +216,7 @@ bool TryUnfold = false; for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { EVT VT = N->getValueType(i); - if (VT == MVT::Flag) + if (VT == MVT::Glue) return NULL; else if (VT == MVT::Other) TryUnfold = true; @@ -224,7 +224,7 @@ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { const SDValue &Op = N->getOperand(i); EVT VT = Op.getNode()->getValueType(Op.getResNo()); - if (VT == MVT::Flag) + if (VT == MVT::Glue) return NULL; } @@ -480,7 +480,7 @@ if (Node->getOpcode() == ISD::INLINEASM) { // Inline asm can clobber physical defs. unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) + if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) --NumOps; // Ignore the flag operand. for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Dec 20 20:38:05 2010 @@ -401,7 +401,7 @@ bool TryUnfold = false; for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { EVT VT = N->getValueType(i); - if (VT == MVT::Flag) + if (VT == MVT::Glue) return NULL; else if (VT == MVT::Other) TryUnfold = true; @@ -409,7 +409,7 @@ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { const SDValue &Op = N->getOperand(i); EVT VT = Op.getNode()->getValueType(Op.getResNo()); - if (VT == MVT::Flag) + if (VT == MVT::Glue) return NULL; } @@ -671,7 +671,7 @@ if (Node->getOpcode() == ISD::INLINEASM) { // Inline asm can clobber physical defs. unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) + if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) --NumOps; // Ignore the flag operand. for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) { @@ -1410,7 +1410,7 @@ unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs(); for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) { EVT VT = N->getValueType(i); - if (VT == MVT::Flag || VT == MVT::Other) + if (VT == MVT::Glue || VT == MVT::Other) continue; if (!N->hasAnyUseOfValue(i)) continue; @@ -1724,7 +1724,7 @@ return false; for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) { EVT VT = N->getValueType(i); - if (VT == MVT::Flag || VT == MVT::Other) + if (VT == MVT::Glue || VT == MVT::Other) continue; if (!N->hasAnyUseOfValue(i)) continue; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Mon Dec 20 20:38:05 2010 @@ -118,13 +118,13 @@ if (FlagDestNode == N) return; // Don't add a flag to something which already has a flag. - if (N->getValueType(N->getNumValues() - 1) == MVT::Flag) return; + if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return; for (unsigned I = 0, E = N->getNumValues(); I != E; ++I) VTs.push_back(N->getValueType(I)); if (AddFlag) - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SmallVector Ops; for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) @@ -152,7 +152,7 @@ /// ClusterNeighboringLoads - Force nearby loads together by "flagging" them. /// This function finds loads of the same base and different offsets. If the -/// offsets are not far apart (target specific), it add MVT::Flag inputs and +/// offsets are not far apart (target specific), it add MVT::Glue inputs and /// outputs to ensure they are scheduled together and in order. This /// optimization may benefit some targets by improving cache locality. void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) { @@ -214,7 +214,7 @@ if (NumLoads == 0) return; - // Cluster loads by adding MVT::Flag outputs and inputs. This also + // Cluster loads by adding MVT::Glue outputs and inputs. This also // ensure they are scheduled in order of increasing addresses. SDNode *Lead = Loads[0]; AddFlags(Lead, SDValue(0, 0), true, DAG); @@ -297,7 +297,7 @@ // Scan up to find flagged preds. SDNode *N = NI; while (N->getNumOperands() && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) { N = N->getOperand(N->getNumOperands()-1).getNode(); assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NodeSUnit->NodeNum); @@ -307,7 +307,7 @@ // Scan down to find any flagged succs. N = NI; - while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { + while (N->getValueType(N->getNumValues()-1) == MVT::Glue) { SDValue FlagVal(N, N->getNumValues()-1); // There are either zero or one users of the Flag result. @@ -382,7 +382,7 @@ if (OpSU == SU) continue; // In the same group. EVT OpVT = N->getOperand(i).getValueType(); - assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!"); + assert(OpVT != MVT::Glue && "Flagged nodes should be in same sunit!"); bool isChain = OpVT == MVT::Other; unsigned PhysReg = 0; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h Mon Dec 20 20:38:05 2010 @@ -26,7 +26,7 @@ /// SDNodes such as Constants, Registers, and a few others that are not /// interesting to schedulers are not allocated SUnits. /// - /// SDNodes with MVT::Flag operands are grouped along with the flagged + /// SDNodes with MVT::Glue operands are grouped along with the flagged /// nodes into a single SUnit so that they are scheduled together. /// /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Dec 20 20:38:05 2010 @@ -491,7 +491,7 @@ /// doNotCSE - Return true if CSE should not be performed for this node. static bool doNotCSE(SDNode *N) { - if (N->getValueType(0) == MVT::Flag) + if (N->getValueType(0) == MVT::Glue) return true; // Never CSE anything that produces a flag. switch (N->getOpcode()) { @@ -503,7 +503,7 @@ // Check that remaining values produced are not flags. for (unsigned i = 1, e = N->getNumValues(); i != e; ++i) - if (N->getValueType(i) == MVT::Flag) + if (N->getValueType(i) == MVT::Glue) return true; // Never CSE anything that produces a flag. return false; @@ -649,7 +649,7 @@ // Verify that the node was actually in one of the CSE maps, unless it has a // flag result (which cannot be CSE'd) or is one of the special cases that are // not subject to CSE. - if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && + if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Glue && !N->isMachineOpcode() && !doNotCSE(N)) { N->dump(this); dbgs() << "\n"; @@ -2564,7 +2564,7 @@ SDNode *N; SDVTList VTs = getVTList(VT); - if (VT != MVT::Flag) { // Don't CSE flag producing nodes + if (VT != MVT::Glue) { // Don't CSE flag producing nodes FoldingSetNodeID ID; SDValue Ops[1] = { Operand }; AddNodeIDNode(ID, Opcode, VTs, Ops, 1); @@ -3006,7 +3006,7 @@ // Memoize this node if possible. SDNode *N; SDVTList VTs = getVTList(VT); - if (VT != MVT::Flag) { + if (VT != MVT::Glue) { SDValue Ops[] = { N1, N2 }; FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops, 2); @@ -3074,7 +3074,7 @@ // Memoize node if it doesn't produce a flag. SDNode *N; SDVTList VTs = getVTList(VT); - if (VT != MVT::Flag) { + if (VT != MVT::Glue) { SDValue Ops[] = { N1, N2, N3 }; FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops, 3); @@ -3882,7 +3882,7 @@ // Memoize the node unless it returns a flag. MemIntrinsicSDNode *N; - if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) { + if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); void *IP = 0; @@ -4238,7 +4238,7 @@ SDNode *N; SDVTList VTs = getVTList(VT); - if (VT != MVT::Flag) { + if (VT != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops, NumOps); void *IP = 0; @@ -4304,7 +4304,7 @@ // Memoize the node unless it returns a flag. SDNode *N; - if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) { + if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); void *IP = 0; @@ -4713,7 +4713,7 @@ unsigned NumOps) { // If an identical node already exists, use it. void *IP = 0; - if (VTs.VTs[VTs.NumVTs-1] != MVT::Flag) { + if (VTs.VTs[VTs.NumVTs-1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, VTs, Ops, NumOps); if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP)) @@ -4913,7 +4913,7 @@ MachineSDNode * SelectionDAG::getMachineNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, const SDValue *Ops, unsigned NumOps) { - bool DoCSE = VTs.VTs[VTs.NumVTs-1] != MVT::Flag; + bool DoCSE = VTs.VTs[VTs.NumVTs-1] != MVT::Glue; MachineSDNode *N; void *IP; @@ -4975,7 +4975,7 @@ /// else return NULL. SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList, const SDValue *Ops, unsigned NumOps) { - if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) { + if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); void *IP = 0; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Dec 20 20:38:05 2010 @@ -5922,7 +5922,7 @@ if (Flag.getNode()) AsmNodeOperands.push_back(Flag); Chain = DAG.getNode(ISD::INLINEASM, getCurDebugLoc(), - DAG.getVTList(MVT::Other, MVT::Flag), + DAG.getVTList(MVT::Other, MVT::Glue), &AsmNodeOperands[0], AsmNodeOperands.size()); Flag = Chain.getValue(1); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Dec 20 20:38:05 2010 @@ -1287,7 +1287,7 @@ Ops.push_back(InOps[InlineAsm::Op_IsAlignStack]); // 3 unsigned i = InlineAsm::Op_FirstOperand, e = InOps.size(); - if (InOps[e-1].getValueType() == MVT::Flag) + if (InOps[e-1].getValueType() == MVT::Glue) --e; // Don't process a flag operand if it is here. while (i != e) { @@ -1435,7 +1435,7 @@ // If the node has flags, walk down the graph to the "lowest" node in the // flagged set. EVT VT = Root->getValueType(Root->getNumValues()-1); - while (VT == MVT::Flag) { + while (VT == MVT::Glue) { SDNode *FU = findFlagUse(Root); if (FU == NULL) break; @@ -1460,7 +1460,7 @@ std::vector VTs; VTs.push_back(MVT::Other); - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SDValue New = CurDAG->getNode(ISD::INLINEASM, N->getDebugLoc(), VTs, &Ops[0], Ops.size()); New->setNodeId(-1); @@ -1521,7 +1521,7 @@ continue; SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1); - if (ChainVal.getValueType() == MVT::Flag) + if (ChainVal.getValueType() == MVT::Glue) ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2); assert(ChainVal.getValueType() == MVT::Other && "Not a chain?"); CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU); @@ -1544,7 +1544,7 @@ if (FRN->getOpcode() == ISD::DELETED_NODE) continue; - assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag && + assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Glue && "Doesn't have a flag result"); CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1), InputFlag, &ISU); @@ -1752,7 +1752,7 @@ int OldFlagResultNo = -1, OldChainResultNo = -1; unsigned NTMNumResults = Node->getNumValues(); - if (Node->getValueType(NTMNumResults-1) == MVT::Flag) { + if (Node->getValueType(NTMNumResults-1) == MVT::Glue) { OldFlagResultNo = NTMNumResults-1; if (NTMNumResults != 1 && Node->getValueType(NTMNumResults-2) == MVT::Other) @@ -2193,7 +2193,7 @@ case OPC_CaptureFlagInput: // If the current node has an input flag, capture it in InputFlag. if (N->getNumOperands() != 0 && - N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) InputFlag = N->getOperand(N->getNumOperands()-1); continue; @@ -2503,7 +2503,7 @@ if (EmitNodeInfo & OPFL_Chain) VTs.push_back(MVT::Other); if (EmitNodeInfo & OPFL_FlagOutput) - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); // This is hot code, so optimize the two most common cases of 1 and 2 // results. @@ -2539,7 +2539,7 @@ for (unsigned i = FirstOpToCopy, e = NodeToMatch->getNumOperands(); i != e; ++i) { SDValue V = NodeToMatch->getOperand(i); - if (V.getValueType() == MVT::Flag) break; + if (V.getValueType() == MVT::Glue) break; Ops.push_back(V); } } @@ -2560,7 +2560,7 @@ // Add all the non-flag/non-chain results to the RecordedNodes list. for (unsigned i = 0, e = VTs.size(); i != e; ++i) { - if (VTs[i] == MVT::Other || VTs[i] == MVT::Flag) break; + if (VTs[i] == MVT::Other || VTs[i] == MVT::Glue) break; RecordedNodes.push_back(std::pair(SDValue(Res, i), (SDNode*) 0)); } @@ -2639,7 +2639,7 @@ assert(i < NodeToMatch->getNumValues() && NodeToMatch->getValueType(i) != MVT::Other && - NodeToMatch->getValueType(i) != MVT::Flag && + NodeToMatch->getValueType(i) != MVT::Glue && "Invalid number of results to complete!"); assert((NodeToMatch->getValueType(i) == Res.getValueType() || NodeToMatch->getValueType(i) == MVT::iPTR || @@ -2652,7 +2652,7 @@ // If the root node defines a flag, add it to the flag nodes to update // list. - if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Flag) + if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Glue) FlagResultNodesMatched.push_back(NodeToMatch); // Update chain and flag uses. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Mon Dec 20 20:38:05 2010 @@ -93,7 +93,7 @@ static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { SDValue Op = EI.getNode()->getOperand(EI.getOperand()); EVT VT = Op.getValueType(); - if (VT == MVT::Flag) + if (VT == MVT::Glue) return "color=red,style=bold"; else if (VT == MVT::Other) return "color=blue,style=dashed"; Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -2379,7 +2379,7 @@ MVT::i32); SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, - MVT::Flag, Ops, 5); + MVT::Glue, Ops, 5); Chain = SDValue(ResNode, 0); if (N->getNumValues() == 2) { InFlag = SDValue(ResNode, 1); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -874,7 +874,7 @@ for (unsigned i = 0; i != NumVals; ++i) { EVT VT = N->getValueType(i); - if (VT == MVT::Flag || VT == MVT::Other) + if (VT == MVT::Glue || VT == MVT::Other) continue; if (VT.isFloatingPoint() || VT.isVector()) return Sched::Latency; @@ -1423,7 +1423,7 @@ if (InFlag.getNode()) Ops.push_back(InFlag); - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); if (isTailCall) return DAG.getNode(ARMISD::TC_RETURN, dl, NodeTys, &Ops[0], Ops.size()); @@ -2430,7 +2430,7 @@ break; } ARMcc = DAG.getConstant(CondCode, MVT::i32); - return DAG.getNode(CompareType, dl, MVT::Flag, LHS, RHS); + return DAG.getNode(CompareType, dl, MVT::Glue, LHS, RHS); } /// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands. @@ -2439,10 +2439,10 @@ DebugLoc dl) const { SDValue Cmp; if (!isFloatingPointZero(RHS)) - Cmp = DAG.getNode(ARMISD::CMPFP, dl, MVT::Flag, LHS, RHS); + Cmp = DAG.getNode(ARMISD::CMPFP, dl, MVT::Glue, LHS, RHS); else - Cmp = DAG.getNode(ARMISD::CMPFPw0, dl, MVT::Flag, LHS); - return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Flag, Cmp); + Cmp = DAG.getNode(ARMISD::CMPFPw0, dl, MVT::Glue, LHS); + return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Glue, Cmp); } SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { @@ -2633,7 +2633,7 @@ expandf64Toi32(RHS, DAG, RHS1, RHS2); ARMCC::CondCodes CondCode = IntCCToARMCC(CC); ARMcc = DAG.getConstant(CondCode, MVT::i32); - SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest }; return DAG.getNode(ARMISD::BCC_i64, dl, VTList, Ops, 7); } @@ -2673,7 +2673,7 @@ SDValue ARMcc = DAG.getConstant(CondCode, MVT::i32); SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl); SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); - SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Dest, ARMcc, CCR, Cmp }; SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, VTList, Ops, 5); if (CondCode2 != ARMCC::AL) { @@ -3029,7 +3029,7 @@ // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and // captures the result into a carry flag. unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; - Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, MVT::Flag), &Hi, 1); + Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, MVT::Glue), &Hi, 1); // The low part is an ARMISD::RRX operand, which shifts the carry in. Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1)); Modified: llvm/trunk/lib/Target/Alpha/AlphaISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -240,7 +240,7 @@ Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, N0, Chain.getValue(1)); SDNode *CNode = - CurDAG->getMachineNode(Alpha::JSRs, dl, MVT::Other, MVT::Flag, + CurDAG->getMachineNode(Alpha::JSRs, dl, MVT::Other, MVT::Glue, Chain, Chain.getValue(1)); Chain = CurDAG->getCopyFromReg(Chain, dl, Alpha::R27, MVT::i64, SDValue(CNode, 1)); @@ -403,13 +403,13 @@ Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag); InFlag = Chain.getValue(1); Chain = SDValue(CurDAG->getMachineNode(Alpha::BSR, dl, MVT::Other, - MVT::Flag, Addr.getOperand(0), + MVT::Glue, Addr.getOperand(0), Chain, InFlag), 0); } else { Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, Addr, InFlag); InFlag = Chain.getValue(1); Chain = SDValue(CurDAG->getMachineNode(Alpha::JSR, dl, MVT::Other, - MVT::Flag, Chain, InFlag), 0); + MVT::Glue, Chain, InFlag), 0); } InFlag = Chain.getValue(1); Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -306,7 +306,7 @@ } // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); Modified: llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -365,7 +365,7 @@ std::vector NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use. SDValue Ops[] = { Chain, Callee, InFlag }; Chain = DAG.getNode(BFISD::CALL, dl, NodeTys, Ops, InFlag.getNode() ? 3 : 2); @@ -432,7 +432,7 @@ SDValue(CarryIn, 0)); // Add operands, produce sum and carry flag - SDNode *Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Flag, + SDNode *Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue, Op.getOperand(0), Op.getOperand(1)); // Store intermediate carry from Sum @@ -440,11 +440,11 @@ /* flag= */ SDValue(Sum, 1)); // Add incoming carry, again producing an output flag - Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Flag, + Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue, SDValue(Sum, 0), SDValue(CarryIn, 0)); // Update AC0 with the intermediate carry, producing a flag. - SDNode *CarryOut = DAG.getMachineNode(BF::OR_ac0_cc, dl, MVT::Flag, + SDNode *CarryOut = DAG.getMachineNode(BF::OR_ac0_cc, dl, MVT::Glue, SDValue(Carry1, 0)); // Compose (i32, flag) pair Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -1423,7 +1423,7 @@ if (InFlag.getNode()) Ops.push_back(InFlag); // Returns a chain and a flag for retval copy to use. - Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag), + Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Glue), &Ops[0], Ops.size()); InFlag = Chain.getValue(1); Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -248,7 +248,7 @@ // Emit Jump and Link Register SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other, - MVT::Flag, R20Reg, Chain); + MVT::Glue, R20Reg, Chain); Chain = SDValue(ResNode, 0); InFlag = SDValue(ResNode, 1); ReplaceUses(SDValue(Node, 0), Chain); Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -621,7 +621,7 @@ // = Chain, Callee, Reg#1, Reg#2, ... // // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -536,7 +536,7 @@ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); @@ -747,7 +747,7 @@ } TargetCC = DAG.getConstant(TCC, MVT::i8); - return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS); + return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); } @@ -836,7 +836,7 @@ return SR; } else { SDValue Zero = DAG.getConstant(0, VT); - SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); SmallVector Ops; Ops.push_back(One); Ops.push_back(Zero); @@ -858,7 +858,7 @@ SDValue TargetCC; SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); - SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); SmallVector Ops; Ops.push_back(TrueV); Ops.push_back(FalseV); Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -349,7 +349,7 @@ SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT, SDValue(Carry,0), RHS); - return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Flag, + return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, SDValue(AddCarry,0)); } @@ -367,11 +367,11 @@ else Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV); - SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2); + SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2); SDValue InFlag = SDValue(MulDiv, 0); SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, - MVT::Flag, InFlag); + MVT::Glue, InFlag); InFlag = SDValue(Lo,1); SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); @@ -395,7 +395,7 @@ unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl, - MVT::Flag, MulOp1, MulOp2); + MVT::Glue, MulOp1, MulOp2); SDValue InFlag = SDValue(MulNode, 0); @@ -421,7 +421,7 @@ Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu); MOp = Mips::MFHI; } - SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2); + SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2); SDValue InFlag = SDValue(Node, 0); return CurDAG->getMachineNode(MOp, dl, MVT::i32, InFlag); @@ -474,7 +474,7 @@ SDValue InFlag; // Skip the incomming flag if present - if (Node->getOperand(LastOpNum).getValueType() == MVT::Flag) + if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue) LastOpNum--; if ( (isa(Callee)) || @@ -496,7 +496,7 @@ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag); // Map the JmpLink operands to JALR - SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32)); Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -905,7 +905,7 @@ // = Chain, Callee, Reg#1, Reg#2, ... // // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -635,7 +635,7 @@ } case ISD::SETNE: { SDValue AD = - SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(~0U)), 0); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); @@ -657,7 +657,7 @@ switch (CC) { default: break; case ISD::SETEQ: - Op = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + Op = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(1)), 0); return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, SDValue(CurDAG->getMachineNode(PPC::LI, dl, @@ -666,7 +666,7 @@ Op.getValue(1)); case ISD::SETNE: { Op = SDValue(CurDAG->getMachineNode(PPC::NOR, dl, MVT::i32, Op, Op), 0); - SDNode *AD = CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + SDNode *AD = CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, Op, getI32Imm(~0U)); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDValue(AD, 0), Op, SDValue(AD, 1)); @@ -858,13 +858,13 @@ SDValue N0 = N->getOperand(0); if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { SDNode *Op = - CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, + CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Glue, N0, getI32Imm(Log2_32(Imm))); return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, SDValue(Op, 0), SDValue(Op, 1)); } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { SDNode *Op = - CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, + CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Glue, N0, getI32Imm(Log2_32(-Imm))); SDValue PT = SDValue(CurDAG->getMachineNode(PPC::ADDZE, dl, MVT::i32, @@ -1016,7 +1016,7 @@ // FIXME: Implement this optzn for PPC64. N->getValueType(0) == MVT::i32) { SDNode *Tmp = - CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue, N->getOperand(0), getI32Imm(~0U)); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDValue(Tmp, 0), N->getOperand(0), Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -2427,7 +2427,7 @@ EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use. unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin; @@ -2514,7 +2514,7 @@ // Load the address of the function entry point from the function // descriptor. - SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Other, MVT::Flag); + SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Other, MVT::Glue); SDValue LoadFuncPtr = DAG.getNode(PPCISD::LOAD, dl, VTs, MTCTROps, InFlag.getNode() ? 3 : 2); Chain = LoadFuncPtr.getValue(1); @@ -2541,7 +2541,7 @@ // prevents the register allocator from allocating it), resulting in an // additional register being allocated and an unnecessary move instruction // being generated. - VTs = DAG.getVTList(MVT::Other, MVT::Flag); + VTs = DAG.getVTList(MVT::Other, MVT::Glue); SDValue LoadTOCPtr = DAG.getNode(PPCISD::LOAD_TOC, dl, VTs, Chain, Callee, InFlag); Chain = LoadTOCPtr.getValue(0); @@ -2558,7 +2558,7 @@ NodeTys.clear(); NodeTys.push_back(MVT::Other); - NodeTys.push_back(MVT::Flag); + NodeTys.push_back(MVT::Glue); Ops.push_back(Chain); CallOpc = isSVR4ABI ? PPCISD::BCTRL_SVR4 : PPCISD::BCTRL_Darwin; Callee.setNode(0); @@ -2672,7 +2672,7 @@ // stack frame. If caller and callee belong to the same module (and have the // same TOC), the NOP will remain unchanged. if (!isTailCall && PPCSubTarget.isSVR4ABI()&& PPCSubTarget.isPPC64()) { - SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue); if (CallOpc == PPCISD::BCTRL_SVR4) { // This is a call through a function pointer. // Restore the caller TOC from the save area into R2. @@ -2687,7 +2687,7 @@ InFlag = Chain.getValue(1); } else { // Otherwise insert NOP. - InFlag = DAG.getNode(PPCISD::NOP, dl, MVT::Flag, InFlag); + InFlag = DAG.getNode(PPCISD::NOP, dl, MVT::Glue, InFlag); } } @@ -3627,7 +3627,7 @@ // Save FP Control Word to register NodeTys.push_back(MVT::f64); // return register - NodeTys.push_back(MVT::Flag); // unused in this context + NodeTys.push_back(MVT::Glue); // unused in this context SDValue Chain = DAG.getNode(PPCISD::MFFS, dl, NodeTys, &InFlag, 0); // Save FP register to stack slot @@ -4254,7 +4254,7 @@ }; std::vector VTs; VTs.push_back(Op.getOperand(2).getValueType()); - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SDValue CompNode = DAG.getNode(PPCISD::VCMPo, dl, VTs, Ops, 3); // Now that we have the comparison, emit a copy from the CR to a GPR. @@ -4446,20 +4446,20 @@ SDValue Ops[4], Result, MFFSreg, InFlag, FPreg; NodeTys.push_back(MVT::f64); // Return register - NodeTys.push_back(MVT::Flag); // Returns a flag for later insns + NodeTys.push_back(MVT::Glue); // Returns a flag for later insns Result = DAG.getNode(PPCISD::MFFS, dl, NodeTys, &InFlag, 0); MFFSreg = Result.getValue(0); InFlag = Result.getValue(1); NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag + NodeTys.push_back(MVT::Glue); // Returns a flag Ops[0] = DAG.getConstant(31, MVT::i32); Ops[1] = InFlag; Result = DAG.getNode(PPCISD::MTFSB1, dl, NodeTys, Ops, 2); InFlag = Result.getValue(0); NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag + NodeTys.push_back(MVT::Glue); // Returns a flag Ops[0] = DAG.getConstant(30, MVT::i32); Ops[1] = InFlag; Result = DAG.getNode(PPCISD::MTFSB0, dl, NodeTys, Ops, 2); @@ -4467,7 +4467,7 @@ NodeTys.clear(); NodeTys.push_back(MVT::f64); // result of add - NodeTys.push_back(MVT::Flag); // Returns a flag + NodeTys.push_back(MVT::Glue); // Returns a flag Ops[0] = Lo; Ops[1] = Hi; Ops[2] = InFlag; @@ -5273,7 +5273,7 @@ DAG.getConstant(CompareOpc, MVT::i32) }; VTs.push_back(LHS.getOperand(2).getValueType()); - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SDValue CompNode = DAG.getNode(PPCISD::VCMPo, dl, VTs, Ops, 3); // Unpack the result based on how the target uses it. Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -158,7 +158,7 @@ } else { TopPart = CurDAG->getRegister(SP::G0, MVT::i32); } - TopPart = SDValue(CurDAG->getMachineNode(SP::WRYrr, dl, MVT::Flag, TopPart, + TopPart = SDValue(CurDAG->getMachineNode(SP::WRYrr, dl, MVT::Glue, TopPart, CurDAG->getRegister(SP::G0, MVT::i32)), 0); // FIXME: Handle div by immediate. @@ -172,7 +172,7 @@ SDValue MulLHS = N->getOperand(0); SDValue MulRHS = N->getOperand(1); unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr; - SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Flag, + SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Glue, MulLHS, MulRHS); // The high part is in the Y register. return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDValue(Mul, 1)); Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -488,7 +488,7 @@ std::vector NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use. SDValue Ops[] = { Chain, Callee, InFlag }; Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops, InFlag.getNode() ? 3 : 2); InFlag = Chain.getValue(1); @@ -834,13 +834,13 @@ if (LHS.getValueType() == MVT::i32) { std::vector VTs; VTs.push_back(MVT::i32); - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SDValue Ops[2] = { LHS, RHS }; CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1); if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); Opc = SPISD::BRICC; } else { - CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS); + CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); Opc = SPISD::BRFCC; } @@ -865,13 +865,13 @@ if (LHS.getValueType() == MVT::i32) { std::vector VTs; VTs.push_back(LHS.getValueType()); // subcc returns a value - VTs.push_back(MVT::Flag); + VTs.push_back(MVT::Glue); SDValue Ops[2] = { LHS, RHS }; CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1); Opc = SPISD::SELECT_ICC; if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); } else { - CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS); + CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS); Opc = SPISD::SELECT_FCC; if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); } Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -471,7 +471,7 @@ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy()); // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); @@ -710,7 +710,7 @@ SDValue SystemZCC; SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG); - SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); SmallVector Ops; Ops.push_back(TrueV); Ops.push_back(FalseV); Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Dec 20 20:38:05 2010 @@ -1675,14 +1675,14 @@ SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.getOperand(0), InFlag }; SDNode *CNode = - CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Flag, Ops, + CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue, Ops, array_lengthof(Ops)); InFlag = SDValue(CNode, 1); // Update the chain. ReplaceUses(N1.getValue(1), SDValue(CNode, 0)); } else { - SDNode *CNode = CurDAG->getMachineNode(Opc, dl, MVT::Flag, N1, InFlag); + SDNode *CNode = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N1, InFlag); InFlag = SDValue(CNode, 0); } @@ -1807,7 +1807,7 @@ if (isSigned && !signBitIsZero) { // Sign extend the low part into the high part. InFlag = - SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Flag, InFlag),0); + SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InFlag),0); } else { // Zero out the high part, effectively zero extending the input. SDValue ClrNode = @@ -1821,14 +1821,14 @@ SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.getOperand(0), InFlag }; SDNode *CNode = - CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Flag, Ops, + CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue, Ops, array_lengthof(Ops)); InFlag = SDValue(CNode, 1); // Update the chain. ReplaceUses(N1.getValue(1), SDValue(CNode, 0)); } else { InFlag = - SDValue(CurDAG->getMachineNode(Opc, dl, MVT::Flag, N1, InFlag), 0); + SDValue(CurDAG->getMachineNode(Opc, dl, MVT::Glue, N1, InFlag), 0); } // Prevent use of AH in a REX instruction by referencing AX instead. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -256,7 +256,7 @@ setOperationAction(ISD::SREM, VT, Expand); setOperationAction(ISD::UREM, VT, Expand); - // Add/Sub overflow ops with MVT::Flags are lowered to EFLAGS dependences. + // Add/Sub overflow ops with MVT::Glues are lowered to EFLAGS dependences. setOperationAction(ISD::ADDC, VT, Custom); setOperationAction(ISD::ADDE, VT, Custom); setOperationAction(ISD::SUBC, VT, Custom); @@ -1400,7 +1400,7 @@ if (CopyVT == MVT::f64) Opc = isST0 ? X86::FpGET_ST0_64:X86::FpGET_ST1_64; if (CopyVT == MVT::f80) Opc = isST0 ? X86::FpGET_ST0_80:X86::FpGET_ST1_80; SDValue Ops[] = { Chain, InFlag }; - Chain = SDValue(DAG.getMachineNode(Opc, dl, CopyVT, MVT::Other, MVT::Flag, + Chain = SDValue(DAG.getMachineNode(Opc, dl, CopyVT, MVT::Other, MVT::Glue, Ops, 2), 1); Val = Chain.getValue(0); @@ -2177,7 +2177,7 @@ } // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; if (!IsSibcall && isTailCall) { @@ -6034,7 +6034,7 @@ SDValue *InFlag, const EVT PtrVT, unsigned ReturnReg, unsigned char OperandFlags) { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); DebugLoc dl = GA->getDebugLoc(); SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, GA->getValueType(0), @@ -6183,7 +6183,7 @@ // Lowering the machine isd will make sure everything is in the right // location. SDValue Chain = DAG.getEntryNode(); - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Args[] = { Chain, Offset }; Chain = DAG.getNode(X86ISD::TLSCALL, DL, NodeTys, Args, 2); @@ -6290,7 +6290,7 @@ SDVTList Tys; bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType()); if (useSSE) - Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag); + Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Glue); else Tys = DAG.getVTList(Op.getValueType(), MVT::Other); @@ -7313,7 +7313,7 @@ // X86ISD::CMOV means set the result (which is operand 1) to the RHS if // condition is true. - SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); + SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); SDValue Ops[] = { Op2, Op1, CC, Cond }; return DAG.getNode(X86ISD::CMOV, DL, VTs, Ops, array_lengthof(Ops)); } @@ -7514,7 +7514,7 @@ Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag); Flag = Chain.getValue(1); - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Flag); Flag = Chain.getValue(1); @@ -8569,7 +8569,7 @@ Op.getOperand(3), DAG.getTargetConstant(size, MVT::i8), cpIn.getValue(1) }; - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); MachineMemOperand *MMO = cast(Op)->getMemOperand(); SDValue Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG_DAG, DL, Tys, Ops, 5, T, MMO); @@ -8581,7 +8581,7 @@ SDValue X86TargetLowering::LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const { assert(Subtarget->is64Bit() && "Result not type legalized?"); - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue TheChain = Op.getOperand(0); DebugLoc dl = Op.getDebugLoc(); SDValue rd = DAG.getNode(X86ISD::RDTSC_DAG, dl, Tys, &TheChain, 1); @@ -8775,7 +8775,7 @@ return; } case ISD::READCYCLECOUNTER: { - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue TheChain = N->getOperand(0); SDValue rd = DAG.getNode(X86ISD::RDTSC_DAG, dl, Tys, &TheChain, 1); SDValue eax = DAG.getCopyFromReg(rd, dl, X86::EAX, MVT::i32, @@ -8811,7 +8811,7 @@ SDValue Ops[] = { swapInH.getValue(0), N->getOperand(1), swapInH.getValue(1) }; - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); MachineMemOperand *MMO = cast(N)->getMemOperand(); SDValue Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG8_DAG, dl, Tys, Ops, 3, T, MMO); Modified: llvm/trunk/lib/Target/X86/X86SelectionDAGInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86SelectionDAGInfo.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86SelectionDAGInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86SelectionDAGInfo.cpp Mon Dec 20 20:38:05 2010 @@ -136,7 +136,7 @@ Dst, InFlag); InFlag = Chain.getValue(1); - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag }; Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops)); @@ -150,7 +150,7 @@ X86::ECX, Left, InFlag); InFlag = Chain.getValue(1); - Tys = DAG.getVTList(MVT::Other, MVT::Flag); + Tys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag }; Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops)); } else if (BytesLeft) { @@ -230,7 +230,7 @@ Src, InFlag); InFlag = Chain.getValue(1); - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag }; SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops, array_lengthof(Ops)); Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Mon Dec 20 20:38:05 2010 @@ -926,7 +926,7 @@ // = Chain, Callee, Reg#1, Reg#2, ... // // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); Modified: llvm/trunk/lib/VMCore/ValueTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ValueTypes.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ValueTypes.cpp (original) +++ llvm/trunk/lib/VMCore/ValueTypes.cpp Mon Dec 20 20:38:05 2010 @@ -109,7 +109,7 @@ case MVT::ppcf128: return "ppcf128"; case MVT::isVoid: return "isVoid"; case MVT::Other: return "ch"; - case MVT::Flag: return "flag"; + case MVT::Glue: return "glue"; case MVT::x86mmx: return "x86mmx"; case MVT::v2i8: return "v2i8"; case MVT::v4i8: return "v4i8"; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Dec 20 20:38:05 2010 @@ -64,7 +64,7 @@ case MVT::f128: return "MVT::f128"; case MVT::ppcf128: return "MVT::ppcf128"; case MVT::x86mmx: return "MVT::x86mmx"; - case MVT::Flag: return "MVT::Flag"; + case MVT::Glue: return "MVT::Glue"; case MVT::isVoid: return "MVT::isVoid"; case MVT::v2i8: return "MVT::v2i8"; case MVT::v4i8: return "MVT::v4i8"; Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=122310&r1=122309&r2=122310&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Mon Dec 20 20:38:05 2010 @@ -787,7 +787,7 @@ // The non-chain and non-flag results of the newly emitted node get recorded. for (unsigned i = 0, e = ResultVTs.size(); i != e; ++i) { - if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Flag) break; + if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Glue) break; OutputOps.push_back(NextRecordedOperandNo++); } } From nicholas at mxc.ca Mon Dec 20 21:26:37 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 20 Dec 2010 19:26:37 -0800 Subject: [llvm-commits] [llvm] r122264 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Utils/CMakeLists.txt lib/Transforms/Utils/Utils.cpp In-Reply-To: <20101220205437.585452A6C12C@llvm.org> References: <20101220205437.585452A6C12C@llvm.org> Message-ID: <4D101E6D.9030701@mxc.ca> Duncan Sands wrote: > Author: baldrick > Date: Mon Dec 20 14:54:37 2010 > New Revision: 122264 > > URL: http://llvm.org/viewvc/llvm-project?rev=122264&view=rev > Log: > Add a new convenience pass for testing InstructionSimplify. Previously > it could only be tested indirectly, via instcombine, gvn or some other > pass that makes use of InstructionSimplify, which means that testcases > had to be carefully contrived to dance around any other transformations > that that pass did. If you're interested, you could also test it with the unit testing framework by making calls to SimplifyInstruction. It would look something like: TEST(InstructionSimplify, AddTest) { LLVMContext context; Argument *A = new Argument(Type::Int64Ty); Instruction *I = BinaryOperator::CreateNeg( BinaryOperator::CreateSub( ConstantInt::get(Type::Int64Ty, -1), A ) ); Instruction *J = SimplifyInstruction(I); EXPECT_EQ(J->getOpcode(), Instruction::Add); EXPECT_EQ(J->getOperand(0), A); EXPECT_EQ(J->getOperand(1), ConstantInt::get(Type::Int64Ty), 1)); } Since the C++ API is bulky, you can also use ParseAssemblyString to produce a Module from inline .ll, see unittests/ExecutionEngine/JIT/JITTest.cpp for inspiration. Nick > > Modified: > llvm/trunk/include/llvm/InitializePasses.h > llvm/trunk/include/llvm/LinkAllPasses.h > llvm/trunk/include/llvm/Transforms/Scalar.h > llvm/trunk/lib/Transforms/Utils/CMakeLists.txt > llvm/trunk/lib/Transforms/Utils/Utils.cpp > > Modified: llvm/trunk/include/llvm/InitializePasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=122264&r1=122263&r2=122264&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/InitializePasses.h (original) > +++ llvm/trunk/include/llvm/InitializePasses.h Mon Dec 20 14:54:37 2010 > @@ -217,6 +217,7 @@ > void initializeUnreachableMachineBlockElimPass(PassRegistry&); > void initializeVerifierPass(PassRegistry&); > void initializeVirtRegMapPass(PassRegistry&); > +void initializeInstSimplifierPass(PassRegistry&); > > } > > > Modified: llvm/trunk/include/llvm/LinkAllPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=122264&r1=122263&r2=122264&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/LinkAllPasses.h (original) > +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Dec 20 14:54:37 2010 > @@ -147,6 +147,7 @@ > (void) llvm::createLowerAtomicPass(); > (void) llvm::createCorrelatedValuePropagationPass(); > (void) llvm::createMemDepPrinter(); > + (void) llvm::createInstructionSimplifierPass(); > > (void)new llvm::IntervalPartition(); > (void)new llvm::FindUsedTypes(); > > Modified: llvm/trunk/include/llvm/Transforms/Scalar.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=122264&r1=122263&r2=122264&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) > +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Dec 20 14:54:37 2010 > @@ -322,6 +322,13 @@ > // > Pass *createCorrelatedValuePropagationPass(); > > +//===----------------------------------------------------------------------===// > +// > +// InstructionSimplifier - Remove redundant instructions. > +// > +FunctionPass *createInstructionSimplifierPass(); > +extern char&InstructionSimplifierID; > + > } // End llvm namespace > > #endif > > Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=122264&r1=122263&r2=122264&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original) > +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Mon Dec 20 14:54:37 2010 > @@ -21,6 +21,7 @@ > PromoteMemoryToRegister.cpp > SSAUpdater.cpp > SimplifyCFG.cpp > + SimplifyInstructions.cpp > UnifyFunctionExitNodes.cpp > Utils.cpp > ValueMapper.cpp > > Modified: llvm/trunk/lib/Transforms/Utils/Utils.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Utils.cpp?rev=122264&r1=122263&r2=122264&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/Utils.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/Utils.cpp Mon Dec 20 14:54:37 2010 > @@ -28,6 +28,7 @@ > initializeLowerSwitchPass(Registry); > initializePromotePassPass(Registry); > initializeUnifyFunctionExitNodesPass(Registry); > + initializeInstSimplifierPass(Registry); > } > > /// LLVMInitializeTransformUtils - C binding for initializeTransformUtilsPasses. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From isanbard at gmail.com Mon Dec 20 21:31:05 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Dec 2010 03:31:05 -0000 Subject: [llvm-commits] [llvm] r122312 - /llvm/trunk/docs/CodingStandards.html Message-ID: <20101221033105.53ADA2A6C12C@llvm.org> Author: void Date: Mon Dec 20 21:31:05 2010 New Revision: 122312 URL: http://llvm.org/viewvc/llvm-project?rev=122312&view=rev Log: Grammar corrections and some formatting changes. 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=122312&r1=122311&r2=122312&view=diff ============================================================================== --- llvm/trunk/docs/CodingStandards.html (original) +++ llvm/trunk/docs/CodingStandards.html Mon Dec 20 21:31:05 2010 @@ -219,7 +219,7 @@ when it is useful to use C style (/* */) comments however:

    -
  1. When writing a C code: Obviously if you are writing C code, use C style +
  2. When writing C code: Obviously if you are writing C code, use C style comments.
  3. When writing a header file that may be #included by a C source file.
  4. @@ -259,7 +259,7 @@
  5. System #includes
-

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

+

and each category should be sorted by name.

The "Main Module Header" file applies to .cpp files which implement an interface defined by a .h file. This #include @@ -292,7 +292,7 @@ have standardized on 80 columns, so some people have already configured their editors for it (vs something else, like 90 columns).

-

This is one of many contentious issues in coding standards, but is not up +

This is one of many contentious issues in coding standards, but it is not up for debate.

@@ -306,12 +306,12 @@

In all cases, prefer spaces to tabs in source files. People have different preferred indentation levels, and different styles of indentation that they -like... this is fine. What isn't is that different editors/viewers expand tabs -out to different tab stops. This can cause your code to look completely +like; this is fine. What isn't fine is that different editors/viewers expand +tabs out to different tab stops. This can cause your code to look completely unreadable, and it is not worth dealing with.

As always, follow the Golden Rule above: follow the -style of existing code if your are modifying and extending it. If you like four +style of existing code if you are modifying and extending it. If you like four spaces of indentation, DO NOT do that in the middle of a chunk of code with two spaces of indentation. Also, do not reindent a whole source file: it makes for incredible diffs that are absolutely worthless.

@@ -345,17 +345,17 @@
-

If your code has compiler warnings in it, something is wrong: you aren't -casting values correctly, your have "questionable" constructs in your code, or -you are doing something legitimately wrong. Compiler warnings can cover up -legitimate errors in output and make dealing with a translation unit +

If your code has compiler warnings in it, something is wrong — you +aren't casting values correctly, your have "questionable" constructs in your +code, or you are doing something legitimately wrong. Compiler warnings can +cover up legitimate errors in output and make dealing with a translation unit difficult.

It is not possible to prevent all warnings from all compilers, nor is it desirable. Instead, pick a standard compiler (like gcc) that provides -a good thorough set of warnings, and stick to them. At least in the case of +a good thorough set of warnings, and stick to it. At least in the case of gcc, it is possible to work around any spurious errors by changing the -syntax of the code slightly. For example, an warning that annoys me occurs when +syntax of the code slightly. For example, a warning that annoys me occurs when I write code like this:

@@ -379,11 +379,16 @@
-

...which shuts gcc up. Any gcc warning that annoys you can +

which shuts gcc up. Any gcc warning that annoys you can be fixed by massaging the code appropriately.

-

These are the gcc warnings that I prefer to enable: -Wall --Winline -W -Wwrite-strings -Wno-unused

+

These are the gcc warnings that I prefer to enable:

+ +
+
+-Wall -Winline -W -Wwrite-strings -Wno-unused
+
+
@@ -412,19 +417,18 @@
-

LLVM does not use RTTI (e.g. dynamic_cast<>) or exceptions, in an -effort to reduce code and executable size. These two language features violate -the general C++ principle of "you only pay for what you use", causing executable -bloat even if exceptions are never used in a code base, or if RTTI is never used -for a class. Because of this, we turn them off globally in the code. -

- -

-That said, LLVM does make extensive use of a hand-rolled form of RTTI that use -templates like isa<>, cast<>, -and dyn_cast<>. This form of RTTI is opt-in and can be added to any -class. It is also substantially more efficient than dynamic_cast<>. -

+

In an effort to reduce code and executable size, LLVM does not use RTTI +(e.g. dynamic_cast<>) or exceptions. These two language features +violate the general C++ principle of "you only pay for what you use", +causing executable bloat even if exceptions are never used in the code base, or +if RTTI is never used for a class. Because of this, we turn them off globally +in the code.

+ +

That said, LLVM does make extensive use of a hand-rolled form of RTTI that +use templates like isa<>, +cast<>, and dyn_cast<>. This form of RTTI is +opt-in and can be added to any class. It is also substantially more efficient +than dynamic_cast<>.

@@ -444,8 +448,9 @@ declare the symbol. This can lead to problems at link time.

So, the rule for LLVM is to always use the class keyword, unless -all members are public and the type is a C++ "POD" type, in which case -struct is allowed.

+all members are public and the type is a C++ +POD type, in +which case struct is allowed.

@@ -473,18 +478,18 @@

C++ doesn't do too well in the modularity department. There is no real encapsulation or data hiding (unless you use expensive protocol classes), but it is what we have to work with. When you write a public header file (in the LLVM -source tree, they live in the top level "include" directory), you are defining a -module of functionality.

+source tree, they live in the top level "include" directory), you are +defining a module of functionality.

Ideally, modules should be completely independent of each other, and their -header files should only include the absolute minimum number of headers -possible. A module is not just a class, a function, or a namespace: it's a collection -of these that defines an interface. This interface may be several -functions, classes or data structures, but the important issue is how they work -together.

+header files should only #include the absolute minimum number of +headers possible. A module is not just a class, a function, or a +namespace: it's +a collection of these that defines an interface. This interface may be +several functions, classes, or data structures, but the important issue is how +they work together.

-

In general, a module should be implemented with one or more .cpp +

In general, a module should be implemented by one or more .cpp files. Each of these .cpp files should include the header that defines their interface first. This ensures that all of the dependences of the module header have been properly added to the module header itself, and are not @@ -503,29 +508,28 @@

#include hurts compile time performance. Don't do it unless you have to, especially in header files.

-

But wait, sometimes you need to have the definition of a class to use it, or +

But wait! Sometimes you need to have the definition of a class to use it, or to inherit from it. In these cases go ahead and #include that header file. Be aware however that there are many cases where you don't need to have the full definition of a class. If you are using a pointer or reference to a class, you don't need the header file. If you are simply returning a class instance from a prototyped function or method, you don't need it. In fact, for -most cases, you simply don't need the definition of a class... and not +most cases, you simply don't need the definition of a class. And not #include'ing speeds up compilation.

It is easy to try to go too overboard on this recommendation, however. You -must include all of the header files that you are using -- you can -include them either directly -or indirectly (through another header file). To make sure that you don't -accidentally forget to include a header file in your module header, make sure to -include your module header first in the implementation file (as mentioned -above). This way there won't be any hidden dependencies that you'll find out -about later...

+must include all of the header files that you are using — you can +include them either directly or indirectly (through another header file). To +make sure that you don't accidentally forget to include a header file in your +module header, make sure to include your module header first in the +implementation file (as mentioned above). This way there won't be any hidden +dependencies that you'll find out about later.

@@ -533,14 +537,14 @@

Many modules have a complex implementation that causes them to use more than one implementation (.cpp) file. It is often tempting to put the internal communication interface (helper classes, extra functions, etc) in the -public module header file. Don't do this.

+public module header file. Don't do this!

If you really need to do something like this, put a private header file in the same directory as the source files, and include it locally. This ensures that your private interface remains private and undisturbed by outsiders.

-

Note however, that it's okay to put extra implementation methods a public -class itself... just make them private (or protected), and all is well.

+

Note however, that it's okay to put extra implementation methods in a public +class itself. Just make them private (or protected) and all is well.

@@ -555,8 +559,8 @@ decisions have to be remembered by the reader to understand a block of code. Aim to reduce indentation where possible when it doesn't make it more difficult to understand the code. One great way to do this is by making use of early -exits and the continue keyword in long loops. As an example of using an early -exit from a function, consider this "bad" code:

+exits and the continue keyword in long loops. As an example of using +an early exit from a function, consider this "bad" code:

@@ -571,23 +575,23 @@
 
-

This code has several problems if the body of the 'if' is large. When you're -looking at the top of the function, it isn't immediately clear that this -only does interesting things with non-terminator instructions, and only -applies to things with the other predicates. Second, it is relatively difficult -to describe (in comments) why these predicates are important because the if -statement makes it difficult to lay out the comments. Third, when you're deep -within the body of the code, it is indented an extra level. Finally, when -reading the top of the function, it isn't clear what the result is if the -predicate isn't true, you have to read to the end of the function to know that -it returns null.

+

This code has several problems if the body of the 'if' is large. +When you're looking at the top of the function, it isn't immediately clear that +this only does interesting things with non-terminator instructions, and +only applies to things with the other predicates. Second, it is relatively +difficult to describe (in comments) why these predicates are important because +the if statement makes it difficult to lay out the comments. Third, +when you're deep within the body of the code, it is indented an extra level. +Finally, when reading the top of the function, it isn't clear what the result is +if the predicate isn't true; you have to read to the end of the function to know +that it returns null.

It is much preferred to format the code like this:

 Value *DoSomething(Instruction *I) {
-  // Terminators never need 'something' done to them because, ... 
+  // Terminators never need 'something' done to them because ... 
   if (isa<TerminatorInst>(I))
     return 0;
 
@@ -622,14 +626,13 @@
 
-

When you have very very small loops, this sort of structure is fine, but if +

When you have very, very small loops, this sort of structure is fine. But if it exceeds more than 10-15 lines, it becomes difficult for people to read and -understand at a glance. -The problem with this sort of code is that it gets very nested very quickly, -meaning that the reader of the code has to keep a lot of context in their brain -to remember what is going immediately on in the loop, because they don't know -if/when the if conditions will have elses etc. It is strongly preferred to -structure the loop like this:

+understand at a glance. The problem with this sort of code is that it gets very +nested very quickly. Meaning that the reader of the code has to keep a lot of +context in their brain to remember what is going immediately on in the loop, +because they don't know if/when the if conditions will have elses etc. +It is strongly preferred to structure the loop like this:

@@ -640,16 +643,17 @@
     Value *LHS = BO->getOperand(0);
     Value *RHS = BO->getOperand(1);
     if (LHS == RHS) continue;
+
     ...
   }
 
-

This has all the benefits of using early exits from functions: it reduces +

This has all the benefits of using early exits for functions: it reduces nesting of the loop, it makes it easier to describe why the conditions are true, -and it makes it obvious to the reader that there is no else coming up that -they have to push context into their brain for. If a loop is large, this can -be a big understandability win.

+and it makes it obvious to the reader that there is no else coming up +that they have to push context into their brain for. If a loop is large, this +can be a big understandability win.

@@ -661,10 +665,10 @@

For similar reasons above (reduction of indentation and easier reading), - please do not use else or 'else if' after something that interrupts - control flow like return, break, continue, goto, etc. For example, this is - "bad":

- +please do not use 'else' or 'else if' after something that +interrupts control flow — like return, break, +continue, goto, etc. For example, this is bad:

+
   case 'J': {
@@ -673,24 +677,24 @@
       if (Type.isNull()) {
         Error = ASTContext::GE_Missing_sigjmp_buf;
         return QualType();
-      } else {
+      } else {
         break;
-      }
+      }
     } else {
       Type = Context.getjmp_bufType();
       if (Type.isNull()) {
         Error = ASTContext::GE_Missing_jmp_buf;
         return QualType();
-      } else {
+      } else {
         break;
-      }
+      }
     }
   }
   }
 
-

It is better to write this something like:

+

It is better to write it like this:

@@ -708,11 +712,11 @@
         return QualType();
       }
     }
-    break;
+    break;
 
-

Or better yet (in this case), as:

+

Or better yet (in this case) as:

@@ -727,12 +731,12 @@
                        ASTContext::GE_Missing_jmp_buf;
       return QualType();
     }
-    break;
+    break;
 

The idea is to reduce indentation and the amount of code you have to keep - track of when reading the code.

+track of when reading the code.

@@ -743,9 +747,9 @@
-

It is very common to write small loops that just compute a boolean - value. There are a number of ways that people commonly write these, but an - example of this sort of thing is:

+

It is very common to write small loops that just compute a boolean value. +There are a number of ways that people commonly write these, but an example of +this sort of thing is:

@@ -766,9 +770,7 @@
 Instead of this sort of loop, we strongly prefer to use a predicate function
 (which may be static) that uses
 early exits to compute the predicate.  We prefer
-the code to be structured like this:
-

- +the code to be structured like this:

@@ -814,47 +816,43 @@
 
-

Poorly-chosen names can mislead the reader and cause bugs. We cannot -stress enough how important it is to use descriptive names. -Pick names that match the semantics and role of the underlying -entities, within reason. Avoid abbreviations unless they are well -known. After picking a good name, make sure to use consistent capitalization -for the name, as inconsistency requires clients to either memorize the APIs or -to look it up to find the exact spelling. -

+ +

Poorly-chosen names can mislead the reader and cause bugs. We cannot stress +enough how important it is to use descriptive names. Pick names that +match the semantics and role of the underlying entities, within reason. Avoid +abbreviations unless they are well known. After picking a good name, make sure +to use consistent capitalization for the name, as inconsistency requires clients +to either memorize the APIs or to look it up to find the exact spelling.

In general, names should be in camel case (e.g. TextFileReader -and isLValue()). Different kinds of declarations have different rules: -

+and isLValue()). Different kinds of declarations have different +rules:

  • Type names (including classes, structs, enums, typedefs, etc) should be nouns and start with an upper-case letter (e.g. - TextFileReader).

    -
  • + TextFileReader).

  • Function names should be verb phrases (as they represent actions), and command-like function should be imperative. The name should be camel case, and start with a lower case letter (e.g. openFile() - or isFoo()).

    -
  • + or isFoo()).

    -
  • Enum declarations (e.g. "enum Foo {...}") are types, so they -should follow the naming conventions for types. A common use for enums is as a - discriminator for a union, or an indicator of a subclass. When an enum is - used for something like this, it should have a "Kind" suffix (e.g. - "ValueKind").

    -
  • - -
  • Enumerators (e.g. enum { Foo, Bar }) and -public member variables should start with an upper-case letter, just -like types. Unless the enumerators are defined in their own small -namespace or inside a class, enumerators should have a prefix corresponding -to the enum declaration name. For example, enum ValueKind { ... }; -may contain enumerators like VK_Argument, VK_BasicBlock, -etc. Enumerators that are just convenience constants are exempt from the -requirement for a prefix. For instance:

    +
  • Enum declarations (e.g. enum Foo {...}) are types, so + they should follow the naming conventions for types. A common use for enums + is as a discriminator for a union, or an indicator of a subclass. When an + enum is used for something like this, it should have a Kind suffix + (e.g. ValueKind).

  • +
  • Enumerators (e.g. enum { Foo, Bar }) and public member + variables should start with an upper-case letter, just like types. + Unless the enumerators are defined in their own small namespace or inside a + class, enumerators should have a prefix corresponding to the enum + declaration name. For example, enum ValueKind { ... }; may contain + enumerators like VK_Argument, VK_BasicBlock, etc. + Enumerators that are just convenience constants are exempt from the + requirement for a prefix. For instance:

    +
     enum {
    @@ -863,16 +861,16 @@
     };
     
    -
  • +
+

As an exception, classes that mimic STL classes can have member names in +STL's style of lower-case words separated by underscores (e.g. begin(), +push_back(), and empty()).

-

As an exception, classes that mimic STL classes can have member names -in STL's style of lower-case words separated by underscores -(e.g. begin(), push_back(), and empty()).

+

Here are some examples of good and bad names:

-

Here are some examples of bad and good names:

 class VehicleMaker {
@@ -884,8 +882,8 @@
 };
 
 Vehicle MakeVehicle(VehicleType Type) {
-  VehicleMaker M;                     // Might be OK if having a short life-span.
-  Tire tmp1 = M.makeTire();  // Bad -- 'tmp1' provides no information.
+  VehicleMaker M;                         // Might be OK if having a short life-span.
+  Tire tmp1 = M.makeTire();               // Bad -- 'tmp1' provides no information.
   Light headlight = M.makeLight("head");  // Good -- descriptive.
   ...
 }
@@ -910,7 +908,7 @@
 it.

To further assist with debugging, make sure to put some kind of error message -in the assertion statement (which is printed if the assertion is tripped). This +in the assertion statement, which is printed if the assertion is tripped. This helps the poor debugger make sense of why an assertion is being made and enforced, and hopefully what to do about it. Here is one complete example:

@@ -923,7 +921,7 @@
-

Here are some examples:

+

Here are more examples:

@@ -939,9 +937,9 @@
 
-

You get the idea...

+

You get the idea.

-

Please be aware when adding assert statements that not all compilers are aware of +

Please be aware that, when adding assert statements, not all compilers are aware of the semantics of the assert. In some places, asserts are used to indicate a piece of code that should not be reached. These are typically of the form:

@@ -965,33 +963,33 @@

Another issue is that values used only by assertions will produce an "unused - value" warning when assertions are disabled. For example, this code will warn: -

+value" warning when assertions are disabled. For example, this code will +warn:

-  unsigned Size = V.size(); 
-  assert(Size > 42 && "Vector smaller than it should be");
+unsigned Size = V.size();
+assert(Size > 42 && "Vector smaller than it should be");
 
-  bool NewToSet = Myset.insert(Value);
-  assert(NewToSet && "The value shouldn't be in the set yet");  
+bool NewToSet = Myset.insert(Value);
+assert(NewToSet && "The value shouldn't be in the set yet");
 
-

These are two interesting different cases: in the first case, the call to +

These are two interesting different cases. In the first case, the call to V.size() is only useful for the assert, and we don't want it executed when assertions are disabled. Code like this should move the call into the assert itself. In the second case, the side effects of the call must happen whether -the assert is enabled or not. In this case, the value should be cast to void -to disable the warning. To be specific, it is preferred to write the code -like this:

+the assert is enabled or not. In this case, the value should be cast to void to +disable the warning. To be specific, it is preferred to write the code like +this:

-  assert(V.size() > 42 && "Vector smaller than it should be");
+assert(V.size() > 42 && "Vector smaller than it should be");
 
-  bool NewToSet = Myset.insert(Value); (void)NewToSet;
-  assert(NewToSet && "The value shouldn't be in the set yet");  
+bool NewToSet = Myset.insert(Value); (void)NewToSet;
+assert(NewToSet && "The value shouldn't be in the set yet");
 
@@ -1000,10 +998,11 @@
+

In LLVM, we prefer to explicitly prefix all identifiers from the standard namespace with an "std::" prefix, rather than rely on "using namespace std;".

@@ -1015,7 +1014,7 @@

In implementation files (e.g. .cpp files), the rule is more of a stylistic rule, but is still important. Basically, using explicit namespace prefixes makes the code clearer, because it is immediately obvious what facilities -are being used and where they are coming from, and more portable, because +are being used and where they are coming from. And more portable, because namespace clashes cannot occur between LLVM code and other namespaces. The portability rule is important because different standard library implementations expose different symbols (potentially ones they shouldn't), and future revisions @@ -1026,7 +1025,7 @@ the std namespace) is for implementation files. For example, all of the code in the LLVM project implements code that lives in the 'llvm' namespace. As such, it is ok, and actually clearer, for the .cpp files to have a -'using namespace llvm' directive at their top, after the +'using namespace llvm;' directive at the top, after the #includes. This reduces indentation in the body of the file for source editors that indent based on braces, and keeps the conceptual context cleaner. The general form of this rule is that any .cpp file that implements @@ -1037,8 +1036,8 @@

@@ -1054,15 +1053,16 @@
-

Because C++ doesn't have a standard "foreach" loop (though it can be emulated -with macros and may be coming in C++'0x) we end up writing a lot of loops that -manually iterate from begin to end on a variety of containers or through other -data structures. One common mistake is to write a loop in this style:

+

Because C++ doesn't have a standard "foreach" loop (though it can be +emulated with macros and may be coming in C++'0x) we end up writing a lot of +loops that manually iterate from begin to end on a variety of containers or +through other data structures. One common mistake is to write a loop in this +style:

@@ -1093,10 +1093,10 @@
 that you did it intentionally.

Why do we prefer the second form (when correct)? Writing the loop in the -first form has two problems: First it may be less efficient than evaluating it -at the start of the loop. In this case, the cost is probably minor: a few extra -loads every time through the loop. However, if the base expression is more -complex, then the cost can rise quickly. I've seen loops where the end +first form has two problems. First it may be less efficient than evaluating it +at the start of the loop. In this case, the cost is probably minor — a +few extra loads every time through the loop. However, if the base expression is +more complex, then the cost can rise quickly. I've seen loops where the end expression was actually something like: "SomeMap[x]->end()" and map lookups really aren't cheap. By writing it in the second form consistently, you eliminate the issue entirely and don't even have to think about it.

@@ -1115,7 +1115,7 @@
@@ -1124,12 +1124,13 @@ hereby forbidden. The primary reason for doing this is to support clients using LLVM libraries as part of larger systems. In particular, we statically link LLVM into some dynamic libraries. Even if LLVM isn't used, -the static c'tors are run whenever an application start up that uses the dynamic -library. There are two problems with this:

+the static constructors are run whenever an application starts up that uses the +dynamic library. There are two problems with this:

    -
  1. The time to run the static c'tors impacts startup time of - applications—a critical time for GUI apps.
  2. +
  3. The time to run the static c'tors impacts startup time of applications + — a critical time for GUI apps.
  4. +
  5. The static c'tors cause the app to pull many extra pages of memory off the disk: both the code for the static c'tors in each .o file and the small amount of data that gets touched. In addition, touched/dirty pages @@ -1137,10 +1138,10 @@

Note that using the other stream headers (<sstream> for -example) is not problematic in this regard (just <iostream>). -However, raw_ostream provides various APIs that are better performing for almost -every use than std::ostream style APIs. -Therefore new code should always +example) is not problematic in this regard — +just <iostream>. However, raw_ostream provides various +APIs that are better performing for almost every use than std::ostream +style APIs. Therefore new code should always use raw_ostream for writing, or the llvm::MemoryBuffer API for reading files.

@@ -1155,9 +1156,9 @@

LLVM includes a lightweight, simple, and efficient stream implementation -in llvm/Support/raw_ostream.h which provides all of the common features -of std::ostream. All new code should use raw_ostream instead -of ostream.

+in llvm/Support/raw_ostream.h, which provides all of the common +features of std::ostream. All new code should use raw_ostream +instead of ostream.

Unlike std::ostream, raw_ostream is not a template and can be forward declared as class raw_ostream. Public headers should @@ -1174,9 +1175,9 @@

-

The std::endl modifier, when used with iostreams outputs a newline -to the output stream specified. In addition to doing this, however, it also -flushes the output stream. In other words, these are equivalent:

+

The std::endl modifier, when used with iostreams outputs a +newline to the output stream specified. In addition to doing this, however, it +also flushes the output stream. In other words, these are equivalent:

@@ -1213,48 +1214,48 @@
 
 
-  if (x) ...
-  for (i = 0; i != 100; ++i) ...
-  while (llvm_rocks) ...
+if (x) ...
+for (i = 0; i != 100; ++i) ...
+while (llvm_rocks) ...
 
-  somefunc(42);
-  assert(3 != 4 && "laws of math are failing me");
+somefunc(42);
+assert(3 != 4 && "laws of math are failing me");
   
-  a = foo(42, 92) + bar(x);
-  
+a = foo(42, 92) + bar(x); +
-

... and this is bad:

+

and this is bad:

-  if(x) ...
-  for(i = 0; i != 100; ++i) ...
-  while(llvm_rocks) ...
+if(x) ...
+for(i = 0; i != 100; ++i) ...
+while(llvm_rocks) ...
 
-  somefunc (42);
-  assert (3 != 4 && "laws of math are failing me");
+somefunc (42);
+assert (3 != 4 && "laws of math are failing me");
   
-  a = foo (42, 92) + bar (x);
+a = foo (42, 92) + bar (x);
 

The reason for doing this is not completely arbitrary. This style makes - control flow operators stand out more, and makes expressions flow better. The - function call operator binds very tightly as a postfix operator. Putting - a space after a function name (as in the last example) makes it appear that - the code might bind the arguments of the left-hand-side of a binary operator - with the argument list of a function and the name of the right side. More - specifically, it is easy to misread the "a" example as:

+control flow operators stand out more, and makes expressions flow better. The +function call operator binds very tightly as a postfix operator. Putting a +space after a function name (as in the last example) makes it appear that the +code might bind the arguments of the left-hand-side of a binary operator with +the argument list of a function and the name of the right side. More +specifically, it is easy to misread the "a" example as:

-  a = foo ((42, 92) + bar) (x);
+a = foo ((42, 92) + bar) (x);
 
-

... when skimming through the code. By avoiding a space in a function, we -avoid this misinterpretation.

+

when skimming through the code. By avoiding a space in a function, we avoid +this misinterpretation.

From echristo at apple.com Mon Dec 20 21:50:43 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 21 Dec 2010 03:50:43 -0000 Subject: [llvm-commits] [llvm] r122313 - /llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Message-ID: <20101221035043.67AF82A6C12C@llvm.org> Author: echristo Date: Mon Dec 20 21:50:43 2010 New Revision: 122313 URL: http://llvm.org/viewvc/llvm-project?rev=122313&view=rev Log: Arm and thumb call instructions are also in different orders. Fixes rdar://8782223 Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=122313&r1=122312&r2=122313&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Mon Dec 20 21:50:43 2010 @@ -1699,14 +1699,19 @@ // TODO: Turn this into the table of arm call ops. MachineInstrBuilder MIB; unsigned CallOpc; - if(isThumb) + if(isThumb) { CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi; - else + // Explicitly adding the predicate here. + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc))) + .addExternalSymbol(TLI.getLibcallName(Call)); + } else { CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL; - // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc))) - .addExternalSymbol(TLI.getLibcallName(Call)); + // Explicitly adding the predicate here. + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc)) + .addExternalSymbol(TLI.getLibcallName(Call))); + } // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) @@ -1813,15 +1818,21 @@ // TODO: Turn this into the table of arm call ops. MachineInstrBuilder MIB; unsigned CallOpc; - if(isThumb) + // Explicitly adding the predicate here. + if(isThumb) { CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi; - else + // Explicitly adding the predicate here. + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc))) + .addGlobalAddress(GV, 0, 0); + } else { CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL; - // Explicitly adding the predicate here. - MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(CallOpc))) - .addGlobalAddress(GV, 0, 0); - + // Explicitly adding the predicate here. + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc)) + .addGlobalAddress(GV, 0, 0)); + } + // Add implicit physical register uses to the call. for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) MIB.addReg(RegArgs[i]); From rafael.espindola at gmail.com Mon Dec 20 22:22:09 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 21 Dec 2010 04:22:09 -0000 Subject: [llvm-commits] [llvm] r122314 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp Message-ID: <20101221042209.571F42A6C12C@llvm.org> Author: rafael Date: Mon Dec 20 22:22:09 2010 New Revision: 122314 URL: http://llvm.org/viewvc/llvm-project?rev=122314&view=rev Log: Layout one section until no relaxations are done and then move to the next section. This helps because in practice sections form a dag with debug sections pointing to text sections. Finishing up the text sections first makes the debug section relaxation trivial. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/lib/MC/MCAssembler.cpp Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=122314&r1=122313&r2=122314&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Mon Dec 20 22:22:09 2010 @@ -711,6 +711,8 @@ /// were adjusted. bool LayoutOnce(MCAsmLayout &Layout); + bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); + bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); bool RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF); Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122314&r1=122313&r2=122314&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Dec 20 22:22:09 2010 @@ -707,46 +707,53 @@ return OldSize != Size; } +bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, + MCSectionData &SD) { + MCFragment *FirstInvalidFragment = NULL; + // Scan for fragments that need relaxation. + for (MCSectionData::iterator it2 = SD.begin(), + ie2 = SD.end(); it2 != ie2; ++it2) { + // Check if this is an fragment that needs relaxation. + bool relaxedFrag = false; + switch(it2->getKind()) { + default: + break; + case MCFragment::FT_Align: + relaxedFrag = RelaxAlignment(Layout, *cast(it2)); + break; + case MCFragment::FT_Inst: + relaxedFrag = RelaxInstruction(Layout, *cast(it2)); + break; + case MCFragment::FT_Org: + relaxedFrag = RelaxOrg(Layout, *cast(it2)); + break; + case MCFragment::FT_Dwarf: + relaxedFrag = RelaxDwarfLineAddr(Layout, + *cast(it2)); + break; + case MCFragment::FT_LEB: + relaxedFrag = RelaxLEB(Layout, *cast(it2)); + break; + } + // Update the layout, and remember that we relaxed. + if (relaxedFrag && !FirstInvalidFragment) + FirstInvalidFragment = it2; + } + if (FirstInvalidFragment) { + Layout.Invalidate(FirstInvalidFragment); + return true; + } + return false; +} + bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) { ++stats::RelaxationSteps; - // Scan for fragments that need relaxation. bool WasRelaxed = false; for (iterator it = begin(), ie = end(); it != ie; ++it) { MCSectionData &SD = *it; - MCFragment *FirstInvalidFragment = NULL; - - for (MCSectionData::iterator it2 = SD.begin(), - ie2 = SD.end(); it2 != ie2; ++it2) { - // Check if this is an fragment that needs relaxation. - bool relaxedFrag = false; - switch(it2->getKind()) { - default: - break; - case MCFragment::FT_Align: - relaxedFrag = RelaxAlignment(Layout, *cast(it2)); - break; - case MCFragment::FT_Inst: - relaxedFrag = RelaxInstruction(Layout, *cast(it2)); - break; - case MCFragment::FT_Org: - relaxedFrag = RelaxOrg(Layout, *cast(it2)); - break; - case MCFragment::FT_Dwarf: - relaxedFrag = RelaxDwarfLineAddr(Layout, - *cast(it2)); - break; - case MCFragment::FT_LEB: - relaxedFrag = RelaxLEB(Layout, *cast(it2)); - break; - } - // Update the layout, and remember that we relaxed. - if (relaxedFrag && !FirstInvalidFragment) - FirstInvalidFragment = it2; - WasRelaxed |= relaxedFrag; - } - if (FirstInvalidFragment) - Layout.Invalidate(FirstInvalidFragment); + while(LayoutSectionOnce(Layout, SD)) + WasRelaxed = true; } return WasRelaxed; From bob.wilson at apple.com Tue Dec 21 00:43:19 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 21 Dec 2010 06:43:19 -0000 Subject: [llvm-commits] [llvm] r122319 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/vector-DAGCombine.ll Message-ID: <20101221064319.ABFEF2A6C12C@llvm.org> Author: bwilson Date: Tue Dec 21 00:43:19 2010 New Revision: 122319 URL: http://llvm.org/viewvc/llvm-project?rev=122319&view=rev Log: Add ARM-specific DAG combining to cast i64 vector element load/stores to f64. Type legalization splits up i64 values into pairs of i32 values, which leads to poor quality code when inserting or extracting i64 vector elements. If the vector element is loaded or stored, it can be treated as an f64 value and loaded or stored directly from a VPR register. Use the pre-legalization DAG combiner to cast those vector elements to f64 types so that the type legalizer won't mess them up. Radar 8755338. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/test/CodeGen/ARM/vector-DAGCombine.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=122319&r1=122318&r2=122319&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Dec 21 00:43:19 2010 @@ -464,6 +464,8 @@ setTargetDAGCombine(ISD::SELECT_CC); setTargetDAGCombine(ISD::BUILD_VECTOR); setTargetDAGCombine(ISD::VECTOR_SHUFFLE); + setTargetDAGCombine(ISD::INSERT_VECTOR_ELT); + setTargetDAGCombine(ISD::STORE); } computeRegisterProperties(); @@ -4862,17 +4864,111 @@ return SDValue(); } +/// PerformSTORECombine - Target-specific dag combine xforms for +/// ISD::STORE. +static SDValue PerformSTORECombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI) { + // Bitcast an i64 store extracted from a vector to f64. + // Otherwise, the i64 value will be legalized to a pair of i32 values. + StoreSDNode *St = cast(N); + SDValue StVal = St->getValue(); + if (!ISD::isNormalStore(St) || St->isVolatile() || + StVal.getValueType() != MVT::i64 || + StVal.getNode()->getOpcode() != ISD::EXTRACT_VECTOR_ELT) + return SDValue(); + + SelectionDAG &DAG = DCI.DAG; + DebugLoc dl = StVal.getDebugLoc(); + SDValue IntVec = StVal.getOperand(0); + EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, + IntVec.getValueType().getVectorNumElements()); + SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec); + SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, + Vec, StVal.getOperand(1)); + dl = N->getDebugLoc(); + SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt); + // Make the DAGCombiner fold the bitcasts. + DCI.AddToWorklist(Vec.getNode()); + DCI.AddToWorklist(ExtElt.getNode()); + DCI.AddToWorklist(V.getNode()); + return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(), + St->getPointerInfo(), St->isVolatile(), + St->isNonTemporal(), St->getAlignment(), + St->getTBAAInfo()); +} + +/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node +/// are normal, non-volatile loads. If so, it is profitable to bitcast an +/// i64 vector to have f64 elements, since the value can then be loaded +/// directly into a VFP register. +static bool hasNormalLoadOperand(SDNode *N) { + unsigned NumElts = N->getValueType(0).getVectorNumElements(); + for (unsigned i = 0; i < NumElts; ++i) { + SDNode *Elt = N->getOperand(i).getNode(); + if (ISD::isNormalLoad(Elt) && !cast(Elt)->isVolatile()) + return true; + } + return false; +} + /// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for /// ISD::BUILD_VECTOR. -static SDValue PerformBUILD_VECTORCombine(SDNode *N, SelectionDAG &DAG) { +static SDValue PerformBUILD_VECTORCombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI){ // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X): // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value // into a pair of GPRs, which is fine when the value is used as a scalar, // but if the i64 value is converted to a vector, we need to undo the VMOVRRD. - if (N->getNumOperands() == 2) - return PerformVMOVDRRCombine(N, DAG); + SelectionDAG &DAG = DCI.DAG; + if (N->getNumOperands() == 2) { + SDValue RV = PerformVMOVDRRCombine(N, DAG); + if (RV.getNode()) + return RV; + } - return SDValue(); + // Load i64 elements as f64 values so that type legalization does not split + // them up into i32 values. + EVT VT = N->getValueType(0); + if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N)) + return SDValue(); + DebugLoc dl = N->getDebugLoc(); + SmallVector Ops; + unsigned NumElts = VT.getVectorNumElements(); + for (unsigned i = 0; i < NumElts; ++i) { + SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i)); + Ops.push_back(V); + // Make the DAGCombiner fold the bitcast. + DCI.AddToWorklist(V.getNode()); + } + EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts); + SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, dl, FloatVT, Ops.data(), NumElts); + return DAG.getNode(ISD::BITCAST, dl, VT, BV); +} + +/// PerformInsertEltCombine - Target-specific dag combine xforms for +/// ISD::INSERT_VECTOR_ELT. +static SDValue PerformInsertEltCombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI) { + // Bitcast an i64 load inserted into a vector to f64. + // Otherwise, the i64 value will be legalized to a pair of i32 values. + EVT VT = N->getValueType(0); + SDNode *Elt = N->getOperand(1).getNode(); + if (VT.getVectorElementType() != MVT::i64 || + !ISD::isNormalLoad(Elt) || cast(Elt)->isVolatile()) + return SDValue(); + + SelectionDAG &DAG = DCI.DAG; + DebugLoc dl = N->getDebugLoc(); + EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, + VT.getVectorNumElements()); + SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0)); + SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1)); + // Make the DAGCombiner fold the bitcasts. + DCI.AddToWorklist(Vec.getNode()); + DCI.AddToWorklist(V.getNode()); + SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT, + Vec, V, N->getOperand(2)); + return DAG.getNode(ISD::BITCAST, dl, VT, InsElt); } /// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for @@ -5425,7 +5521,9 @@ case ARMISD::BFI: return PerformBFICombine(N, DCI); case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI); case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG); - case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI.DAG); + case ISD::STORE: return PerformSTORECombine(N, DCI); + case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI); + case ISD::INSERT_VECTOR_ELT: return PerformInsertEltCombine(N, DCI); case ISD::VECTOR_SHUFFLE: return PerformVECTOR_SHUFFLECombine(N, DCI.DAG); case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI); case ISD::INTRINSIC_WO_CHAIN: return PerformIntrinsicCombine(N, DCI.DAG); Modified: llvm/trunk/test/CodeGen/ARM/vector-DAGCombine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vector-DAGCombine.ll?rev=122319&r1=122318&r2=122319&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vector-DAGCombine.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vector-DAGCombine.ll Tue Dec 21 00:43:19 2010 @@ -75,3 +75,33 @@ } declare void @llvm.arm.neon.vst1.v8i8(i8*, <8 x i8>, i32) nounwind + +; Test that loads and stores of i64 vector elements are handled as f64 values +; so they are not split up into i32 values. Radar 8755338. +define void @i64_buildvector(i64* %ptr, <2 x i64>* %vp) nounwind { +; CHECK: i64_buildvector +; CHECK: vldr.64 + %t0 = load i64* %ptr, align 4 + %t1 = insertelement <2 x i64> undef, i64 %t0, i32 0 + store <2 x i64> %t1, <2 x i64>* %vp + ret void +} + +define void @i64_insertelement(i64* %ptr, <2 x i64>* %vp) nounwind { +; CHECK: i64_insertelement +; CHECK: vldr.64 + %t0 = load i64* %ptr, align 4 + %vec = load <2 x i64>* %vp + %t1 = insertelement <2 x i64> %vec, i64 %t0, i32 0 + store <2 x i64> %t1, <2 x i64>* %vp + ret void +} + +define void @i64_extractelement(i64* %ptr, <2 x i64>* %vp) nounwind { +; CHECK: i64_extractelement +; CHECK: vstr.64 + %vec = load <2 x i64>* %vp + %t1 = extractelement <2 x i64> %vec, i32 0 + store i64 %t1, i64* %ptr + ret void +} From aggarwa4 at illinois.edu Tue Dec 21 00:47:10 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 06:47:10 -0000 Subject: [llvm-commits] [poolalloc] r122320 - /poolalloc/trunk/include/dsa/DSSupport.h Message-ID: <20101221064710.2D6122A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 00:47:10 2010 New Revision: 122320 URL: http://llvm.org/viewvc/llvm-project?rev=122320&view=rev Log: Making sure the mapped DSCallSites are copied over in the copy constructor. Modified: poolalloc/trunk/include/dsa/DSSupport.h Modified: poolalloc/trunk/include/dsa/DSSupport.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSSupport.h?rev=122320&r1=122319&r2=122320&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DSSupport.h (original) +++ poolalloc/trunk/include/dsa/DSSupport.h Tue Dec 21 00:47:10 2010 @@ -209,7 +209,7 @@ DSCallSite(const DSCallSite &DSCS) // Simple copy ctor : Site(DSCS.Site), CalleeF(DSCS.CalleeF), CalleeN(DSCS.CalleeN), RetVal(DSCS.RetVal), VarArgVal(DSCS.VarArgVal), - CallArgs(DSCS.CallArgs) {} + CallArgs(DSCS.CallArgs), MappedSites(DSCS.MappedSites) {} /// Mapping copy constructor - This constructor takes a preexisting call site /// to copy plus a map that specifies how the links should be transformed. From zwarich at apple.com Tue Dec 21 00:54:43 2010 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 21 Dec 2010 06:54:43 -0000 Subject: [llvm-commits] [llvm] r122321 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20101221065443.F2F7E2A6C12C@llvm.org> Author: zwarich Date: Tue Dec 21 00:54:43 2010 New Revision: 122321 URL: http://llvm.org/viewvc/llvm-project?rev=122321&view=rev Log: Incremental progress towards a new implementation of StrongPHIElimination. Most of the problems with my last attempt were in the updating of LiveIntervals rather than the coalescing itself. Therefore, I decided to get that right first by essentially reimplementing the existing PHIElimination using LiveIntervals. It works correctly, with only a few tests failing (which may not be legitimate failures) and no new verifier failures (at least as far as I can tell, I didn't count the number per file). Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=122321&r1=122320&r2=122321&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Tue Dec 21 00:54:43 2010 @@ -11,11 +11,15 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "strongphielim" +#include "PHIEliminationUtils.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Support/ErrorHandling.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/Debug.h" using namespace llvm; namespace { @@ -28,6 +32,16 @@ virtual void getAnalysisUsage(AnalysisUsage&) const; bool runOnMachineFunction(MachineFunction&); + + private: + void InsertCopiesForPHI(MachineInstr*, MachineBasicBlock*); + + MachineRegisterInfo* MRI; + const TargetInstrInfo* TII; + LiveIntervals* LI; + + typedef DenseSet > CopySet; + CopySet InsertedCopies; }; } // namespace @@ -52,6 +66,175 @@ MachineFunctionPass::getAnalysisUsage(AU); } -bool StrongPHIElimination::runOnMachineFunction(MachineFunction& Fn) { - llvm_unreachable("Strong phi elimination is not implemented"); +static MachineOperand* findLastUse(MachineBasicBlock* MBB, unsigned Reg) { + // FIXME: This only needs to check from the first terminator, as only the + // first terminator can use a virtual register. + for (MachineBasicBlock::reverse_iterator RI = MBB->rbegin(); ; ++RI) { + assert (RI != MBB->rend()); + MachineInstr* MI = &*RI; + + for (MachineInstr::mop_iterator OI = MI->operands_begin(), + OE = MI->operands_end(); OI != OE; ++OI) { + MachineOperand& MO = *OI; + if (MO.isReg() && MO.isUse() && MO.getReg() == Reg) + return &MO; + } + } + return NULL; +} + +bool StrongPHIElimination::runOnMachineFunction(MachineFunction& MF) { + MRI = &MF.getRegInfo(); + TII = MF.getTarget().getInstrInfo(); + LI = &getAnalysis(); + + // Insert copies for all PHI source and destination registers. + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE && BBI->isPHI(); ++BBI) { + InsertCopiesForPHI(BBI, I); + } + } + + // Adjust the live intervals of all PHI source registers to handle the case + // where the PHIs in successor blocks were the only later uses of the source + // register. + for (CopySet::iterator I = InsertedCopies.begin(), E = InsertedCopies.end(); + I != E; ++I) { + MachineBasicBlock* MBB = I->first; + unsigned SrcReg = I->second; + LiveInterval& SrcLI = LI->getInterval(SrcReg); + + bool isLiveOut = false; + for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), + SE = MBB->succ_end(); SI != SE; ++SI) { + if (SrcLI.liveAt(LI->getMBBStartIdx(*SI))) { + isLiveOut = true; + break; + } + } + + if (isLiveOut) + continue; + + MachineOperand* LastUse = findLastUse(MBB, SrcReg); + assert(LastUse); + SrcLI.removeRange(LI->getInstructionIndex(LastUse->getParent()).getDefIndex(), + LI->getMBBEndIdx(MBB)); + LastUse->setIsKill(true); + } + + // Remove all PHI instructions from the function. + bool Changed = false; + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end(); + while (BBI != BBE && BBI->isPHI()) { + MachineInstr* PHI = BBI; + ++BBI; + LI->RemoveMachineInstrFromMaps(PHI); + PHI->eraseFromParent(); + Changed = true; + } + } + + LI->renumber(); + MF.verify(this); + + InsertedCopies.clear(); + + return Changed; +} + +void StrongPHIElimination::InsertCopiesForPHI(MachineInstr* PHI, + MachineBasicBlock* MBB) { + assert(PHI->isPHI()); + unsigned DestReg = PHI->getOperand(0).getReg(); + + const TargetRegisterClass* RC = MRI->getRegClass(DestReg); + unsigned CopyReg = MRI->createVirtualRegister(RC); + + MachineInstr* CopyInstr = BuildMI(*MBB, + MBB->SkipPHIsAndLabels(MBB->begin()), + PHI->getDebugLoc(), + TII->get(TargetOpcode::COPY), + DestReg).addReg(CopyReg); + LI->InsertMachineInstrInMaps(CopyInstr); + CopyInstr->getOperand(1).setIsKill(true); + + // Add the region from the beginning of MBB to the copy instruction to + // CopyReg's live interval, and give the VNInfo the phidef flag. + LiveInterval& CopyLI = LI->getOrCreateInterval(CopyReg); + SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB); + SlotIndex DestCopyIndex = LI->getInstructionIndex(CopyInstr); + VNInfo* CopyVNI = CopyLI.getNextValue(MBBStartIndex, + CopyInstr, + LI->getVNInfoAllocator()); + CopyVNI->setIsPHIDef(true); + CopyLI.addRange(LiveRange(MBBStartIndex, + DestCopyIndex.getDefIndex(), + CopyVNI)); + + // Adjust DestReg's live interval to adjust for its new definition at + // CopyInstr. + LiveInterval& DestLI = LI->getOrCreateInterval(DestReg); + SlotIndex PHIIndex = LI->getInstructionIndex(PHI); + DestLI.removeRange(PHIIndex.getDefIndex(), DestCopyIndex.getDefIndex()); + + VNInfo* DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getDefIndex()); + assert(DestVNI); + DestVNI->def = DestCopyIndex.getDefIndex(); + + SmallPtrSet MBBsInsertedInto; + for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) { + MachineOperand& SrcMO = PHI->getOperand(i); + unsigned SrcReg = SrcMO.getReg(); + unsigned SrcSubReg = SrcMO.getSubReg(); + + assert(TargetRegisterInfo::isVirtualRegister(SrcReg) && + "Machine PHI Operands must all be virtual registers!"); + + // If source is defined by an implicit def, there is no need to insert a + // copy. + // FIXME: For some reason, if LiveIntervals is run prior to PHI elimination + // implcit defs have no defining instruction. Is this expected? + MachineInstr* DefMI = MRI->getVRegDef(SrcReg); + if (!DefMI) + continue; + + MachineBasicBlock* PredBB = PHI->getOperand(i + 1).getMBB(); + + // A copy may have already been inserted in the predecessor in the case of a + // block with multiple incoming edges. + if (!MBBsInsertedInto.insert(PredBB)) + continue; + + MachineBasicBlock::iterator + CopyInsertPoint = findPHICopyInsertPoint(PredBB, MBB, SrcReg); + MachineInstr* CopyInstr = BuildMI(*PredBB, + CopyInsertPoint, + PHI->getDebugLoc(), + TII->get(TargetOpcode::COPY), + CopyReg).addReg(SrcReg, 0, SrcSubReg); + LI->InsertMachineInstrInMaps(CopyInstr); + + // addLiveRangeToEndOfBlock() also adds the phikill flag to the VNInfo for + // the newly added range. + LI->addLiveRangeToEndOfBlock(CopyReg, CopyInstr); + InsertedCopies.insert(std::make_pair(PredBB, SrcReg)); + + // If SrcReg is not live beyond the PHI, trim its interval so that it is no + // longer live-in to MBB. Note that SrcReg may appear in other PHIs that are + // processed later, but this is still correct to do at this point because we + // never rely on LiveIntervals being correct while inserting copies. + // FIXME: Should this just count uses at PHIs like the normal PHIElimination + // pass does? + LiveInterval& SrcLI = LI->getInterval(SrcReg); + SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB); + SlotIndex PHIIndex = LI->getInstructionIndex(PHI); + SlotIndex NextInstrIndex = PHIIndex.getNextIndex(); + if (SrcLI.liveAt(MBBStartIndex) && SrcLI.expiredAt(NextInstrIndex)) + SrcLI.removeRange(MBBStartIndex, PHIIndex, true); + } } From baldrick at free.fr Tue Dec 21 02:49:00 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 08:49:00 -0000 Subject: [llvm-commits] [llvm] r122326 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/ test/Transforms/InstSimplify/2010-12-20-Reassociate.ll test/Transforms/InstSimplify/dg.exp Message-ID: <20101221084900.DFBF42A6C12D@llvm.org> Author: baldrick Date: Tue Dec 21 02:49:00 2010 New Revision: 122326 URL: http://llvm.org/viewvc/llvm-project?rev=122326&view=rev Log: Add generic simplification of associative operations, generalizing a couple of existing transforms. This fires surprisingly often, for example when compiling gcc "(X+(-1))+1->X" fires quite a lot as well as various "and" simplifications (usually with a phi node operand). Most of the time this doesn't make a real difference since the same thing would have been done elsewhere anyway, eg: by instcombine, but there are a few places where this results in simplifications that we were not doing before. Added: llvm/trunk/test/Transforms/InstSimplify/ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Reassociate.ll llvm/trunk/test/Transforms/InstSimplify/dg.exp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122326&r1=122325&r2=122326&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 02:49:00 2010 @@ -53,6 +53,100 @@ return false; } +// SimplifyAssociativeBinOp - Generic simplifications for associative binary +// operations. Returns the simpler value, or null if none was found. +static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS, + const TargetData *TD, + const DominatorTree *DT, + unsigned MaxRecurse) { + assert(Instruction::isAssociative(Opcode) && "Not an associative operation!"); + + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + + BinaryOperator *Op0 = dyn_cast(LHS); + BinaryOperator *Op1 = dyn_cast(RHS); + + // Transform: "(A op B) op C" ==> "A op (B op C)" if it simplifies completely. + if (Op0 && Op0->getOpcode() == Opcode) { + Value *A = Op0->getOperand(0); + Value *B = Op0->getOperand(1); + Value *C = RHS; + + // Does "B op C" simplify? + if (Value *V = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { + // It does! Return "A op V" if it simplifies or is already available. + // If V equals B then "A op V" is just the LHS. + if (V == B) + return LHS; + // Otherwise return "A op V" if it simplifies. + if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) + return W; + } + } + + // Transform: "A op (B op C)" ==> "(A op B) op C" if it simplifies completely. + if (Op1 && Op1->getOpcode() == Opcode) { + Value *A = LHS; + Value *B = Op1->getOperand(0); + Value *C = Op1->getOperand(1); + + // Does "A op B" simplify? + if (Value *V = SimplifyBinOp(Opcode, A, B, TD, DT, MaxRecurse)) { + // It does! Return "V op C" if it simplifies or is already available. + // If V equals B then "V op C" is just the RHS. + if (V == B) + return RHS; + // Otherwise return "V op C" if it simplifies. + if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) + return W; + } + } + + // The remaining transforms require commutativity as well as associativity. + if (!Instruction::isCommutative(Opcode)) + return 0; + + // Transform: "(A op B) op C" ==> "(C op A) op B" if it simplifies completely. + if (Op0 && Op0->getOpcode() == Opcode) { + Value *A = Op0->getOperand(0); + Value *B = Op0->getOperand(1); + Value *C = RHS; + + // Does "C op A" simplify? + if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { + // It does! Return "V op B" if it simplifies or is already available. + // If V equals A then "V op B" is just the LHS. + if (V == A) + return LHS; + // Otherwise return "V op B" if it simplifies. + if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) + return W; + } + } + + // Transform: "A op (B op C)" ==> "B op (C op A)" if it simplifies completely. + if (Op1 && Op1->getOpcode() == Opcode) { + Value *A = LHS; + Value *B = Op1->getOperand(0); + Value *C = Op1->getOperand(1); + + // Does "C op A" simplify? + if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { + // It does! Return "B op V" if it simplifies or is already available. + // If V equals C then "B op V" is just the RHS. + if (V == C) + return RHS; + // Otherwise return "B op V" if it simplifies. + if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) + return W; + } + } + + return 0; +} + /// ThreadBinOpOverSelect - In the case of a binary operation with a select /// instruction as an operand, try to simplify the binop by seeing whether /// evaluating it on both branches of the select results in the same value. @@ -266,6 +360,11 @@ match(Op1, m_Not(m_Specific(Op0)))) return Constant::getAllOnesValue(Op0->getType()); + // Try some generic simplifications for associative operations. + if (Value *V = SimplifyAssociativeBinOp(Instruction::Add, Op0, Op1, TD, DT, + MaxRecurse)) + return V; + // Threading Add over selects and phi nodes is pointless, so don't bother. // Threading over the select in "A + select(cond, B, C)" means evaluating // "A+B" and "A+C" and seeing if they are equal; but they are equal if and @@ -379,15 +478,10 @@ (A == Op0 || B == Op0)) return Op0; - // (A & B) & A -> A & B - if (match(Op0, m_And(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) - return Op0; - - // A & (A & B) -> A & B - if (match(Op1, m_And(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) - return Op1; + // Try some generic simplifications for associative operations. + if (Value *V = SimplifyAssociativeBinOp(Instruction::And, Op0, Op1, TD, DT, + MaxRecurse)) + return V; // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. @@ -458,15 +552,10 @@ (A == Op0 || B == Op0)) return Op0; - // (A | B) | A -> A | B - if (match(Op0, m_Or(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) - return Op0; - - // A | (A | B) -> A | B - if (match(Op1, m_Or(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) - return Op1; + // Try some generic simplifications for associative operations. + if (Value *V = SimplifyAssociativeBinOp(Instruction::Or, Op0, Op1, TD, DT, + MaxRecurse)) + return V; // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. @@ -518,20 +607,15 @@ return Constant::getNullValue(Op0->getType()); // A ^ ~A = ~A ^ A = -1 - Value *A = 0, *B = 0; + Value *A = 0; if ((match(Op0, m_Not(m_Value(A))) && A == Op1) || (match(Op1, m_Not(m_Value(A))) && A == Op0)) return Constant::getAllOnesValue(Op0->getType()); - // (A ^ B) ^ A = B - if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) - return A == Op1 ? B : A; - - // A ^ (A ^ B) = B - if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) - return A == Op0 ? B : A; + // Try some generic simplifications for associative operations. + if (Value *V = SimplifyAssociativeBinOp(Instruction::Xor, Op0, Op1, TD, DT, + MaxRecurse)) + return V; // Threading Xor over selects and phi nodes is pointless, so don't bother. // Threading over the select in "A ^ select(cond, B, C)" means evaluating @@ -855,6 +939,12 @@ return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, TD); } + // If the operation is associative, try some generic simplifications. + if (Instruction::isAssociative(Opcode)) + if (Value *V = SimplifyAssociativeBinOp(Opcode, LHS, RHS, TD, DT, + MaxRecurse)) + return V; + // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (MaxRecurse && (isa(LHS) || isa(RHS))) Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Reassociate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Reassociate.ll?rev=122326&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Reassociate.ll (added) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Reassociate.ll Tue Dec 21 02:49:00 2010 @@ -0,0 +1,64 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s + +define i32 @add1(i32 %x) { +; CHECK: @add1 +; (X + -1) + 1 -> X + %l = add i32 %x, -1 + %r = add i32 %l, 1 + ret i32 %r +; CHECK: ret i32 %x +} + +define i32 @and1(i32 %x, i32 %y) { +; CHECK: @and1 +; (X & Y) & X -> X & Y + %l = and i32 %x, %y + %r = and i32 %l, %x + ret i32 %r +; CHECK: ret i32 %l +} + +define i32 @and2(i32 %x, i32 %y) { +; CHECK: @and2 +; X & (X & Y) -> X & Y + %r = and i32 %x, %y + %l = and i32 %x, %r + ret i32 %l +; CHECK: ret i32 %r +} + +define i32 @or1(i32 %x, i32 %y) { +; CHECK: @or1 +; (X | Y) | X -> X | Y + %l = or i32 %x, %y + %r = or i32 %l, %x + ret i32 %r +; CHECK: ret i32 %l +} + +define i32 @or2(i32 %x, i32 %y) { +; CHECK: @or2 +; X | (X | Y) -> X | Y + %r = or i32 %x, %y + %l = or i32 %x, %r + ret i32 %l +; CHECK: ret i32 %r +} + +define i32 @xor1(i32 %x, i32 %y) { +; CHECK: @xor1 +; (X ^ Y) ^ X = Y + %l = xor i32 %x, %y + %r = xor i32 %l, %x + ret i32 %r +; CHECK: ret i32 %y +} + +define i32 @xor2(i32 %x, i32 %y) { +; CHECK: @xor2 +; X ^ (X ^ Y) = Y + %r = xor i32 %x, %y + %l = xor i32 %x, %r + ret i32 %l +; CHECK: ret i32 %y +} Added: llvm/trunk/test/Transforms/InstSimplify/dg.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/dg.exp?rev=122326&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/dg.exp (added) +++ llvm/trunk/test/Transforms/InstSimplify/dg.exp Tue Dec 21 02:49:00 2010 @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] From baldrick at free.fr Tue Dec 21 03:09:15 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 09:09:15 -0000 Subject: [llvm-commits] [llvm] r122327 - /llvm/trunk/lib/Analysis/InstructionSimplify.cpp Message-ID: <20101221090915.67EA32A6C12D@llvm.org> Author: baldrick Date: Tue Dec 21 03:09:15 2010 New Revision: 122327 URL: http://llvm.org/viewvc/llvm-project?rev=122327&view=rev Log: Move checking of the recursion limit into the various Thread methods. No functionality change. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122327&r1=122326&r2=122327&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 03:09:15 2010 @@ -155,6 +155,10 @@ const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + SelectInst *SI; if (isa(LHS)) { SI = cast(LHS); @@ -225,6 +229,10 @@ Value *RHS, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + // Make sure the select is on the LHS. if (!isa(LHS)) { std::swap(LHS, RHS); @@ -254,6 +262,10 @@ static Value *ThreadBinOpOverPHI(unsigned Opcode, Value *LHS, Value *RHS, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + PHINode *PI; if (isa(LHS)) { PI = cast(LHS); @@ -294,6 +306,10 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + // Make sure the phi is on the LHS. if (!isa(LHS)) { std::swap(LHS, RHS); @@ -485,16 +501,16 @@ // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. - if (MaxRecurse && (isa(Op0) || isa(Op1))) + if (isa(Op0) || isa(Op1)) if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, TD, DT, - MaxRecurse-1)) + MaxRecurse)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. - if (MaxRecurse && (isa(Op0) || isa(Op1))) + if (isa(Op0) || isa(Op1)) if (Value *V = ThreadBinOpOverPHI(Instruction::And, Op0, Op1, TD, DT, - MaxRecurse-1)) + MaxRecurse)) return V; return 0; @@ -559,16 +575,16 @@ // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. - if (MaxRecurse && (isa(Op0) || isa(Op1))) + if (isa(Op0) || isa(Op1)) if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, TD, DT, - MaxRecurse-1)) + MaxRecurse)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. - if (MaxRecurse && (isa(Op0) || isa(Op1))) + if (isa(Op0) || isa(Op1)) if (Value *V = ThreadBinOpOverPHI(Instruction::Or, Op0, Op1, TD, DT, - MaxRecurse-1)) + MaxRecurse)) return V; return 0; @@ -700,14 +716,14 @@ // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. - if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) + if (isa(LHS) || isa(RHS)) + if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse)) return V; // If the comparison is with the result of a phi instruction, check whether // doing the compare with each incoming phi value yields a common result. - if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) + if (isa(LHS) || isa(RHS)) + if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse)) return V; return 0; @@ -795,14 +811,14 @@ // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. - if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) + if (isa(LHS) || isa(RHS)) + if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse)) return V; // If the comparison is with the result of a phi instruction, check whether // doing the compare with each incoming phi value yields a common result. - if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) + if (isa(LHS) || isa(RHS)) + if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse)) return V; return 0; @@ -947,15 +963,15 @@ // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. - if (MaxRecurse && (isa(LHS) || isa(RHS))) + if (isa(LHS) || isa(RHS)) if (Value *V = ThreadBinOpOverSelect(Opcode, LHS, RHS, TD, DT, - MaxRecurse-1)) + MaxRecurse)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. - if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadBinOpOverPHI(Opcode, LHS, RHS, TD, DT, MaxRecurse-1)) + if (isa(LHS) || isa(RHS)) + if (Value *V = ThreadBinOpOverPHI(Opcode, LHS, RHS, TD, DT, MaxRecurse)) return V; return 0; From baldrick at free.fr Tue Dec 21 07:32:22 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 13:32:22 -0000 Subject: [llvm-commits] [llvm] r122328 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2010-12-20-Distribute.ll Message-ID: <20101221133222.5CA352A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 07:32:22 2010 New Revision: 122328 URL: http://llvm.org/viewvc/llvm-project?rev=122328&view=rev Log: Teach InstructionSimplify about distributive laws. These transforms fire quite often, but don't make much difference in practice presumably because instcombine also knows them and more. Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122328&r1=122327&r2=122328&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 07:32:22 2010 @@ -53,8 +53,120 @@ return false; } -// SimplifyAssociativeBinOp - Generic simplifications for associative binary -// operations. Returns the simpler value, or null if none was found. +/// ExpandBinOp - Simplify "A op (B op' C)" by distributing op over op', turning +/// it into "(A op B) op' (A op C)". Here "op" is given by Opcode and "op'" is +/// given by OpcodeToExpand, while "A" corresponds to LHS and "B op' C" to RHS. +/// Also performs the transform "(A op' B) op C" -> "(A op C) op' (B op C)". +/// Returns the simplified value, or null if no simplification was performed. +static Value *ExpandBinOp(unsigned Opcode, Value *LHS, Value *RHS, + unsigned OpcodeToExpand, const TargetData *TD, + const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + + // Check whether the expression has the form "(A op' B) op C". + if (BinaryOperator *Op0 = dyn_cast(LHS)) + if (Op0->getOpcode() == OpcodeToExpand) { + // It does! Try turning it into "(A op C) op' (B op C)". + Value *A = Op0->getOperand(0), *B = Op0->getOperand(1), *C = RHS; + // Do "A op C" and "B op C" both simplify? + if (Value *L = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) + if (Value *R = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { + // They do! Return "L op' R" if it simplifies or is already available. + // If "L op' R" equals "A op' B" then "L op' R" is just the LHS. + if ((L == A && R == B) || + (Instruction::isCommutative(OpcodeToExpand) && L == B && R == A)) + return LHS; + // Otherwise return "L op' R" if it simplifies. + if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse)) + return V; + } + } + + // Check whether the expression has the form "A op (B op' C)". + if (BinaryOperator *Op1 = dyn_cast(RHS)) + if (Op1->getOpcode() == OpcodeToExpand) { + // It does! Try turning it into "(A op B) op' (A op C)". + Value *A = LHS, *B = Op1->getOperand(0), *C = Op1->getOperand(1); + // Do "A op B" and "A op C" both simplify? + if (Value *L = SimplifyBinOp(Opcode, A, B, TD, DT, MaxRecurse)) + if (Value *R = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) { + // They do! Return "L op' R" if it simplifies or is already available. + // If "L op' R" equals "B op' C" then "L op' R" is just the RHS. + if ((L == B && R == C) || + (Instruction::isCommutative(OpcodeToExpand) && L == C && R == B)) + return RHS; + // Otherwise return "L op' R" if it simplifies. + if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse)) + return V; + } + } + + return 0; +} + +/// FactorizeBinOp - Simplify "LHS Opcode RHS" by factorizing out a common term +/// using the operation OpCodeToExtract. For example, when Opcode is Add and +/// OpCodeToExtract is Mul then this tries to turn "(A*B)+(A*C)" into "A*(B+C)". +/// Returns the simplified value, or null if no simplification was performed. +static Value *FactorizeBinOp(unsigned Opcode, Value *LHS, Value *RHS, + unsigned OpcodeToExtract, const TargetData *TD, + const DominatorTree *DT, unsigned MaxRecurse) { + // Recursion is always used, so bail out at once if we already hit the limit. + if (!MaxRecurse--) + return 0; + + BinaryOperator *Op0 = dyn_cast(LHS); + BinaryOperator *Op1 = dyn_cast(RHS); + + if (!Op0 || Op0->getOpcode() != OpcodeToExtract || + !Op1 || Op1->getOpcode() != OpcodeToExtract) + return 0; + + // The expression has the form "(A op' B) op (C op' D)". + Value *A = Op0->getOperand(0); Value *B = Op0->getOperand(1); + Value *C = Op1->getOperand(0); Value *D = Op1->getOperand(1); + + // Use left distributivity, i.e. "X op' (Y op Z) = (X op' Y) op (X op' Z)". + // Does the instruction have the form "(A op' B) op (A op' D)" or, in the + // commutative case, "(A op' B) op (C op' A)"? + if (A == C || (Instruction::isCommutative(OpcodeToExtract) && A == D)) { + Value *DD = A == C ? D : C; + // Form "A op' (B op DD)" if it simplifies completely. + // Does "B op DD" simplify? + if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) { + // It does! Return "A op' V" if it simplifies or is already available. + // If V equals B then "A op' V" is just the LHS. + if (V == B) return LHS; + // Otherwise return "A op' V" if it simplifies. + if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) + return W; + } + } + + // Use right distributivity, i.e. "(X op Y) op' Z = (X op' Z) op (Y op' Z)". + // Does the instruction have the form "(A op' B) op (C op' B)" or, in the + // commutative case, "(A op' B) op (B op' D)"? + if (B == D || (Instruction::isCommutative(OpcodeToExtract) && B == C)) { + Value *CC = B == D ? C : D; + // Form "(A op CC) op' B" if it simplifies completely.. + // Does "A op CC" simplify? + if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) { + // It does! Return "V op' B" if it simplifies or is already available. + // If V equals A then "V op' B" is just the LHS. + if (V == B) return LHS; + // Otherwise return "V op' B" if it simplifies. + if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) + return W; + } + } + + return 0; +} + +/// SimplifyAssociativeBinOp - Generic simplifications for associative binary +/// operations. Returns the simpler value, or null if none was found. static Value *SimplifyAssociativeBinOp(unsigned Opcode, Value *LHS, Value *RHS, const TargetData *TD, const DominatorTree *DT, @@ -78,8 +190,7 @@ if (Value *V = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // It does! Return "A op V" if it simplifies or is already available. // If V equals B then "A op V" is just the LHS. - if (V == B) - return LHS; + if (V == B) return LHS; // Otherwise return "A op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) return W; @@ -96,8 +207,7 @@ if (Value *V = SimplifyBinOp(Opcode, A, B, TD, DT, MaxRecurse)) { // It does! Return "V op C" if it simplifies or is already available. // If V equals B then "V op C" is just the RHS. - if (V == B) - return RHS; + if (V == B) return RHS; // Otherwise return "V op C" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) return W; @@ -118,8 +228,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "V op B" if it simplifies or is already available. // If V equals A then "V op B" is just the LHS. - if (V == A) - return LHS; + if (V == A) return LHS; // Otherwise return "V op B" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) return W; @@ -136,8 +245,7 @@ if (Value *V = SimplifyBinOp(Opcode, C, A, TD, DT, MaxRecurse)) { // It does! Return "B op V" if it simplifies or is already available. // If V equals C then "B op V" is just the RHS. - if (V == C) - return RHS; + if (V == C) return RHS; // Otherwise return "B op V" if it simplifies. if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) return W; @@ -381,6 +489,11 @@ MaxRecurse)) return V; + // Mul distributes over Add. Try some generic simplifications based on this. + if (Value *V = FactorizeBinOp(Instruction::Add, Op0, Op1, Instruction::Mul, + TD, DT, MaxRecurse)) + return V; + // Threading Add over selects and phi nodes is pointless, so don't bother. // Threading over the select in "A + select(cond, B, C)" means evaluating // "A+B" and "A+C" and seeing if they are equal; but they are equal if and @@ -401,7 +514,7 @@ /// SimplifySubInst - Given operands for a Sub, see if we can /// fold the result. If not, this returns null. static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const TargetData *TD, const DominatorTree *, + const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) if (Constant *CRHS = dyn_cast(Op1)) { @@ -430,6 +543,11 @@ match(Op0, m_Add(m_Specific(Op1), m_Value(X)))) return X; + // Mul distributes over Sub. Try some generic simplifications based on this. + if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul, + TD, DT, MaxRecurse)) + return V; + // Threading Sub over selects and phi nodes is pointless, so don't bother. // Threading over the select in "A - select(cond, B, C)" means evaluating // "A-B" and "A-C" and seeing if they are equal; but they are equal if and @@ -499,6 +617,21 @@ MaxRecurse)) return V; + // And distributes over Or. Try some generic simplifications based on this. + if (Value *V = ExpandBinOp(Instruction::And, Op0, Op1, Instruction::Or, + TD, DT, MaxRecurse)) + return V; + + // And distributes over Xor. Try some generic simplifications based on this. + if (Value *V = ExpandBinOp(Instruction::And, Op0, Op1, Instruction::Xor, + TD, DT, MaxRecurse)) + return V; + + // Or distributes over And. Try some generic simplifications based on this. + if (Value *V = FactorizeBinOp(Instruction::And, Op0, Op1, Instruction::Or, + TD, DT, MaxRecurse)) + return V; + // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (isa(Op0) || isa(Op1)) @@ -573,6 +706,16 @@ MaxRecurse)) return V; + // Or distributes over And. Try some generic simplifications based on this. + if (Value *V = ExpandBinOp(Instruction::Or, Op0, Op1, Instruction::And, + TD, DT, MaxRecurse)) + return V; + + // And distributes over Or. Try some generic simplifications based on this. + if (Value *V = FactorizeBinOp(Instruction::Or, Op0, Op1, Instruction::And, + TD, DT, MaxRecurse)) + return V; + // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (isa(Op0) || isa(Op1)) @@ -633,6 +776,11 @@ MaxRecurse)) return V; + // And distributes over Xor. Try some generic simplifications based on this. + if (Value *V = FactorizeBinOp(Instruction::Xor, Op0, Op1, Instruction::And, + TD, DT, MaxRecurse)) + return V; + // Threading Xor over selects and phi nodes is pointless, so don't bother. // Threading over the select in "A ^ select(cond, B, C)" means evaluating // "A^B" and "A^C" and seeing if they are equal; but they are equal if and Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll?rev=122328&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll (added) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Tue Dec 21 07:32:22 2010 @@ -0,0 +1,21 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s + +define i32 @factorize(i32 %x, i32 %y) { +; CHECK: @factorize +; (X | 2) & (X | 2) -> X | (1 & 2) -> X + %l = or i32 %x, 1 + %r = or i32 %x, 2 + %z = and i32 %l, %r + ret i32 %z +; CHECK: ret i32 %x +} + +define i32 @expand(i32 %x) { +; CHECK: @expand +; ((X & 1) | 2) & 1 -> ((X & 1) & 1) | (2 & 1) -> (X & 1) | 0 -> X & 1 + %a = and i32 %x, 1 + %b = or i32 %a, 2 + %c = and i32 %b, 1 + ret i32 %c +; CHECK: ret i32 %a +} From baldrick at free.fr Tue Dec 21 07:39:20 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 13:39:20 -0000 Subject: [llvm-commits] [llvm] r122329 - /llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Message-ID: <20101221133920.A4F372A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 07:39:20 2010 New Revision: 122329 URL: http://llvm.org/viewvc/llvm-project?rev=122329&view=rev Log: Fix typo in comment, spotted by Deewiant. Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll?rev=122329&r1=122328&r2=122329&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll (original) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Tue Dec 21 07:39:20 2010 @@ -2,7 +2,7 @@ define i32 @factorize(i32 %x, i32 %y) { ; CHECK: @factorize -; (X | 2) & (X | 2) -> X | (1 & 2) -> X +; (X | 1) & (X | 2) -> X | (1 & 2) -> X %l = or i32 %x, 1 %r = or i32 %x, 2 %z = and i32 %l, %r From baldrick at free.fr Tue Dec 21 08:00:22 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 14:00:22 -0000 Subject: [llvm-commits] [llvm] r122330 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Message-ID: <20101221140022.6ABC12A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 08:00:22 2010 New Revision: 122330 URL: http://llvm.org/viewvc/llvm-project?rev=122330&view=rev Log: Pull a few more simplifications out of instcombine (there are still plenty left though!), in particular for multiplication. Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=122330&r1=122329&r2=122330&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original) +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Tue Dec 21 08:00:22 2010 @@ -39,6 +39,11 @@ Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0, const DominatorTree *DT = 0); + /// SimplifyMulInst - Given operands for a Mul, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); + /// SimplifyOrInst - Given operands for an Or, see if we can /// fold the result. If not, this returns null. Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122330&r1=122329&r2=122330&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 08:00:22 2010 @@ -28,10 +28,16 @@ #define RecursionLimit 3 +static Value *SimplifyAndInst(Value *, Value *, const TargetData *, + const DominatorTree *, unsigned); static Value *SimplifyBinOp(unsigned, Value *, Value *, const TargetData *, const DominatorTree *, unsigned); static Value *SimplifyCmpInst(unsigned, Value *, Value *, const TargetData *, const DominatorTree *, unsigned); +static Value *SimplifyOrInst(Value *, Value *, const TargetData *, + const DominatorTree *, unsigned); +static Value *SimplifyXorInst(Value *, Value *, const TargetData *, + const DominatorTree *, unsigned); /// ValueDominatesPHI - Does the given value dominate the specified phi node? static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { @@ -125,8 +131,8 @@ return 0; // The expression has the form "(A op' B) op (C op' D)". - Value *A = Op0->getOperand(0); Value *B = Op0->getOperand(1); - Value *C = Op1->getOperand(0); Value *D = Op1->getOperand(1); + Value *A = Op0->getOperand(0), *B = Op0->getOperand(1); + Value *C = Op1->getOperand(0), *D = Op1->getOperand(1); // Use left distributivity, i.e. "X op' (Y op Z) = (X op' Y) op (X op' Z)". // Does the instruction have the form "(A op' B) op (A op' D)" or, in the @@ -484,6 +490,10 @@ match(Op1, m_Not(m_Specific(Op0)))) return Constant::getAllOnesValue(Op0->getType()); + /// i1 add -> xor. + if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); + // Try some generic simplifications for associative operations. if (Value *V = SimplifyAssociativeBinOp(Instruction::Add, Op0, Op1, TD, DT, MaxRecurse)) @@ -543,6 +553,10 @@ match(Op0, m_Add(m_Specific(Op1), m_Value(X)))) return X; + /// i1 sub -> xor. + if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); + // Mul distributes over Sub. Try some generic simplifications based on this. if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul, TD, DT, MaxRecurse)) @@ -565,6 +579,69 @@ return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit); } +/// SimplifyMulInst - Given operands for a Mul, see if we can +/// fold the result. If not, this returns null. +static Value *SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD, + const DominatorTree *DT, unsigned MaxRecurse) { + if (Constant *CLHS = dyn_cast(Op0)) { + if (Constant *CRHS = dyn_cast(Op1)) { + Constant *Ops[] = { CLHS, CRHS }; + return ConstantFoldInstOperands(Instruction::Mul, CLHS->getType(), + Ops, 2, TD); + } + + // Canonicalize the constant to the RHS. + std::swap(Op0, Op1); + } + + // X * undef -> 0 + if (isa(Op1)) + return Constant::getNullValue(Op0->getType()); + + // X * 0 -> 0 + if (match(Op1, m_Zero())) + return Op1; + + // X * 1 -> X + if (match(Op1, m_One())) + return Op0; + + /// i1 mul -> and. + if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + return SimplifyAndInst(Op0, Op1, TD, DT, MaxRecurse-1); + + // Try some generic simplifications for associative operations. + if (Value *V = SimplifyAssociativeBinOp(Instruction::Mul, Op0, Op1, TD, DT, + MaxRecurse)) + return V; + + // Mul distributes over Add. Try some generic simplifications based on this. + if (Value *V = ExpandBinOp(Instruction::Mul, Op0, Op1, Instruction::Add, + TD, DT, MaxRecurse)) + return V; + + // If the operation is with the result of a select instruction, check whether + // operating on either branch of the select always yields the same value. + if (isa(Op0) || isa(Op1)) + if (Value *V = ThreadBinOpOverSelect(Instruction::Mul, Op0, Op1, TD, DT, + MaxRecurse)) + return V; + + // If the operation is with the result of a phi instruction, check whether + // operating on all incoming values of the phi always yields the same value. + if (isa(Op0) || isa(Op1)) + if (Value *V = ThreadBinOpOverPHI(Instruction::Mul, Op0, Op1, TD, DT, + MaxRecurse)) + return V; + + return 0; +} + +Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD, + const DominatorTree *DT) { + return ::SimplifyMulInst(Op0, Op1, TD, DT, RecursionLimit); +} + /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, @@ -1087,15 +1164,16 @@ const TargetData *TD, const DominatorTree *DT, unsigned MaxRecurse) { switch (Opcode) { - case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse); - case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse); - case Instruction::Xor: return SimplifyXorInst(LHS, RHS, TD, DT, MaxRecurse); case Instruction::Add: return SimplifyAddInst(LHS, RHS, /* isNSW */ false, /* isNUW */ false, TD, DT, MaxRecurse); case Instruction::Sub: return SimplifySubInst(LHS, RHS, /* isNSW */ false, /* isNUW */ false, TD, DT, MaxRecurse); + case Instruction::Mul: return SimplifyMulInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Xor: return SimplifyXorInst(LHS, RHS, TD, DT, MaxRecurse); default: if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) { @@ -1168,6 +1246,9 @@ cast(I)->hasNoUnsignedWrap(), TD, DT); break; + case Instruction::Mul: + Result = SimplifyMulInst(I->getOperand(0), I->getOperand(1), TD, DT); + break; case Instruction::And: Result = SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD, DT); break; Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=122330&r1=122329&r2=122330&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Tue Dec 21 08:00:22 2010 @@ -14,6 +14,7 @@ #include "InstCombine.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Support/PatternMatch.h" using namespace llvm; using namespace PatternMatch; @@ -50,8 +51,8 @@ bool Changed = SimplifyAssociativeOrCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (isa(Op1)) // undef * X -> 0 - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + if (Value *V = SimplifyMulInst(Op0, Op1, TD)) + return ReplaceInstUsesWith(I, V); // Simplify mul instructions with a constant RHS. if (Constant *Op1C = dyn_cast(Op1)) { @@ -64,10 +65,6 @@ return BinaryOperator::CreateMul(SI->getOperand(0), ConstantExpr::getShl(CI, ShOp)); - if (CI->isZero()) - return ReplaceInstUsesWith(I, Op1C); // X * 0 == 0 - if (CI->equalsInt(1)) // X * 1 == X - return ReplaceInstUsesWith(I, Op0); if (CI->isAllOnesValue()) // X * -1 == 0 - X return BinaryOperator::CreateNeg(Op0, I.getName()); From fvbommel at gmail.com Tue Dec 21 08:34:27 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Tue, 21 Dec 2010 15:34:27 +0100 Subject: [llvm-commits] [llvm] r122330 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp In-Reply-To: <20101221140022.6ABC12A6C12C@llvm.org> References: <20101221140022.6ABC12A6C12C@llvm.org> Message-ID: On Tue, Dec 21, 2010 at 3:00 PM, Duncan Sands wrote: > + ?/// i1 add -> xor. > + ?if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) > + ? ?return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); > + Since !MaxRecurse is true, the MaxRecurse-1 argument will overflow to ~0U. This will also return null if the xor doesn't simplify even though some later transformation might still work if it stays an 'add'. So shouldn't this be something more like /// i1 add -> xor. if (MaxRecurse && Op0->getType()->isIntegerTy(1)) if (Value *V = SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1)) return V; ? (Note the missing '!') Same goes for the 'i1 sub -> xor' and 'i1 mul -> and' transforms. From baldrick at free.fr Tue Dec 21 08:48:48 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 14:48:48 -0000 Subject: [llvm-commits] [llvm] r122331 - /llvm/trunk/lib/Analysis/InstructionSimplify.cpp Message-ID: <20101221144848.6A3CC2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 08:48:48 2010 New Revision: 122331 URL: http://llvm.org/viewvc/llvm-project?rev=122331&view=rev Log: Fix inverted condition noticed by Frits van Bommel. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122331&r1=122330&r2=122331&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 08:48:48 2010 @@ -491,7 +491,7 @@ return Constant::getAllOnesValue(Op0->getType()); /// i1 add -> xor. - if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + if (MaxRecurse && Op0->getType()->isIntegerTy(1)) return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); // Try some generic simplifications for associative operations. @@ -554,7 +554,7 @@ return X; /// i1 sub -> xor. - if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + if (MaxRecurse && Op0->getType()->isIntegerTy(1)) return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); // Mul distributes over Sub. Try some generic simplifications based on this. @@ -607,7 +607,7 @@ return Op0; /// i1 mul -> and. - if (!MaxRecurse && Op0->getType()->isIntegerTy(1)) + if (MaxRecurse && Op0->getType()->isIntegerTy(1)) return SimplifyAndInst(Op0, Op1, TD, DT, MaxRecurse-1); // Try some generic simplifications for associative operations. From baldrick at free.fr Tue Dec 21 08:51:56 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 15:51:56 +0100 Subject: [llvm-commits] [llvm] r122330 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp In-Reply-To: References: <20101221140022.6ABC12A6C12C@llvm.org> Message-ID: <4D10BF0C.6060607@free.fr> Hi Frits, > On Tue, Dec 21, 2010 at 3:00 PM, Duncan Sands wrote: >> + /// i1 add -> xor. >> + if (!MaxRecurse&& Op0->getType()->isIntegerTy(1)) >> + return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); >> + > > Since !MaxRecurse is true, the MaxRecurse-1 argument will overflow to ~0U. oops, fat fingers! Now fixed - thanks. > This will also return null if the xor doesn't simplify even though > some later transformation might still work if it stays an 'add'. I don't think that is possible. I debated this with myself for some time - skipping the extra tests should give a small speedup. Maybe I will change my mind again - I'm meditating on it :) > So shouldn't this be something more like > /// i1 add -> xor. > if (MaxRecurse&& Op0->getType()->isIntegerTy(1)) > if (Value *V = SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1)) > return V; > ? > (Note the missing '!') Ciao, Duncan. From baldrick at free.fr Tue Dec 21 09:03:43 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 15:03:43 -0000 Subject: [llvm-commits] [llvm] r122332 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll Message-ID: <20101221150343.67CC82A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 09:03:43 2010 New Revision: 122332 URL: http://llvm.org/viewvc/llvm-project?rev=122332&view=rev Log: While I don't think any later transforms can fire, it seems cleaner to not assume this (for example in case more transforms get added below it). Suggested by Frits van Bommel. Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122332&r1=122331&r2=122332&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Dec 21 09:03:43 2010 @@ -492,7 +492,8 @@ /// i1 add -> xor. if (MaxRecurse && Op0->getType()->isIntegerTy(1)) - return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); + if (Value *V = SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1)) + return V; // Try some generic simplifications for associative operations. if (Value *V = SimplifyAssociativeBinOp(Instruction::Add, Op0, Op1, TD, DT, @@ -555,7 +556,8 @@ /// i1 sub -> xor. if (MaxRecurse && Op0->getType()->isIntegerTy(1)) - return SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1); + if (Value *V = SimplifyXorInst(Op0, Op1, TD, DT, MaxRecurse-1)) + return V; // Mul distributes over Sub. Try some generic simplifications based on this. if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul, @@ -608,7 +610,8 @@ /// i1 mul -> and. if (MaxRecurse && Op0->getType()->isIntegerTy(1)) - return SimplifyAndInst(Op0, Op1, TD, DT, MaxRecurse-1); + if (Value *V = SimplifyAndInst(Op0, Op1, TD, DT, MaxRecurse-1)) + return V; // Try some generic simplifications for associative operations. if (Value *V = SimplifyAssociativeBinOp(Instruction::Mul, Op0, Op1, TD, DT, Added: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll?rev=122332&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll (added) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll Tue Dec 21 09:03:43 2010 @@ -0,0 +1,22 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s + +define i1 @add(i1 %x) { +; CHECK: @add + %z = add i1 %x, %x + ret i1 %z +; CHECK: ret i1 false +} + +define i1 @sub(i1 %x) { +; CHECK: @sub + %z = sub i1 false, %x + ret i1 %z +; CHECK: ret i1 %x +} + +define i1 @mul(i1 %x) { +; CHECK: @mul + %z = mul i1 %x, %x + ret i1 %z +; CHECK: ret i1 %x +} From baldrick at free.fr Tue Dec 21 09:12:22 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 15:12:22 -0000 Subject: [llvm-commits] [llvm] r122333 - /llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Message-ID: <20101221151222.3AE112A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 09:12:22 2010 New Revision: 122333 URL: http://llvm.org/viewvc/llvm-project?rev=122333&view=rev Log: Add an additional InstructionSimplify factorization test. Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll?rev=122333&r1=122332&r2=122333&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll (original) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Tue Dec 21 09:12:22 2010 @@ -10,6 +10,16 @@ ; CHECK: ret i32 %x } +define i32 @factorize2(i32 %x) { +; CHECK: @factorize2 +; 3*X - 2*X -> X + %l = mul i32 3, %x + %r = mul i32 2, %x + %z = sub i32 %l, %r + ret i32 %z +; CHECK: ret i32 %x +} + define i32 @expand(i32 %x) { ; CHECK: @expand ; ((X & 1) | 2) & 1 -> ((X & 1) & 1) | (2 & 1) -> (X & 1) | 0 -> X & 1 From daniel at zuster.org Tue Dec 21 09:26:45 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 21 Dec 2010 15:26:45 -0000 Subject: [llvm-commits] [llvm] r122334 - in /llvm/trunk: include/llvm/MC/MCMachObjectWriter.h include/llvm/Object/MachOFormat.h lib/MC/MachObjectWriter.cpp Message-ID: <20101221152645.5F1E82A6C12C@llvm.org> Author: ddunbar Date: Tue Dec 21 09:26:45 2010 New Revision: 122334 URL: http://llvm.org/viewvc/llvm-project?rev=122334&view=rev Log: MC/Mach-O: Shuffle enums a bit to make it harder to inadvertently use the wrong type. Modified: llvm/trunk/include/llvm/MC/MCMachObjectWriter.h llvm/trunk/include/llvm/Object/MachOFormat.h llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/include/llvm/MC/MCMachObjectWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCMachObjectWriter.h?rev=122334&r1=122333&r2=122334&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCMachObjectWriter.h (original) +++ llvm/trunk/include/llvm/MC/MCMachObjectWriter.h Tue Dec 21 09:26:45 2010 @@ -22,12 +22,17 @@ // FIXME: Remove this, we should just always use it once we no longer care // about Darwin 'as' compatibility. const unsigned UseAggressiveSymbolFolding : 1; + unsigned LocalDifference_RIT; protected: MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, uint32_t CPUSubtype_, bool UseAggressiveSymbolFolding_ = false); + void setLocalDifferenceRelocationType(unsigned Type) { + LocalDifference_RIT = Type; + } + public: virtual ~MCMachObjectTargetWriter(); @@ -38,6 +43,9 @@ bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } uint32_t getCPUType() const { return CPUType; } uint32_t getCPUSubtype() const { return CPUSubtype; } + unsigned getLocalDifferenceRelocationType() const { + return LocalDifference_RIT; + } /// @} }; Modified: llvm/trunk/include/llvm/Object/MachOFormat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachOFormat.h?rev=122334&r1=122333&r2=122334&view=diff ============================================================================== --- llvm/trunk/include/llvm/Object/MachOFormat.h (original) +++ llvm/trunk/include/llvm/Object/MachOFormat.h Tue Dec 21 09:26:45 2010 @@ -317,17 +317,24 @@ RF_Scattered = 0x80000000 }; + /// Common relocation info types. enum RelocationInfoType { RIT_Vanilla = 0, RIT_Pair = 1, - RIT_Difference = 2, - RIT_PreboundLazyPointer = 3, - RIT_LocalDifference = 4, - RIT_TLV = 5 + RIT_Difference = 2 + }; + + /// Generic relocation info types, which are shared by some (but not all) + /// platforms. + enum RelocationInfoType_Generic { + RIT_Generic_PreboundLazyPointer = 3, + RIT_Generic_LocalDifference = 4, + RIT_Generic_TLV = 5 }; /// X86_64 uses its own relocation types. enum RelocationInfoTypeX86_64 { + // Note that x86_64 doesn't even share the common relocation types. RIT_X86_64_Unsigned = 0, RIT_X86_64_Signed = 1, RIT_X86_64_Branch = 2, @@ -342,11 +349,8 @@ /// ARM also has its own relocation types. enum RelocationInfoTypeARM { - RIT_ARM_Vanilla = 0, - RIT_ARM_Pair = 1, - RIT_ARM_Difference = 2, RIT_ARM_LocalDifference = 3, - RIT_ARM_PreboundLazyPointer =4, + RIT_ARM_PreboundLazyPointer = 4, RIT_ARM_Branch24Bit = 5, RIT_ARM_ThumbBranch22Bit = 6, RIT_ARM_ThumbBranch32Bit = 7 Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122334&r1=122333&r2=122334&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Tue Dec 21 09:26:45 2010 @@ -766,13 +766,14 @@ // relocation types from the linkers point of view, this is done solely // for pedantic compatibility with 'as'. Type = A_SD->isExternal() ? macho::RIT_Difference : - macho::RIT_LocalDifference; + macho::RIT_Generic_LocalDifference; Value2 = getSymbolAddress(B_SD, Layout); FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); } // Relocations are written out in reverse order, so the PAIR comes first. - if (Type == macho::RIT_Difference || Type == macho::RIT_LocalDifference) { + if (Type == macho::RIT_Difference || + Type == macho::RIT_Generic_LocalDifference) { macho::RelocationEntry MRE; MRE.Word0 = ((0 << 0) | (macho::RIT_Pair << 24) | @@ -830,11 +831,11 @@ // struct relocation_info (8 bytes) macho::RelocationEntry MRE; MRE.Word0 = Value; - MRE.Word1 = ((Index << 0) | - (IsPCRel << 24) | - (Log2Size << 25) | - (1 << 27) | // Extern - (macho::RIT_TLV << 28)); // Type + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (1 << 27) | // Extern + (macho::RIT_Generic_TLV << 28)); // Type Relocations[Fragment->getParent()].push_back(MRE); } From baldrick at free.fr Tue Dec 21 10:12:03 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 16:12:03 -0000 Subject: [llvm-commits] [llvm] r122336 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20101221161203.EE25D2A6C12C@llvm.org> Author: baldrick Date: Tue Dec 21 10:12:03 2010 New Revision: 122336 URL: http://llvm.org/viewvc/llvm-project?rev=122336&view=rev Log: If an instruction simplifies, try again to simplify any uses of it. This is not very important since the pass is only used for testing, but it does make it more realistic. Suggested by Frits van Bommel. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122336&r1=122335&r2=122336&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Tue Dec 21 10:12:03 2010 @@ -23,6 +23,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions removed"); @@ -40,19 +41,46 @@ /// runOnFunction - Remove instructions that simplify. bool runOnFunction(Function &F) { - bool Changed = false; const TargetData *TD = getAnalysisIfAvailable(); const DominatorTree *DT = getAnalysisIfAvailable(); + bool Changed = false; + + // Add all interesting instructions to the worklist. + std::set Worklist; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; - if (Value *V = SimplifyInstruction(I, TD, DT)) { - I->replaceAllUsesWith(V); + // Zap any dead instructions. + if (isInstructionTriviallyDead(I)) { I->eraseFromParent(); Changed = true; - ++NumSimplified; + continue; } + // Add all others to the worklist. + Worklist.insert(I); } + + // Simplify everything in the worklist until the cows come home. + while (!Worklist.empty()) { + Instruction *I = *Worklist.begin(); + Worklist.erase(Worklist.begin()); + Value *V = SimplifyInstruction(I, TD, DT); + if (!V) continue; + + // This instruction simplifies! Replace it with its simplification and + // add all uses to the worklist, since they may now simplify. + I->replaceAllUsesWith(V); + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) + // In unreachable code an instruction can use itself, in which case + // don't add it to the worklist since we are about to erase it. + if (*UI != I) Worklist.insert(cast(*UI)); + if (isInstructionTriviallyDead(I)) + I->eraseFromParent(); + ++NumSimplified; + Changed = true; + } + return Changed; } }; From baldrick at free.fr Tue Dec 21 10:17:04 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 17:17:04 +0100 Subject: [llvm-commits] [llvm] r122265 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: References: <20101220210743.1BDBA2A6C12C@llvm.org> Message-ID: <4D10D300.8050707@free.fr> Hi Frits, > I know this is intended primarily for testing, but maybe this should > iterate until no changes were made just to be thorough? Or use a > worklist so users of replaced values are re-examined later? > Currently this pass depends on basic blocks order; IIRC > SimplifyInstruction assumes the operands have already been simplified, > which currently isn't necessarily the case if blocks don't happen to > be topologically sorted (with respect to domination). I added a worklist as you suggested in commit 122336. Ciao, Duncan. From grosbach at apple.com Tue Dec 21 10:16:00 2010 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 21 Dec 2010 16:16:00 -0000 Subject: [llvm-commits] [llvm] r122337 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp DAGISelMatcher.cpp DAGISelMatcher.h DAGISelMatcherGen.cpp Message-ID: <20101221161600.D06772A6C12C@llvm.org> Author: grosbach Date: Tue Dec 21 10:16:00 2010 New Revision: 122337 URL: http://llvm.org/viewvc/llvm-project?rev=122337&view=rev Log: Tidy up a bit. Trailing whitespace, hard tabs and 80-columns. Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/DAGISelMatcher.cpp llvm/trunk/utils/TableGen/DAGISelMatcher.h llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=122337&r1=122336&r2=122337&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Dec 21 10:16:00 2010 @@ -56,11 +56,11 @@ EEVT::TypeSet::TypeSet(const std::vector &VTList) { assert(!VTList.empty() && "empty list?"); TypeVec.append(VTList.begin(), VTList.end()); - + if (!VTList.empty()) assert(VTList[0] != MVT::iAny && VTList[0] != MVT::vAny && VTList[0] != MVT::fAny); - + // Verify no duplicates. array_pod_sort(TypeVec.begin(), TypeVec.end()); assert(std::unique(TypeVec.begin(), TypeVec.end()) == TypeVec.end()); @@ -72,9 +72,9 @@ bool (*Pred)(MVT::SimpleValueType), const char *PredicateName) { assert(isCompletelyUnknown()); - const std::vector &LegalTypes = + const std::vector &LegalTypes = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes(); - + for (unsigned i = 0, e = LegalTypes.size(); i != e; ++i) if (Pred == 0 || Pred(LegalTypes[i])) TypeVec.push_back(LegalTypes[i]); @@ -82,14 +82,14 @@ // If we have nothing that matches the predicate, bail out. if (TypeVec.empty()) TP.error("Type inference contradiction found, no " + - std::string(PredicateName) + " types found"); + std::string(PredicateName) + " types found"); // No need to sort with one element. if (TypeVec.size() == 1) return true; // Remove duplicates. array_pod_sort(TypeVec.begin(), TypeVec.end()); TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end()); - + return true; } @@ -100,7 +100,7 @@ if (isInteger(TypeVec[i])) return true; return false; -} +} /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or /// a floating point value type. @@ -109,7 +109,7 @@ if (isFloatingPoint(TypeVec[i])) return true; return false; -} +} /// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector /// value type. @@ -123,9 +123,9 @@ std::string EEVT::TypeSet::getName() const { if (TypeVec.empty()) return ""; - + std::string Result; - + for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) { std::string VTName = llvm::getEnumName(TypeVec[i]); // Strip off MVT:: prefix if present. @@ -134,7 +134,7 @@ if (i) Result += ':'; Result += VTName; } - + if (TypeVec.size() == 1) return Result; return "{" + Result + "}"; @@ -146,14 +146,14 @@ bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){ if (InVT.isCompletelyUnknown() || *this == InVT) return false; - + if (isCompletelyUnknown()) { *this = InVT; return true; } - + assert(TypeVec.size() >= 1 && InVT.TypeVec.size() >= 1 && "No unknowns"); - + // Handle the abstract cases, seeing if we can resolve them better. switch (TypeVec[0]) { default: break; @@ -163,26 +163,26 @@ EEVT::TypeSet InCopy(InVT); InCopy.EnforceInteger(TP); InCopy.EnforceScalar(TP); - + if (InCopy.isConcrete()) { // If the RHS has one integer type, upgrade iPTR to i32. TypeVec[0] = InVT.TypeVec[0]; return true; } - + // If the input has multiple scalar integers, this doesn't add any info. if (!InCopy.isCompletelyUnknown()) return false; } break; } - + // If the input constraint is iAny/iPTR and this is an integer type list, // remove non-integer types from the list. if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) && hasIntegerTypes()) { bool MadeChange = EnforceInteger(TP); - + // If we're merging in iPTR/iPTRAny and the node currently has a list of // multiple different integer types, replace them with a single iPTR. if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) && @@ -191,10 +191,10 @@ TypeVec[0] = InVT.TypeVec[0]; MadeChange = true; } - + return MadeChange; } - + // If this is a type list and the RHS is a typelist as well, eliminate entries // from this list that aren't in the other one. bool MadeChange = false; @@ -207,16 +207,16 @@ InInVT = true; break; } - + if (InInVT) continue; TypeVec.erase(TypeVec.begin()+i--); MadeChange = true; } - + // If we removed all of our types, we have a type contradiction. if (!TypeVec.empty()) return MadeChange; - + // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, merging '" + InVT.getName() + "' into '" + InputSet.getName() + "'"); @@ -232,12 +232,12 @@ return false; TypeSet InputSet(*this); - + // Filter out all the fp types. for (unsigned i = 0; i != TypeVec.size(); ++i) if (!isInteger(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - + if (TypeVec.empty()) TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be integer"); @@ -254,12 +254,12 @@ return false; TypeSet InputSet(*this); - + // Filter out all the fp types. for (unsigned i = 0; i != TypeVec.size(); ++i) if (!isFloatingPoint(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - + if (TypeVec.empty()) TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be floating point"); @@ -276,12 +276,12 @@ return false; TypeSet InputSet(*this); - + // Filter out all the vector types. for (unsigned i = 0; i != TypeVec.size(); ++i) if (!isScalar(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - + if (TypeVec.empty()) TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be scalar"); @@ -296,14 +296,14 @@ TypeSet InputSet(*this); bool MadeChange = false; - + // Filter out all the scalar types. for (unsigned i = 0; i != TypeVec.size(); ++i) if (!isVector(TypeVec[i])) { TypeVec.erase(TypeVec.begin()+i--); MadeChange = true; } - + if (TypeVec.empty()) TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be a vector"); @@ -317,13 +317,13 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // Both operands must be integer or FP, but we don't care which. bool MadeChange = false; - + if (isCompletelyUnknown()) MadeChange = FillWithPossibleTypes(TP); if (Other.isCompletelyUnknown()) MadeChange = Other.FillWithPossibleTypes(TP); - + // If one side is known to be integer or known to be FP but the other side has // no information, get at least the type integrality info in there. if (!hasFloatingPointTypes()) @@ -334,62 +334,62 @@ MadeChange |= EnforceInteger(TP); else if (!Other.hasIntegerTypes()) MadeChange |= EnforceFloatingPoint(TP); - + assert(!isCompletelyUnknown() && !Other.isCompletelyUnknown() && "Should have a type list now"); - + // If one contains vectors but the other doesn't pull vectors out. if (!hasVectorTypes()) MadeChange |= Other.EnforceScalar(TP); if (!hasVectorTypes()) MadeChange |= EnforceScalar(TP); - + // This code does not currently handle nodes which have multiple types, // where some types are integer, and some are fp. Assert that this is not // the case. assert(!(hasIntegerTypes() && hasFloatingPointTypes()) && !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); - + // Okay, find the smallest type from the current set and remove it from the // largest set. MVT::SimpleValueType Smallest = TypeVec[0]; for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) if (TypeVec[i] < Smallest) Smallest = TypeVec[i]; - + // If this is the only type in the large set, the constraint can never be // satisfied. if (Other.TypeVec.size() == 1 && Other.TypeVec[0] == Smallest) TP.error("Type inference contradiction found, '" + Other.getName() + "' has nothing larger than '" + getName() +"'!"); - + SmallVector::iterator TVI = std::find(Other.TypeVec.begin(), Other.TypeVec.end(), Smallest); if (TVI != Other.TypeVec.end()) { Other.TypeVec.erase(TVI); MadeChange = true; } - + // Okay, find the largest type in the Other set and remove it from the // current set. MVT::SimpleValueType Largest = Other.TypeVec[0]; for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) if (Other.TypeVec[i] > Largest) Largest = Other.TypeVec[i]; - + // If this is the only type in the small set, the constraint can never be // satisfied. if (TypeVec.size() == 1 && TypeVec[0] == Largest) TP.error("Type inference contradiction found, '" + getName() + "' has nothing smaller than '" + Other.getName()+"'!"); - + TVI = std::find(TypeVec.begin(), TypeVec.end(), Largest); if (TVI != TypeVec.end()) { TypeVec.erase(TVI); MadeChange = true; } - + return MadeChange; } @@ -406,7 +406,7 @@ if (isConcrete()) { EVT IVT = getConcrete(); IVT = IVT.getVectorElementType(); - return MadeChange | + return MadeChange | VTOperand.MergeInTypeInfo(IVT.getSimpleVT().SimpleTy, TP); } @@ -414,11 +414,11 @@ // disagree. if (!VTOperand.isConcrete()) return MadeChange; - + MVT::SimpleValueType VT = VTOperand.getConcrete(); - + TypeSet InputSet(*this); - + // Filter out all the types which don't have the right element type. for (unsigned i = 0; i != TypeVec.size(); ++i) { assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); @@ -427,7 +427,7 @@ MadeChange = true; } } - + if (TypeVec.empty()) // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have a vector element"); @@ -505,7 +505,7 @@ // e.g. (set R32:$dst, 0). if (P->isLeaf() && dynamic_cast(P->getLeafValue())) Size += 2; - + // FIXME: This is a hack to statically increase the priority of patterns // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. // Later we can allow complexity / cost for each pattern to be (optionally) @@ -514,12 +514,12 @@ const ComplexPattern *AM = P->getComplexPatternInfo(CGP); if (AM) Size += AM->getNumOperands() * 3; - + // If this node has some predicate function that must match, it adds to the // complexity of this node. if (!P->getPredicateFns().empty()) ++Size; - + // Count children in the count if they are also nodes. for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { TreePatternNode *Child = P->getChild(i); @@ -527,7 +527,7 @@ Child->getType(0) != MVT::Other) Size += getPatternSize(Child, CGP); else if (Child->isLeaf()) { - if (dynamic_cast(Child->getLeafValue())) + if (dynamic_cast(Child->getLeafValue())) Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2). else if (Child->getComplexPatternInfo(CGP)) Size += getPatternSize(Child, CGP); @@ -535,7 +535,7 @@ ++Size; } } - + return Size; } @@ -576,13 +576,13 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { OperandNo = R->getValueAsInt("OperandNum"); - + if (R->isSubClassOf("SDTCisVT")) { ConstraintType = SDTCisVT; x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT")); if (x.SDTCisVT_Info.VT == MVT::isVoid) throw TGError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT"); - + } else if (R->isSubClassOf("SDTCisPtrTy")) { ConstraintType = SDTCisPtrTy; } else if (R->isSubClassOf("SDTCisInt")) { @@ -596,11 +596,11 @@ x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) { ConstraintType = SDTCisVTSmallerThanOp; - x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = + x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) { ConstraintType = SDTCisOpSmallerThanOp; - x.SDTCisOpSmallerThanOp_Info.BigOperandNum = + x.SDTCisOpSmallerThanOp_Info.BigOperandNum = R->getValueAsInt("BigOperandNum"); } else if (R->isSubClassOf("SDTCisEltOfVec")) { ConstraintType = SDTCisEltOfVec; @@ -621,11 +621,11 @@ ResNo = OpNo; return N; } - + OpNo -= NumResults; - + if (OpNo >= N->getNumChildren()) { - errs() << "Invalid operand number in type constraint " + errs() << "Invalid operand number in type constraint " << (OpNo+NumResults) << " "; N->dump(); errs() << '\n'; @@ -644,7 +644,7 @@ TreePattern &TP) const { unsigned ResNo = 0; // The result number being referenced. TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo); - + switch (ConstraintType) { default: assert(0 && "Unknown constraint type!"); case SDTCisVT: @@ -679,9 +679,9 @@ TP.error(N->getOperator()->getName() + " expects a VT operand!"); MVT::SimpleValueType VT = getValueType(static_cast(NodeToApply->getLeafValue())->getDef()); - + EEVT::TypeSet TypeListTmp(VT, TP); - + unsigned OResNo = 0; TreePatternNode *OtherNode = getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo, @@ -702,13 +702,13 @@ TreePatternNode *VecOperand = getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo, VResNo); - + // Filter vector types out of VecOperand that don't have the right element // type. return VecOperand->getExtType(VResNo). EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), TP); } - } + } return false; } @@ -721,7 +721,7 @@ Record *TypeProfile = R->getValueAsDef("TypeProfile"); NumResults = TypeProfile->getValueAsInt("NumResults"); NumOperands = TypeProfile->getValueAsInt("NumOperands"); - + // Parse the properties. Properties = 0; std::vector PropList = R->getValueAsListOfDefs("Properties"); @@ -754,8 +754,8 @@ exit(1); } } - - + + // Parse the type constraints. std::vector ConstraintList = TypeProfile->getValueAsListOfDefs("Constraints"); @@ -770,12 +770,12 @@ assert(NumResults <= 1 && "We only work with nodes with zero or one result so far!"); assert(ResNo == 0 && "Only handles single result nodes so far"); - + for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i) { // Make sure that this applies to the correct node result. if (TypeConstraints[i].OperandNo >= NumResults) // FIXME: need value # continue; - + switch (TypeConstraints[i].ConstraintType) { default: break; case SDTypeConstraint::SDTCisVT: @@ -802,20 +802,20 @@ if (Operator->getName() == "set" || Operator->getName() == "implicit") return 0; // All return nothing. - + if (Operator->isSubClassOf("Intrinsic")) return CDP.getIntrinsic(Operator).IS.RetVTs.size(); - + if (Operator->isSubClassOf("SDNode")) return CDP.getSDNodeInfo(Operator).getNumResults(); - + if (Operator->isSubClassOf("PatFrag")) { // If we've already parsed this pattern fragment, get it. Otherwise, handle // the forward reference case where one pattern fragment references another // before it is processed. if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator)) return PFRec->getOnlyTree()->getNumTypes(); - + // Get the result tree. DagInit *Tree = Operator->getValueAsDag("Fragment"); Record *Op = 0; @@ -824,22 +824,22 @@ assert(Op && "Invalid Fragment"); return GetNumNodeResults(Op, CDP); } - + if (Operator->isSubClassOf("Instruction")) { CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator); // FIXME: Should allow access to all the results here. unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0; - + // Add on one implicit def if it has a resolvable type. if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other) ++NumDefsToAdd; return NumDefsToAdd; } - + if (Operator->isSubClassOf("SDNodeXForm")) return 1; // FIXME: Generalize SDNodeXForm - + Operator->dump(); errs() << "Unhandled node in GetNumNodeResults\n"; exit(1); @@ -865,7 +865,7 @@ } OS << ")"; } - + for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i) OS << "<>"; if (TransformFn) @@ -903,7 +903,7 @@ } return getLeafValue() == N->getLeafValue(); } - + if (N->getOperator() != getOperator() || N->getNumChildren() != getNumChildren()) return false; for (unsigned i = 0, e = getNumChildren(); i != e; ++i) @@ -947,7 +947,7 @@ void TreePatternNode:: SubstituteFormalArguments(std::map &ArgMap) { if (isLeaf()) return; - + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { TreePatternNode *Child = getChild(i); if (Child->isLeaf()) { @@ -975,7 +975,7 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { if (isLeaf()) return this; // nothing to do. Record *Op = getOperator(); - + if (!Op->isSubClassOf("PatFrag")) { // Just recursively inline children nodes. for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { @@ -994,7 +994,7 @@ // Otherwise, we found a reference to a fragment. First, look up its // TreePattern record. TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op); - + // Verify that we are passing the right number of operands. if (Frag->getNumArgs() != Children.size()) TP.error("'" + Op->getName() + "' fragment requires " + @@ -1012,10 +1012,10 @@ std::map ArgMap; for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP); - + FragTree->SubstituteFormalArguments(ArgMap); } - + FragTree->setName(getName()); for (unsigned i = 0, e = Types.size(); i != e; ++i) FragTree->UpdateNodeType(i, getExtType(i), TP); @@ -1026,7 +1026,7 @@ // Get a new copy of this fragment to stitch into here. //delete this; // FIXME: implement refcounting! - + // The fragment we inlined could have recursive inlining that is needed. See // if there are any pattern fragments in it and inline them as needed. return FragTree->InlinePatternFragments(TP); @@ -1041,21 +1041,21 @@ // Check to see if this is a register or a register class. if (R->isSubClassOf("RegisterClass")) { assert(ResNo == 0 && "Regclass ref only has one result!"); - if (NotRegisters) + if (NotRegisters) return EEVT::TypeSet(); // Unknown. const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); return EEVT::TypeSet(T.getRegisterClass(R).getValueTypes()); } - + if (R->isSubClassOf("PatFrag")) { assert(ResNo == 0 && "FIXME: PatFrag with multiple results?"); // Pattern fragment types will be resolved when they are inlined. return EEVT::TypeSet(); // Unknown. } - + if (R->isSubClassOf("Register")) { assert(ResNo == 0 && "Registers only produce one result!"); - if (NotRegisters) + if (NotRegisters) return EEVT::TypeSet(); // Unknown. const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); return EEVT::TypeSet(T.getRegisterVTs(R)); @@ -1065,16 +1065,16 @@ assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); return EEVT::TypeSet(); } - + if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { assert(ResNo == 0 && "This node only has one result!"); // Using a VTSDNode or CondCodeSDNode. return EEVT::TypeSet(MVT::Other, TP); } - + if (R->isSubClassOf("ComplexPattern")) { assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?"); - if (NotRegisters) + if (NotRegisters) return EEVT::TypeSet(); // Unknown. return EEVT::TypeSet(TP.getDAGPatterns().getComplexPattern(R).getValueType(), TP); @@ -1083,13 +1083,13 @@ assert(ResNo == 0 && "Regclass can only have one result!"); return EEVT::TypeSet(MVT::iPTR, TP); } - + if (R->getName() == "node" || R->getName() == "srcvalue" || R->getName() == "zero_reg") { // Placeholder. return EEVT::TypeSet(); // Unknown. } - + TP.error("Unknown node flavor used in pattern: " + R->getName()); return EEVT::TypeSet(MVT::Other, TP); } @@ -1103,8 +1103,8 @@ getOperator() != CDP.get_intrinsic_w_chain_sdnode() && getOperator() != CDP.get_intrinsic_wo_chain_sdnode()) return 0; - - unsigned IID = + + unsigned IID = dynamic_cast(getChild(0)->getLeafValue())->getValue(); return &CDP.getIntrinsicInfo(IID); } @@ -1114,7 +1114,7 @@ const ComplexPattern * TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const { if (!isLeaf()) return 0; - + DefInit *DI = dynamic_cast(getLeafValue()); if (DI && DI->getDef()->isSubClassOf("ComplexPattern")) return &CGP.getComplexPattern(DI->getDef()); @@ -1129,10 +1129,10 @@ return CP->hasProperty(Property); return false; } - + Record *Operator = getOperator(); if (!Operator->isSubClassOf("SDNode")) return false; - + return CGP.getSDNodeInfo(Operator).hasProperty(Property); } @@ -1149,7 +1149,7 @@ if (getChild(i)->TreeHasProperty(Property, CGP)) return true; return false; -} +} /// isCommutativeIntrinsic - Return true if the node corresponds to a /// commutative intrinsic. @@ -1176,27 +1176,27 @@ NotRegisters, TP), TP); return MadeChange; } - + if (IntInit *II = dynamic_cast(getLeafValue())) { assert(Types.size() == 1 && "Invalid IntInit"); - + // Int inits are always integers. :) bool MadeChange = Types[0].EnforceInteger(TP); - + if (!Types[0].isConcrete()) return MadeChange; - + MVT::SimpleValueType VT = getType(0); if (VT == MVT::iPTR || VT == MVT::iPTRAny) return MadeChange; - + unsigned Size = EVT(VT).getSizeInBits(); // Make sure that the value is representable for this type. if (Size >= 32) return MadeChange; - + int Val = (II->getValue() << (32-Size)) >> (32-Size); if (Val == II->getValue()) return MadeChange; - + // If sign-extended doesn't fit, does it fit as unsigned? unsigned ValueMask; unsigned UnsignedVal; @@ -1205,34 +1205,34 @@ if ((ValueMask & UnsignedVal) == UnsignedVal) return MadeChange; - + TP.error("Integer value '" + itostr(II->getValue())+ "' is out of range for type '" + getEnumName(getType(0)) + "'!"); return MadeChange; } return false; } - + // special handling for set, which isn't really an SDNode. if (getOperator()->getName() == "set") { assert(getNumTypes() == 0 && "Set doesn't produce a value"); assert(getNumChildren() >= 2 && "Missing RHS of a set?"); unsigned NC = getNumChildren(); - + TreePatternNode *SetVal = getChild(NC-1); bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters); for (unsigned i = 0; i < NC-1; ++i) { TreePatternNode *Child = getChild(i); MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); - + // Types of operands must match. MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP); MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP); } return MadeChange; } - + if (getOperator()->getName() == "implicit") { assert(getNumTypes() == 0 && "Node doesn't produce a value"); @@ -1241,15 +1241,15 @@ MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); return MadeChange; } - + if (getOperator()->getName() == "COPY_TO_REGCLASS") { bool MadeChange = false; MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); - + assert(getChild(0)->getNumTypes() == 1 && getChild(1)->getNumTypes() == 1 && "Unhandled case"); - + // child #1 of COPY_TO_REGCLASS should be a register class. We don't care // what type it gets, so if it didn't get a concrete type just give it the // first viable type from the reg class. @@ -1260,14 +1260,14 @@ } return MadeChange; } - + if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; // Apply the result type to the node. unsigned NumRetVTs = Int->IS.RetVTs.size(); unsigned NumParamVTs = Int->IS.ParamVTs.size(); - + for (unsigned i = 0, e = NumRetVTs; i != e; ++i) MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP); @@ -1278,37 +1278,37 @@ // Apply type info to the intrinsic ID. MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP); - + for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) { MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters); - + MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i]; assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case"); MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP); } return MadeChange; } - + if (getOperator()->isSubClassOf("SDNode")) { const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator()); - + // Check that the number of operands is sane. Negative operands -> varargs. if (NI.getNumOperands() >= 0 && getNumChildren() != (unsigned)NI.getNumOperands()) TP.error(getOperator()->getName() + " node requires exactly " + itostr(NI.getNumOperands()) + " operands!"); - + bool MadeChange = NI.ApplyTypeConstraints(this, TP); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); return MadeChange; } - + if (getOperator()->isSubClassOf("Instruction")) { const DAGInstruction &Inst = CDP.getInstruction(getOperator()); CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(getOperator()); - + bool MadeChange = false; // Apply the result types to the node, these come from the things in the @@ -1317,7 +1317,7 @@ unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0; for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) { Record *ResultNode = Inst.getResult(ResNo); - + if (ResultNode->isSubClassOf("PointerLikeRegClass")) { MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP); } else if (ResultNode->getName() == "unknown") { @@ -1325,26 +1325,26 @@ } else { assert(ResultNode->isSubClassOf("RegisterClass") && "Operands should be register classes!"); - const CodeGenRegisterClass &RC = + const CodeGenRegisterClass &RC = CDP.getTargetInfo().getRegisterClass(ResultNode); MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP); } } - + // If the instruction has implicit defs, we apply the first one as a result. // FIXME: This sucks, it should apply all implicit defs. if (!InstInfo.ImplicitDefs.empty()) { unsigned ResNo = NumResultsToAdd; - + // FIXME: Generalize to multiple possible types and multiple possible // ImplicitDefs. MVT::SimpleValueType VT = InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()); - + if (VT != MVT::Other) MadeChange |= UpdateNodeType(ResNo, VT, TP); } - + // If this is an INSERT_SUBREG, constrain the source and destination VTs to // be the same. if (getOperator()->getName() == "INSERT_SUBREG") { @@ -1356,7 +1356,7 @@ unsigned ChildNo = 0; for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { Record *OperandNode = Inst.getOperand(i); - + // If the instruction expects a predicate or optional def operand, we // codegen this by setting the operand to it's default value if it has a // non-empty DefaultOps field. @@ -1364,18 +1364,18 @@ OperandNode->isSubClassOf("OptionalDefOperand")) && !CDP.getDefaultOperand(OperandNode).DefaultOps.empty()) continue; - + // Verify that we didn't run out of provided operands. if (ChildNo >= getNumChildren()) TP.error("Instruction '" + getOperator()->getName() + "' expects more operands than were provided."); - + MVT::SimpleValueType VT; TreePatternNode *Child = getChild(ChildNo++); unsigned ChildResNo = 0; // Instructions always use res #0 of their op. - + if (OperandNode->isSubClassOf("RegisterClass")) { - const CodeGenRegisterClass &RC = + const CodeGenRegisterClass &RC = CDP.getTargetInfo().getRegisterClass(OperandNode); MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP); } else if (OperandNode->isSubClassOf("Operand")) { @@ -1395,12 +1395,12 @@ if (ChildNo != getNumChildren()) TP.error("Instruction '" + getOperator()->getName() + "' was provided too many operands!"); - + return MadeChange; } - + assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); - + // Node transforms always take one operand. if (getNumChildren() != 1) TP.error("Node transform '" + getOperator()->getName() + @@ -1408,7 +1408,7 @@ bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters); - + // If either the output or input of the xform does not have exact // type info. We assume they must be the same. Otherwise, it is perfectly // legal to transform from one type to a completely different type. @@ -1438,7 +1438,7 @@ /// used as a sanity check for .td files (to prevent people from writing stuff /// that can never possibly work), and to prevent the pattern permuter from /// generating stuff that is useless. -bool TreePatternNode::canPatternMatch(std::string &Reason, +bool TreePatternNode::canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP) { if (isLeaf()) return true; @@ -1452,7 +1452,7 @@ // TODO: return true; } - + // If this node is a commutative operator, check that the LHS isn't an // immediate. const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator()); @@ -1469,7 +1469,7 @@ } } } - + return true; } @@ -1509,7 +1509,7 @@ void TreePattern::ComputeNamedNodes(TreePatternNode *N) { if (!N->getName().empty()) NamedNodes[N->getName()].push_back(N); - + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) ComputeNamedNodes(N->getChild(i)); } @@ -1518,7 +1518,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (DefInit *DI = dynamic_cast(TheInit)) { Record *R = DI->getDef(); - + // Direct reference to a leaf DagNode or PatFrag? Turn it into a // TreePatternNode if its own. For example: /// (foo GPR, imm) -> (foo GPR, (imm)) @@ -1526,7 +1526,7 @@ return ParseTreePattern(new DagInit(DI, "", std::vector >()), OpName); - + // Input argument? TreePatternNode *Res = new TreePatternNode(DI, 1); if (R->getName() == "node" && !OpName.empty()) { @@ -1538,13 +1538,13 @@ Res->setName(OpName); return Res; } - + if (IntInit *II = dynamic_cast(TheInit)) { if (!OpName.empty()) error("Constant int argument should not have a name!"); return new TreePatternNode(II, 1); } - + if (BitsInit *BI = dynamic_cast(TheInit)) { // Turn this into an IntInit. Init *II = BI->convertInitializerTo(new IntRecTy()); @@ -1561,34 +1561,34 @@ DefInit *OpDef = dynamic_cast(Dag->getOperator()); if (!OpDef) error("Pattern has unexpected operator type!"); Record *Operator = OpDef->getDef(); - + if (Operator->isSubClassOf("ValueType")) { // If the operator is a ValueType, then this must be "type cast" of a leaf // node. if (Dag->getNumArgs() != 1) error("Type cast only takes one operand!"); - + TreePatternNode *New = ParseTreePattern(Dag->getArg(0), Dag->getArgName(0)); - + // Apply the type cast. assert(New->getNumTypes() == 1 && "FIXME: Unhandled"); New->UpdateNodeType(0, getValueType(Operator), *this); - + if (!OpName.empty()) error("ValueType cast should not have a name!"); return New; } - + // Verify that this is something that makes sense for an operator. - if (!Operator->isSubClassOf("PatFrag") && + if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") && - !Operator->isSubClassOf("Instruction") && + !Operator->isSubClassOf("Instruction") && !Operator->isSubClassOf("SDNodeXForm") && !Operator->isSubClassOf("Intrinsic") && Operator->getName() != "set" && Operator->getName() != "implicit") error("Unrecognized node '" + Operator->getName() + "'!"); - + // Check to see if this is something that is illegal in an input pattern. if (isInputPattern) { if (Operator->isSubClassOf("Instruction") || @@ -1597,7 +1597,7 @@ } else { if (Operator->isSubClassOf("Intrinsic")) error("Cannot use '" + Operator->getName() + "' in an output pattern!"); - + if (Operator->isSubClassOf("SDNode") && Operator->getName() != "imm" && Operator->getName() != "fpimm" && @@ -1612,15 +1612,15 @@ Operator->getName() != "vt") error("Cannot use '" + Operator->getName() + "' in an output pattern!"); } - + std::vector Children; // Parse all the operands. for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgName(i))); - + // If the operator is an intrinsic, then this is just syntactic sugar for for - // (intrinsic_* , ..children..). Pick the right intrinsic node, and + // (intrinsic_* , ..children..). Pick the right intrinsic node, and // convert the intrinsic name to a number. if (Operator->isSubClassOf("Intrinsic")) { const CodeGenIntrinsic &Int = getDAGPatterns().getIntrinsic(Operator); @@ -1635,15 +1635,15 @@ Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode(); else // Otherwise, no chain. Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); - + TreePatternNode *IIDNode = new TreePatternNode(new IntInit(IID), 1); Children.insert(Children.begin(), IIDNode); } - + unsigned NumResults = GetNumNodeResults(Operator, CDP); TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults); Result->setName(OpName); - + if (!Dag->getName().empty()) { assert(Result->getName().empty()); Result->setName(Dag->getName()); @@ -1701,10 +1701,10 @@ } // If there are constraints on our named nodes, apply them. - for (StringMap >::iterator + for (StringMap >::iterator I = NamedNodes.begin(), E = NamedNodes.end(); I != E; ++I) { SmallVectorImpl &Nodes = I->second; - + // If we have input named node types, propagate their types to the named // values here. if (InNamedTypes) { @@ -1727,7 +1727,7 @@ if (DI && DI->getDef()->isSubClassOf("RegisterClass")) continue; } - + assert(Nodes[i]->getNumTypes() == 1 && InNodes[0]->getNumTypes() == 1 && "FIXME: cannot name multiple result nodes yet"); @@ -1735,7 +1735,7 @@ *this); } } - + // If there are multiple nodes with the same name, they must all have the // same type. if (I->second.size() > 1) { @@ -1743,14 +1743,14 @@ TreePatternNode *N1 = Nodes[i], *N2 = Nodes[i+1]; assert(N1->getNumTypes() == 1 && N2->getNumTypes() == 1 && "FIXME: cannot name multiple result nodes yet"); - + MadeChange |= N1->UpdateNodeType(0, N2->getExtType(0), *this); MadeChange |= N2->UpdateNodeType(0, N1->getExtType(0), *this); } } } } - + bool HasUnresolvedTypes = false; for (unsigned i = 0, e = Trees.size(); i != e; ++i) HasUnresolvedTypes |= Trees[i]->ContainsUnresolvedType(); @@ -1766,7 +1766,7 @@ OS << ")"; } OS << ": "; - + if (Trees.size() > 1) OS << "[\n"; for (unsigned i = 0, e = Trees.size(); i != e; ++i) { @@ -1785,7 +1785,7 @@ // CodeGenDAGPatterns implementation // -CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : +CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R), Target(R) { Intrinsics = LoadIntrinsics(Records, false); @@ -1797,7 +1797,7 @@ ParseDefaultOperands(); ParseInstructions(); ParsePatterns(); - + // Generate variants. For example, commutative patterns can match // multiple ways. Add them to PatternsToMatch as well. GenerateVariants(); @@ -1868,20 +1868,20 @@ /// void CodeGenDAGPatterns::ParsePatternFragments() { std::vector Fragments = Records.getAllDerivedDefinitions("PatFrag"); - + // First step, parse all of the fragments. for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { DagInit *Tree = Fragments[i]->getValueAsDag("Fragment"); TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this); PatternFragments[Fragments[i]] = P; - + // Validate the argument list, converting it to set, to discard duplicates. std::vector &Args = P->getArgList(); std::set OperandsSet(Args.begin(), Args.end()); - + if (OperandsSet.count("")) P->error("Cannot have unnamed 'node' values in pattern fragment!"); - + // Parse the operands list. DagInit *OpsList = Fragments[i]->getValueAsDag("Operands"); DefInit *OpsOp = dynamic_cast(OpsList->getOperator()); @@ -1892,8 +1892,8 @@ OpsOp->getDef()->getName() != "outs" && OpsOp->getDef()->getName() != "ins")) P->error("Operands list should start with '(ops ... '!"); - - // Copy over the arguments. + + // Copy over the arguments. Args.clear(); for (unsigned j = 0, e = OpsList->getNumArgs(); j != e; ++j) { if (!dynamic_cast(OpsList->getArg(j)) || @@ -1908,7 +1908,7 @@ OperandsSet.erase(OpsList->getArgName(j)); Args.push_back(OpsList->getArgName(j)); } - + if (!OperandsSet.empty()) P->error("Operands list does not contain an entry for operand '" + *OperandsSet.begin() + "'!"); @@ -1918,20 +1918,20 @@ std::string Code = Fragments[i]->getValueAsCode("Predicate"); if (!Code.empty()) P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName()); - + // If there is a node transformation corresponding to this, keep track of // it. Record *Transform = Fragments[i]->getValueAsDef("OperandTransform"); if (!getSDNodeTransform(Transform).second.empty()) // not noop xform? P->getOnlyTree()->setTransformFn(Transform); } - + // Now that we've parsed all of the tree fragments, do a closure on them so // that there are not references to PatFrags left inside of them. for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { TreePattern *ThePat = PatternFragments[Fragments[i]]; ThePat->InlinePatternFragments(); - + // Infer as many types as possible. Don't worry about it if we don't infer // all of them, some may depend on the inputs of the pattern. try { @@ -1942,7 +1942,7 @@ // actually used by instructions, the type consistency error will be // reported there. } - + // If debugging, print out the pattern fragment result. DEBUG(ThePat->dump()); } @@ -1956,11 +1956,11 @@ // Find some SDNode. assert(!SDNodes.empty() && "No SDNodes parsed?"); Init *SomeSDNode = new DefInit(SDNodes.begin()->first); - + for (unsigned iter = 0; iter != 2; ++iter) { for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) { DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps"); - + // Clone the DefaultInfo dag node, changing the operator from 'ops' to // SomeSDnode so that we can parse this. std::vector > Ops; @@ -1968,20 +1968,20 @@ Ops.push_back(std::make_pair(DefaultInfo->getArg(op), DefaultInfo->getArgName(op))); DagInit *DI = new DagInit(SomeSDNode, "", Ops); - + // Create a TreePattern to parse this. TreePattern P(DefaultOps[iter][i], DI, false, *this); assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!"); // Copy the operands over into a DAGDefaultOperand. DAGDefaultOperand DefaultOpInfo; - + TreePatternNode *T = P.getTree(0); for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) { TreePatternNode *TPN = T->getChild(op); while (TPN->ApplyTypeConstraints(P, false)) /* Resolve all types */; - + if (TPN->ContainsUnresolvedType()) { if (iter == 0) throw "Value #" + utostr(i) + " of PredicateOperand '" + @@ -2038,7 +2038,7 @@ assert(Slot->getNumChildren() == 0 && "can't be a use with children!"); SlotRec = Slot->getOperator(); } - + // Ensure that the inputs agree if we've already seen this input. if (Rec != SlotRec) I->error("All $" + Pat->getName() + " inputs must agree with each other"); @@ -2061,13 +2061,13 @@ I->error("Cannot specify a transform function for a non-input value!"); return; } - + if (Pat->getOperator()->getName() == "implicit") { for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { TreePatternNode *Dest = Pat->getChild(i); if (!Dest->isLeaf()) I->error("implicitly defined value should be a register!"); - + DefInit *Val = dynamic_cast(Dest->getLeafValue()); if (!Val || !Val->getDef()->isSubClassOf("Register")) I->error("implicitly defined value should be a register!"); @@ -2075,7 +2075,7 @@ } return; } - + if (Pat->getOperator()->getName() != "set") { // If this is not a set, verify that the children nodes are not void typed, // and recurse. @@ -2085,30 +2085,30 @@ FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults, InstImpResults); } - + // If this is a non-leaf node with no children, treat it basically as if // it were a leaf. This handles nodes like (imm). bool isUse = HandleUse(I, Pat, InstInputs); - + if (!isUse && Pat->getTransformFn()) I->error("Cannot specify a transform function for a non-input value!"); return; } - + // Otherwise, this is a set, validate and collect instruction results. if (Pat->getNumChildren() == 0) I->error("set requires operands!"); - + if (Pat->getTransformFn()) I->error("Cannot specify a transform function on a set node!"); - + // Check the set destinations. unsigned NumDests = Pat->getNumChildren()-1; for (unsigned i = 0; i != NumDests; ++i) { TreePatternNode *Dest = Pat->getChild(i); if (!Dest->isLeaf()) I->error("set destination should be a register!"); - + DefInit *Val = dynamic_cast(Dest->getLeafValue()); if (!Val) I->error("set destination should be a register!"); @@ -2126,7 +2126,7 @@ I->error("set destination should be a register!"); } } - + // Verify and collect info from the computation. FindPatternInputsAndOutputs(I, Pat->getChild(NumDests), InstInputs, InstResults, InstImpResults); @@ -2259,7 +2259,7 @@ "which already inferred this.\n", Inst.TheDef->getName().c_str()); HasSideEffects = true; } - + if (Inst.Operands.isVariadic) IsVariadic = true; // Can warn if we want. } @@ -2269,20 +2269,20 @@ /// resolved instructions. void CodeGenDAGPatterns::ParseInstructions() { std::vector Instrs = Records.getAllDerivedDefinitions("Instruction"); - + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { ListInit *LI = 0; - + if (dynamic_cast(Instrs[i]->getValueInit("Pattern"))) LI = Instrs[i]->getValueAsListInit("Pattern"); - + // If there is no pattern, only collect minimal information about the // instruction for its operand list. We have to assume that there is one // result, as we have no detailed info. if (!LI || LI->getSize() == 0) { std::vector Results; std::vector Operands; - + CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); if (InstInfo.Operands.size() != 0) { @@ -2293,40 +2293,40 @@ } else { // Assume the first operand is the result. Results.push_back(InstInfo.Operands[0].Rec); - + // The rest are inputs. for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j) Operands.push_back(InstInfo.Operands[j].Rec); } } - + // Create and insert the instruction. std::vector ImpResults; - Instructions.insert(std::make_pair(Instrs[i], + Instructions.insert(std::make_pair(Instrs[i], DAGInstruction(0, Results, Operands, ImpResults))); continue; // no pattern. } - + // Parse the instruction. TreePattern *I = new TreePattern(Instrs[i], LI, true, *this); // Inline pattern fragments into it. I->InlinePatternFragments(); - + // Infer as many types as possible. If we cannot infer all of them, we can // never do anything with this instruction pattern: report it to the user. if (!I->InferAllTypes()) I->error("Could not infer all types in pattern!"); - - // InstInputs - Keep track of all of the inputs of the instruction, along + + // InstInputs - Keep track of all of the inputs of the instruction, along // with the record they are declared as. std::map InstInputs; - + // InstResults - Keep track of all the virtual registers that are 'set' // in the instruction, including what reg class they are. std::map InstResults; std::vector InstImpResults; - + // Verify that the top-level forms in the instruction are of void type, and // fill in the InstResults map. for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) { @@ -2357,25 +2357,25 @@ I->error("'" + InstResults.begin()->first + "' set but does not appear in operand list!"); const std::string &OpName = CGI.Operands[i].Name; - + // Check that it exists in InstResults. TreePatternNode *RNode = InstResults[OpName]; if (RNode == 0) I->error("Operand $" + OpName + " does not exist in operand list!"); - + if (i == 0) Res0Node = RNode; Record *R = dynamic_cast(RNode->getLeafValue())->getDef(); if (R == 0) I->error("Operand $" + OpName + " should be a set destination: all " "outputs must occur before inputs in operand list!"); - + if (CGI.Operands[i].Rec != R) I->error("Operand $" + OpName + " class mismatch!"); - + // Remember the return type. Results.push_back(CGI.Operands[i].Rec); - + // Okay, this one checks out. InstResults.erase(OpName); } @@ -2408,7 +2408,7 @@ } TreePatternNode *InVal = InstInputsCheck[OpName]; InstInputsCheck.erase(OpName); // It occurred, remove from map. - + if (InVal->isLeaf() && dynamic_cast(InVal->getLeafValue())) { Record *InRec = static_cast(InVal->getLeafValue())->getDef(); @@ -2417,13 +2417,13 @@ " between the operand and pattern"); } Operands.push_back(Op.Rec); - + // Construct the result for the dest-pattern operand list. TreePatternNode *OpNode = InVal->clone(); - + // No predicate is useful on the result. OpNode->clearPredicateFns(); - + // Promote the xform function to be an explicit node if set. if (Record *Xform = OpNode->getTransformFn()) { OpNode->setTransformFn(0); @@ -2431,10 +2431,10 @@ Children.push_back(OpNode); OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); } - + ResultNodeOperands.push_back(OpNode); } - + if (!InstInputsCheck.empty()) I->error("Input operand $" + InstInputsCheck.begin()->first + " occurs in pattern but not in operands list!"); @@ -2459,10 +2459,10 @@ DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second; TheInsertedInst.setResultPattern(Temp.getOnlyTree()); - + DEBUG(I->dump()); } - + // If we can, convert the instructions to be patterns that are matched! for (std::map::iterator II = Instructions.begin(), @@ -2481,7 +2481,7 @@ // Not a set (store or something?) SrcPattern = Pattern; } - + Record *Instr = II->first; AddPatternToMatch(I, PatternToMatch(Instr, @@ -2497,7 +2497,7 @@ typedef std::pair NameRecord; -static void FindNames(const TreePatternNode *P, +static void FindNames(const TreePatternNode *P, std::map &Names, const TreePattern *PatternTop) { if (!P->getName().empty()) { @@ -2509,7 +2509,7 @@ PatternTop->error("repetition of value: $" + P->getName() + " where different uses have different types!"); } - + if (!P->isLeaf()) { for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) FindNames(P->getChild(i), Names, PatternTop); @@ -2522,7 +2522,7 @@ std::string Reason; if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) Pattern->error("Pattern can never match: " + Reason); - + // If the source pattern's root is a complex pattern, that complex pattern // must specify the nodes it can potentially match. if (const ComplexPattern *CP = @@ -2530,8 +2530,8 @@ if (CP->getRootNodes().empty()) Pattern->error("ComplexPattern at root must specify list of opcodes it" " could match"); - - + + // Find all of the named values in the input and output, ensure they have the // same type. std::map SrcNames, DstNames; @@ -2546,14 +2546,14 @@ Pattern->error("Pattern has input without matching name in output: $" + I->first); } - + // Scan all of the named values in the source pattern, rejecting them if the // name isn't used in the dest, and isn't used to tie two values together. for (std::map::iterator I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I) if (DstNames[I->first].first == 0 && SrcNames[I->first].second == 1) Pattern->error("Pattern has dead named input: $" + I->first); - + PatternsToMatch.push_back(PTM); } @@ -2582,7 +2582,7 @@ static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) { if (N->isLeaf()) return false; - + // Analyze children. for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) if (ForceArbitraryInstResultType(N->getChild(i), TP)) @@ -2596,12 +2596,12 @@ for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) { if (N->getExtType(i).isCompletelyUnknown() || N->getExtType(i).isConcrete()) continue; - + // Otherwise, force its type to the first possibility (an arbitrary choice). if (N->getExtType(i).MergeInTypeInfo(N->getExtType(i).getTypeList()[0], TP)) return true; } - + return false; } @@ -2615,20 +2615,20 @@ // Inline pattern fragments into it. Pattern->InlinePatternFragments(); - + ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs"); if (LI->getSize() == 0) continue; // no pattern. - + // Parse the instruction. TreePattern *Result = new TreePattern(CurPattern, LI, false, *this); - + // Inline pattern fragments into it. Result->InlinePatternFragments(); if (Result->getNumTrees() != 1) Result->error("Cannot handle instructions producing instructions " "with temporaries yet!"); - + bool IterateInference; bool InferredAllPatternTypes, InferredAllResultTypes; do { @@ -2636,14 +2636,14 @@ // can never do anything with this pattern: report it to the user. InferredAllPatternTypes = Pattern->InferAllTypes(&Pattern->getNamedNodesMap()); - + // Infer as many types as possible. If we cannot infer all of them, we // can never do anything with this pattern: report it to the user. InferredAllResultTypes = Result->InferAllTypes(&Pattern->getNamedNodesMap()); IterateInference = false; - + // Apply the type of the result to the source pattern. This helps us // resolve cases where the input type is known to be a pointer type (which // is considered resolved), but the result knows it needs to be 32- or @@ -2656,7 +2656,7 @@ IterateInference |= Result->getTree(0)-> UpdateNodeType(i, Pattern->getTree(0)->getExtType(i), *Result); } - + // If our iteration has converged and the input pattern's types are fully // resolved but the result pattern is not fully resolved, we may have a // situation where we have two instructions in the result pattern and @@ -2671,7 +2671,7 @@ IterateInference = ForceArbitraryInstResultType(Result->getTree(0), *Result); } while (IterateInference); - + // Verify that we inferred enough types that we can do something with the // pattern and result. If these fire the user has to add type casts. if (!InferredAllPatternTypes) @@ -2680,7 +2680,7 @@ Pattern->dump(); Result->error("Could not infer all types in pattern result!"); } - + // Validate that the input pattern is correct. std::map InstInputs; std::map InstResults; @@ -2708,14 +2708,14 @@ DstPattern = new TreePatternNode(DstPattern->getOperator(), ResultNodeOperands, DstPattern->getNumTypes()); - + for (unsigned i = 0, e = Result->getOnlyTree()->getNumTypes(); i != e; ++i) DstPattern->setType(i, Result->getOnlyTree()->getExtType(i)); - + TreePattern Temp(Result->getRecord(), DstPattern, false, *this); Temp.InferAllTypes(); - + AddPatternToMatch(Pattern, PatternToMatch(CurPattern, CurPattern->getValueAsListInit("Predicates"), @@ -2728,7 +2728,7 @@ /// CombineChildVariants - Given a bunch of permutations of each child of the /// 'operator' node, put them together in all possible ways. -static void CombineChildVariants(TreePatternNode *Orig, +static void CombineChildVariants(TreePatternNode *Orig, const std::vector > &ChildVariants, std::vector &OutVariants, CodeGenDAGPatterns &CDP, @@ -2737,7 +2737,7 @@ for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i) if (ChildVariants[i].empty()) return; - + // The end result is an all-pairs construction of the resultant pattern. std::vector Idxs; Idxs.resize(ChildVariants.size()); @@ -2758,21 +2758,21 @@ NewChildren.push_back(ChildVariants[i][Idxs[i]]); TreePatternNode *R = new TreePatternNode(Orig->getOperator(), NewChildren, Orig->getNumTypes()); - + // Copy over properties. R->setName(Orig->getName()); R->setPredicateFns(Orig->getPredicateFns()); R->setTransformFn(Orig->getTransformFn()); for (unsigned i = 0, e = Orig->getNumTypes(); i != e; ++i) R->setType(i, Orig->getExtType(i)); - + // If this pattern cannot match, do not include it as a variant. std::string ErrString; if (!R->canPatternMatch(ErrString, CDP)) { delete R; } else { bool AlreadyExists = false; - + // Scan to see if this pattern has already been emitted. We can get // duplication due to things like commuting: // (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a) @@ -2782,13 +2782,13 @@ AlreadyExists = true; break; } - + if (AlreadyExists) delete R; else OutVariants.push_back(R); } - + // Increment indices to the next permutation by incrementing the // indicies from last index backward, e.g., generate the sequence // [0, 0], [0, 1], [1, 0], [1, 1]. @@ -2805,7 +2805,7 @@ /// CombineChildVariants - A helper function for binary operators. /// -static void CombineChildVariants(TreePatternNode *Orig, +static void CombineChildVariants(TreePatternNode *Orig, const std::vector &LHS, const std::vector &RHS, std::vector &OutVariants, @@ -2815,14 +2815,14 @@ ChildVariants.push_back(LHS); ChildVariants.push_back(RHS); CombineChildVariants(Orig, ChildVariants, OutVariants, CDP, DepVars); -} +} static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N, std::vector &Children) { assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!"); Record *Operator = N->getOperator(); - + // Only permit raw nodes. if (!N->getName().empty() || !N->getPredicateFns().empty() || N->getTransformFn()) { @@ -2859,7 +2859,7 @@ // If this node is associative, re-associate. if (NodeInfo.hasProperty(SDNPAssociative)) { - // Re-associate by pulling together all of the linked operators + // Re-associate by pulling together all of the linked operators std::vector MaximalChildren; GatherChildrenOfAssociativeOpcode(N, MaximalChildren); @@ -2871,11 +2871,11 @@ GenerateVariantsOf(MaximalChildren[0], AVariants, CDP, DepVars); GenerateVariantsOf(MaximalChildren[1], BVariants, CDP, DepVars); GenerateVariantsOf(MaximalChildren[2], CVariants, CDP, DepVars); - + // There are only two ways we can permute the tree: // (A op B) op C and A op (B op C) // Within these forms, we can also permute A/B/C. - + // Generate legal pair permutations of A/B/C. std::vector ABVariants; std::vector BAVariants; @@ -2908,7 +2908,7 @@ return; } } - + // Compute permutations of all children. std::vector > ChildVariants; ChildVariants.resize(N->getNumChildren()); @@ -2960,7 +2960,7 @@ // match multiple ways. Add them to PatternsToMatch as well. void CodeGenDAGPatterns::GenerateVariants() { DEBUG(errs() << "Generating instruction variants.\n"); - + // Loop over all of the patterns we've collected, checking to see if we can // generate variants of the instruction, through the exploitation of // identities. This permits the target to provide aggressive matching without @@ -2996,7 +2996,7 @@ DEBUG(errs() << " VAR#" << v << ": "; Variant->dump(); errs() << "\n"); - + // Scan to see if an instruction or explicit pattern already matches this. bool AlreadyExists = false; for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.cpp?rev=122337&r1=122336&r2=122337&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.cpp Tue Dec 21 10:16:00 2010 @@ -35,7 +35,7 @@ Matcher *Matcher::unlinkNode(Matcher *Other) { if (this == Other) return takeNext(); - + // Scan until we find the predecessor of Other. Matcher *Cur = this; for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext()) @@ -67,11 +67,11 @@ // We can move simple predicates before record nodes. if (isSimplePredicateNode()) return Other->isSimplePredicateOrRecordNode(); - + // We can move record nodes across simple predicates. if (isSimplePredicateOrRecordNode()) return isSimplePredicateNode(); - + // We can't move record nodes across each other etc. return false; } @@ -296,7 +296,7 @@ bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const { // Note: pointer equality isn't enough here, we have to check the enum names - // to ensure that the nodes are for the same opcode. + // to ensure that the nodes are for the same opcode. return cast(M)->Opcode.getEnumName() == Opcode.getEnumName(); } @@ -321,7 +321,7 @@ } unsigned CompleteMatchMatcher::getHashImpl() const { - return HashUnsigneds(Results.begin(), Results.end()) ^ + return HashUnsigneds(Results.begin(), Results.end()) ^ ((unsigned)(intptr_t)&Pattern << 8); } @@ -332,15 +332,15 @@ // If the two types are the same, then they are the same, so they don't // contradict. if (T1 == T2) return false; - + // If either type is about iPtr, then they don't conflict unless the other // one is not a scalar integer type. if (T1 == MVT::iPTR) return !MVT(T2).isInteger() || MVT(T2).isVector(); - + if (T2 == MVT::iPTR) return !MVT(T1).isInteger() || MVT(T1).isVector(); - + // Otherwise, they are two different non-iPTR types, they conflict. return true; } @@ -349,10 +349,10 @@ if (const CheckOpcodeMatcher *COM = dyn_cast(M)) { // One node can't have two different opcodes! // Note: pointer equality isn't enough here, we have to check the enum names - // to ensure that the nodes are for the same opcode. + // to ensure that the nodes are for the same opcode. return COM->getOpcode().getEnumName() != getOpcode().getEnumName(); } - + // If the node has a known type, and if the type we're checking for is // different, then we know they contradict. For example, a check for // ISD::STORE will never be true at the same time a check for Type i32 is. @@ -360,12 +360,12 @@ // If checking for a result the opcode doesn't have, it can't match. if (CT->getResNo() >= getOpcode().getNumResults()) return true; - + MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo()); if (NodeType != MVT::Other) return TypesAreContradictory(NodeType, CT->getType()); } - + return false; } @@ -381,12 +381,12 @@ // conflict! if (CC->getChildNo() != getChildNo()) return false; - + return TypesAreContradictory(getType(), CC->getType()); } return false; } - + bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const { if (const CheckIntegerMatcher *CIM = dyn_cast(M)) return CIM->getValue() != getValue(); Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.h?rev=122337&r1=122336&r2=122337&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcher.h (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcher.h Tue Dec 21 10:16:00 2010 @@ -31,7 +31,7 @@ void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP, raw_ostream &OS); - + /// Matcher - Base class for all the the DAG ISel Matcher representation /// nodes. class Matcher { @@ -48,7 +48,7 @@ CaptureFlagInput, // If the current node has an input flag, save it. MoveChild, // Move current node to specified child. MoveParent, // Move current node to parent. - + // Predicate checking. CheckSame, // Fail if not same as prev match. CheckPatternPredicate, @@ -65,7 +65,7 @@ CheckAndImm, CheckOrImm, CheckFoldableChainNode, - + // Node creation/emisssion. EmitInteger, // Create a TargetConstant EmitStringInteger, // Create a TargetConstant from a string. @@ -85,7 +85,7 @@ Matcher(KindTy K) : Kind(K) {} public: virtual ~Matcher() {} - + KindTy getKind() const { return Kind; } Matcher *getNext() { return Next.get(); } @@ -94,25 +94,25 @@ Matcher *takeNext() { return Next.take(); } OwningPtr &getNextPtr() { return Next; } - + static inline bool classof(const Matcher *) { return true; } - + bool isEqual(const Matcher *M) const { if (getKind() != M->getKind()) return false; return isEqualImpl(M); } - + unsigned getHash() const { // Clear the high bit so we don't conflict with tombstones etc. return ((getHashImpl() << 4) ^ getKind()) & (~0U>>1); } - + /// isSafeToReorderWithPatternPredicate - Return true if it is safe to sink a /// PatternPredicate node past this one. virtual bool isSafeToReorderWithPatternPredicate() const { return false; } - + /// isSimplePredicateNode - Return true if this is a simple predicate that /// operates on the node or its children without potential side effects or a /// change of the current node. @@ -134,28 +134,28 @@ return true; } } - + /// isSimplePredicateOrRecordNode - Return true if this is a record node or /// a simple predicate. bool isSimplePredicateOrRecordNode() const { return isSimplePredicateNode() || getKind() == RecordNode || getKind() == RecordChild; } - + /// unlinkNode - Unlink the specified node from this chain. If Other == this, /// we unlink the next pointer and return it. Otherwise we unlink Other from /// the list and return this. Matcher *unlinkNode(Matcher *Other); - + /// canMoveBefore - Return true if this matcher is the same as Other, or if /// we can move this matcher past all of the nodes in-between Other and this /// node. Other must be equal to or before this. bool canMoveBefore(const Matcher *Other) const; - + /// canMoveBefore - Return true if it is safe to move the current matcher /// across the specified one. bool canMoveBeforeNode(const Matcher *Other) const; - + /// isContradictory - Return true of these two matchers could never match on /// the same node. bool isContradictory(const Matcher *Other) const { @@ -167,7 +167,7 @@ return isContradictoryImpl(Other); return Other->isContradictoryImpl(this); } - + void print(raw_ostream &OS, unsigned indent = 0) const; void printOne(raw_ostream &OS) const; void dump() const; @@ -177,7 +177,7 @@ virtual unsigned getHashImpl() const = 0; virtual bool isContradictoryImpl(const Matcher *M) const { return false; } }; - + /// ScopeMatcher - This attempts to match each of its children to find the first /// one that successfully matches. If one child fails, it tries the next child. /// If none of the children match then this check fails. It never has a 'next'. @@ -188,12 +188,12 @@ : Matcher(Scope), Children(children, children+numchildren) { } virtual ~ScopeMatcher(); - + unsigned getNumChildren() const { return Children.size(); } - + Matcher *getChild(unsigned i) { return Children[i]; } const Matcher *getChild(unsigned i) const { return Children[i]; } - + void resetChild(unsigned i, Matcher *N) { delete Children[i]; Children[i] = N; @@ -204,7 +204,7 @@ Children[i] = 0; return Res; } - + void setNumChildren(unsigned NC) { if (NC < Children.size()) { // delete any children we're about to lose pointers to. @@ -217,7 +217,7 @@ static inline bool classof(const Matcher *N) { return N->getKind() == Scope; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return false; } @@ -229,38 +229,38 @@ /// WhatFor - This is a string indicating why we're recording this. This /// should only be used for comment generation not anything semantic. std::string WhatFor; - + /// ResultNo - The slot number in the RecordedNodes vector that this will be, /// just printed as a comment. unsigned ResultNo; public: RecordMatcher(const std::string &whatfor, unsigned resultNo) : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {} - + const std::string &getWhatFor() const { return WhatFor; } unsigned getResultNo() const { return ResultNo; } - + static inline bool classof(const Matcher *N) { return N->getKind() == RecordNode; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return true; } virtual unsigned getHashImpl() const { return 0; } }; - + /// RecordChildMatcher - Save a numbered child of the current node, or fail /// the match if it doesn't exist. This is logically equivalent to: /// MoveChild N + RecordNode + MoveParent. class RecordChildMatcher : public Matcher { unsigned ChildNo; - + /// WhatFor - This is a string indicating why we're recording this. This /// should only be used for comment generation not anything semantic. std::string WhatFor; - + /// ResultNo - The slot number in the RecordedNodes vector that this will be, /// just printed as a comment. unsigned ResultNo; @@ -269,7 +269,7 @@ unsigned resultNo) : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor), ResultNo(resultNo) {} - + unsigned getChildNo() const { return ChildNo; } const std::string &getWhatFor() const { return WhatFor; } unsigned getResultNo() const { return ResultNo; } @@ -277,7 +277,7 @@ static inline bool classof(const Matcher *N) { return N->getKind() == RecordChild; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -287,16 +287,16 @@ } virtual unsigned getHashImpl() const { return getChildNo(); } }; - + /// RecordMemRefMatcher - Save the current node's memref. class RecordMemRefMatcher : public Matcher { public: RecordMemRefMatcher() : Matcher(RecordMemRef) {} - + static inline bool classof(const Matcher *N) { return N->getKind() == RecordMemRef; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -305,17 +305,17 @@ virtual unsigned getHashImpl() const { return 0; } }; - + /// CaptureFlagInputMatcher - If the current record has a flag input, record /// it so that it is used as an input to the generated code. class CaptureFlagInputMatcher : public Matcher { public: CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {} - + static inline bool classof(const Matcher *N) { return N->getKind() == CaptureFlagInput; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -323,20 +323,20 @@ virtual bool isEqualImpl(const Matcher *M) const { return true; } virtual unsigned getHashImpl() const { return 0; } }; - + /// MoveChildMatcher - This tells the interpreter to move into the /// specified child node. class MoveChildMatcher : public Matcher { unsigned ChildNo; public: MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {} - + unsigned getChildNo() const { return ChildNo; } - + static inline bool classof(const Matcher *N) { return N->getKind() == MoveChild; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -346,17 +346,17 @@ } virtual unsigned getHashImpl() const { return getChildNo(); } }; - + /// MoveParentMatcher - This tells the interpreter to move to the parent /// of the current node. class MoveParentMatcher : public Matcher { public: MoveParentMatcher() : Matcher(MoveParent) {} - + static inline bool classof(const Matcher *N) { return N->getKind() == MoveParent; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -373,13 +373,13 @@ public: CheckSameMatcher(unsigned matchnumber) : Matcher(CheckSame), MatchNumber(matchnumber) {} - + unsigned getMatchNumber() const { return MatchNumber; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckSame; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -389,7 +389,7 @@ } virtual unsigned getHashImpl() const { return getMatchNumber(); } }; - + /// CheckPatternPredicateMatcher - This checks the target-specific predicate /// to see if the entire pattern is capable of matching. This predicate does /// not take a node as input. This is used for subtarget feature checks etc. @@ -398,13 +398,13 @@ public: CheckPatternPredicateMatcher(StringRef predicate) : Matcher(CheckPatternPredicate), Predicate(predicate) {} - + StringRef getPredicate() const { return Predicate; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckPatternPredicate; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -414,7 +414,7 @@ } virtual unsigned getHashImpl() const; }; - + /// CheckPredicateMatcher - This checks the target-specific predicate to /// see if the node is acceptable. class CheckPredicateMatcher : public Matcher { @@ -422,13 +422,13 @@ public: CheckPredicateMatcher(StringRef predname) : Matcher(CheckPredicate), PredName(predname) {} - + StringRef getPredicateName() const { return PredName; } static inline bool classof(const Matcher *N) { return N->getKind() == CheckPredicate; } - + // TODO: Ok? //virtual bool isSafeToReorderWithPatternPredicate() const { return true; } @@ -439,8 +439,8 @@ } virtual unsigned getHashImpl() const; }; - - + + /// CheckOpcodeMatcher - This checks to see if the current node has the /// specified opcode, if not it fails to match. class CheckOpcodeMatcher : public Matcher { @@ -448,13 +448,13 @@ public: CheckOpcodeMatcher(const SDNodeInfo &opcode) : Matcher(CheckOpcode), Opcode(opcode) {} - + const SDNodeInfo &getOpcode() const { return Opcode; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckOpcode; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -478,19 +478,19 @@ static inline bool classof(const Matcher *N) { return N->getKind() == SwitchOpcode; } - + unsigned getNumCases() const { return Cases.size(); } - + const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; } Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; } const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return false; } virtual unsigned getHashImpl() const { return 4123; } }; - + /// CheckTypeMatcher - This checks to see if the current node has the /// specified type at the specified result, if not it fails to match. class CheckTypeMatcher : public Matcher { @@ -499,14 +499,14 @@ public: CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno) : Matcher(CheckType), Type(type), ResNo(resno) {} - + MVT::SimpleValueType getType() const { return Type; } unsigned getResNo() const { return ResNo; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckType; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -517,7 +517,7 @@ virtual unsigned getHashImpl() const { return Type; } virtual bool isContradictoryImpl(const Matcher *M) const; }; - + /// SwitchTypeMatcher - Switch based on the current node's type, dispatching /// to one matcher per case. If the type doesn't match any of the cases, /// then the match fails. This is semantically equivalent to a Scope node where @@ -528,24 +528,24 @@ SwitchTypeMatcher(const std::pair *cases, unsigned numcases) : Matcher(SwitchType), Cases(cases, cases+numcases) {} - + static inline bool classof(const Matcher *N) { return N->getKind() == SwitchType; } - + unsigned getNumCases() const { return Cases.size(); } - + MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; } Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; } const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return false; } virtual unsigned getHashImpl() const { return 4123; } }; - - + + /// CheckChildTypeMatcher - This checks to see if a child node has the /// specified type, if not it fails to match. class CheckChildTypeMatcher : public Matcher { @@ -554,14 +554,14 @@ public: CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type) : Matcher(CheckChildType), ChildNo(childno), Type(type) {} - + unsigned getChildNo() const { return ChildNo; } MVT::SimpleValueType getType() const { return Type; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckChildType; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -573,7 +573,7 @@ virtual unsigned getHashImpl() const { return (Type << 3) | ChildNo; } virtual bool isContradictoryImpl(const Matcher *M) const; }; - + /// CheckIntegerMatcher - This checks to see if the current node is a /// ConstantSDNode with the specified integer value, if not it fails to match. @@ -582,13 +582,13 @@ public: CheckIntegerMatcher(int64_t value) : Matcher(CheckInteger), Value(value) {} - + int64_t getValue() const { return Value; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckInteger; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -599,7 +599,7 @@ virtual unsigned getHashImpl() const { return Value; } virtual bool isContradictoryImpl(const Matcher *M) const; }; - + /// CheckCondCodeMatcher - This checks to see if the current node is a /// CondCodeSDNode with the specified condition, if not it fails to match. class CheckCondCodeMatcher : public Matcher { @@ -607,13 +607,13 @@ public: CheckCondCodeMatcher(StringRef condcodename) : Matcher(CheckCondCode), CondCodeName(condcodename) {} - + StringRef getCondCodeName() const { return CondCodeName; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckCondCode; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -623,7 +623,7 @@ } virtual unsigned getHashImpl() const; }; - + /// CheckValueTypeMatcher - This checks to see if the current node is a /// VTSDNode with the specified type, if not it fails to match. class CheckValueTypeMatcher : public Matcher { @@ -631,13 +631,13 @@ public: CheckValueTypeMatcher(StringRef type_name) : Matcher(CheckValueType), TypeName(type_name) {} - + StringRef getTypeName() const { return TypeName; } static inline bool classof(const Matcher *N) { return N->getKind() == CheckValueType; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -648,21 +648,21 @@ virtual unsigned getHashImpl() const; bool isContradictoryImpl(const Matcher *M) const; }; - - - + + + /// CheckComplexPatMatcher - This node runs the specified ComplexPattern on /// the current node. class CheckComplexPatMatcher : public Matcher { const ComplexPattern &Pattern; - - /// MatchNumber - This is the recorded nodes slot that contains the node we want to - /// match against. + + /// MatchNumber - This is the recorded nodes slot that contains the node we + /// want to match against. unsigned MatchNumber; - + /// Name - The name of the node we're matching, for comment emission. std::string Name; - + /// FirstResult - This is the first slot in the RecordedNodes list that the /// result of the match populates. unsigned FirstResult; @@ -671,17 +671,17 @@ const std::string &name, unsigned firstresult) : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber), Name(name), FirstResult(firstresult) {} - + const ComplexPattern &getPattern() const { return Pattern; } unsigned getMatchNumber() const { return MatchNumber; } - + const std::string getName() const { return Name; } unsigned getFirstResult() const { return FirstResult; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckComplexPat; } - + // Not safe to move a pattern predicate past a complex pattern. virtual bool isSafeToReorderWithPatternPredicate() const { return false; } @@ -695,7 +695,7 @@ return (unsigned)(intptr_t)&Pattern ^ MatchNumber; } }; - + /// CheckAndImmMatcher - This checks to see if the current node is an 'and' /// with something equivalent to the specified immediate. class CheckAndImmMatcher : public Matcher { @@ -703,13 +703,13 @@ public: CheckAndImmMatcher(int64_t value) : Matcher(CheckAndImm), Value(value) {} - + int64_t getValue() const { return Value; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckAndImm; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -727,13 +727,13 @@ public: CheckOrImmMatcher(int64_t value) : Matcher(CheckOrImm), Value(value) {} - + int64_t getValue() const { return Value; } static inline bool classof(const Matcher *N) { return N->getKind() == CheckOrImm; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -750,11 +750,11 @@ public: CheckFoldableChainNodeMatcher() : Matcher(CheckFoldableChainNode) {} - + static inline bool classof(const Matcher *N) { return N->getKind() == CheckFoldableChainNode; } - + virtual bool isSafeToReorderWithPatternPredicate() const { return true; } private: @@ -770,14 +770,14 @@ public: EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt) : Matcher(EmitInteger), Val(val), VT(vt) {} - + int64_t getValue() const { return Val; } MVT::SimpleValueType getVT() const { return VT; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitInteger; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -795,14 +795,14 @@ public: EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt) : Matcher(EmitStringInteger), Val(val), VT(vt) {} - + const std::string &getValue() const { return Val; } MVT::SimpleValueType getVT() const { return VT; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitStringInteger; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -811,7 +811,7 @@ } virtual unsigned getHashImpl() const; }; - + /// EmitRegisterMatcher - This creates a new TargetConstant. class EmitRegisterMatcher : public Matcher { /// Reg - The def for the register that we're emitting. If this is null, then @@ -821,14 +821,14 @@ public: EmitRegisterMatcher(Record *reg, MVT::SimpleValueType vt) : Matcher(EmitRegister), Reg(reg), VT(vt) {} - + Record *getReg() const { return Reg; } MVT::SimpleValueType getVT() const { return VT; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitRegister; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -848,13 +848,13 @@ public: EmitConvertToTargetMatcher(unsigned slot) : Matcher(EmitConvertToTarget), Slot(slot) {} - + unsigned getSlot() const { return Slot; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitConvertToTarget; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -862,7 +862,7 @@ } virtual unsigned getHashImpl() const { return Slot; } }; - + /// EmitMergeInputChainsMatcher - Emit a node that merges a list of input /// chains together with a token factor. The list of nodes are the nodes in the /// matched pattern that have chain input/outputs. This node adds all input @@ -872,18 +872,18 @@ public: EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes) : Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {} - + unsigned getNumNodes() const { return ChainNodes.size(); } - + unsigned getNode(unsigned i) const { assert(i < ChainNodes.size()); return ChainNodes[i]; - } - + } + static inline bool classof(const Matcher *N) { return N->getKind() == EmitMergeInputChains; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -891,7 +891,7 @@ } virtual unsigned getHashImpl() const; }; - + /// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg, /// pushing the chain and flag results. /// @@ -901,27 +901,27 @@ public: EmitCopyToRegMatcher(unsigned srcSlot, Record *destPhysReg) : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {} - + unsigned getSrcSlot() const { return SrcSlot; } Record *getDestPhysReg() const { return DestPhysReg; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitCopyToReg; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return cast(M)->SrcSlot == SrcSlot && - cast(M)->DestPhysReg == DestPhysReg; + cast(M)->DestPhysReg == DestPhysReg; } virtual unsigned getHashImpl() const { return SrcSlot ^ ((unsigned)(intptr_t)DestPhysReg << 4); } }; - - - + + + /// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a /// recorded node and records the result. class EmitNodeXFormMatcher : public Matcher { @@ -930,25 +930,25 @@ public: EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm) : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {} - + unsigned getSlot() const { return Slot; } Record *getNodeXForm() const { return NodeXForm; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitNodeXForm; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { return cast(M)->Slot == Slot && - cast(M)->NodeXForm == NodeXForm; + cast(M)->NodeXForm == NodeXForm; } virtual unsigned getHashImpl() const { return Slot ^ ((unsigned)(intptr_t)NodeXForm << 4); } }; - + /// EmitNodeMatcherCommon - Common class shared between EmitNode and /// MorphNodeTo. class EmitNodeMatcherCommon : public Matcher { @@ -956,7 +956,7 @@ const SmallVector VTs; const SmallVector Operands; bool HasChain, HasInFlag, HasOutFlag, HasMemRefs; - + /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1. /// If this is a varidic node, this is set to the number of fixed arity /// operands in the root of the pattern. The rest are appended to this node. @@ -972,9 +972,9 @@ VTs(vts, vts+numvts), Operands(operands, operands+numops), HasChain(hasChain), HasInFlag(hasInFlag), HasOutFlag(hasOutFlag), HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {} - + const std::string &getOpcodeName() const { return OpcodeName; } - + unsigned getNumVTs() const { return VTs.size(); } MVT::SimpleValueType getVT(unsigned i) const { assert(i < VTs.size()); @@ -986,27 +986,27 @@ assert(i < Operands.size()); return Operands[i]; } - + const SmallVectorImpl &getVTList() const { return VTs; } const SmallVectorImpl &getOperandList() const { return Operands; } - + bool hasChain() const { return HasChain; } bool hasInFlag() const { return HasInFlag; } bool hasOutFlag() const { return HasOutFlag; } bool hasMemRefs() const { return HasMemRefs; } int getNumFixedArityOperands() const { return NumFixedArityOperands; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitNode || N->getKind() == MorphNodeTo; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const; virtual unsigned getHashImpl() const; }; - + /// EmitNodeMatcher - This signals a successful match and generates a node. class EmitNodeMatcher : public EmitNodeMatcherCommon { unsigned FirstResultSlot; @@ -1021,15 +1021,15 @@ hasInFlag, hasOutFlag, hasmemrefs, numfixedarityoperands, false), FirstResultSlot(firstresultslot) {} - + unsigned getFirstResultSlot() const { return FirstResultSlot; } - + static inline bool classof(const Matcher *N) { return N->getKind() == EmitNode; } - + }; - + class MorphNodeToMatcher : public EmitNodeMatcherCommon { const PatternToMatch &Pattern; public: @@ -1044,14 +1044,14 @@ numfixedarityoperands, true), Pattern(pattern) { } - + const PatternToMatch &getPattern() const { return Pattern; } static inline bool classof(const Matcher *N) { return N->getKind() == MorphNodeTo; } }; - + /// MarkFlagResultsMatcher - This node indicates which non-root nodes in the /// pattern produce flags. This allows CompleteMatchMatcher to update them /// with the output flag of the resultant code. @@ -1060,18 +1060,18 @@ public: MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes) : Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {} - + unsigned getNumNodes() const { return FlagResultNodes.size(); } - + unsigned getNode(unsigned i) const { assert(i < FlagResultNodes.size()); return FlagResultNodes[i]; - } - + } + static inline bool classof(const Matcher *N) { return N->getKind() == MarkFlagResults; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -1095,11 +1095,11 @@ unsigned getNumResults() const { return Results.size(); } unsigned getResult(unsigned R) const { return Results[R]; } const PatternToMatch &getPattern() const { return Pattern; } - + static inline bool classof(const Matcher *N) { return N->getKind() == CompleteMatch; } - + private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { @@ -1108,7 +1108,7 @@ } virtual unsigned getHashImpl() const; }; - + } // end namespace llvm #endif Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=122337&r1=122336&r2=122337&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Tue Dec 21 10:16:00 2010 @@ -25,12 +25,12 @@ MVT::SimpleValueType VT = MVT::Other; const std::vector &RCs = T.getRegisterClasses(); std::vector::const_iterator Element; - + for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RCs[rc]; if (!std::count(RC.Elements.begin(), RC.Elements.end(), R)) continue; - + if (!FoundRC) { FoundRC = true; VT = RC.getValueTypeNum(0); @@ -48,22 +48,22 @@ class MatcherGen { const PatternToMatch &Pattern; const CodeGenDAGPatterns &CGP; - + /// PatWithNoTypes - This is a clone of Pattern.getSrcPattern() that starts /// out with all of the types removed. This allows us to insert type checks /// as we scan the tree. TreePatternNode *PatWithNoTypes; - + /// VariableMap - A map from variable names ('$dst') to the recorded operand /// number that they were captured as. These are biased by 1 to make /// insertion easier. StringMap VariableMap; - + /// NextRecordedOperandNo - As we emit opcodes to record matched values in /// the RecordedNodes array, this keeps track of which slot will be next to /// record into. unsigned NextRecordedOperandNo; - + /// MatchedChainNodes - This maintains the position in the recorded nodes /// array of all of the recorded input nodes that have chains. SmallVector MatchedChainNodes; @@ -71,7 +71,7 @@ /// MatchedFlagResultNodes - This maintains the position in the recorded /// nodes array of all of the recorded input nodes that have flag results. SmallVector MatchedFlagResultNodes; - + /// MatchedComplexPatterns - This maintains a list of all of the /// ComplexPatterns that we need to check. The patterns are known to have /// names which were recorded. The second element of each pair is the first @@ -79,39 +79,39 @@ /// results into. SmallVector, 2> MatchedComplexPatterns; - + /// PhysRegInputs - List list has an entry for each explicitly specified /// physreg input to the pattern. The first elt is the Register node, the /// second is the recorded slot number the input pattern match saved it in. SmallVector, 2> PhysRegInputs; - + /// Matcher - This is the top level of the generated matcher, the result. Matcher *TheMatcher; - + /// CurPredicate - As we emit matcher nodes, this points to the latest check /// which should have future checks stuck into its Next position. Matcher *CurPredicate; public: MatcherGen(const PatternToMatch &pattern, const CodeGenDAGPatterns &cgp); - + ~MatcherGen() { delete PatWithNoTypes; } - + bool EmitMatcherCode(unsigned Variant); void EmitResultCode(); - + Matcher *GetMatcher() const { return TheMatcher; } private: void AddMatcher(Matcher *NewNode); void InferPossibleTypes(); - + // Matcher Generation. void EmitMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes); void EmitLeafMatchCode(const TreePatternNode *N); void EmitOperatorMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes); - + // Result Code Generation. unsigned getNamedArgumentSlot(StringRef Name) { unsigned VarMapEntry = VariableMap[Name]; @@ -123,7 +123,7 @@ /// GetInstPatternNode - Get the pattern for an instruction. const TreePatternNode *GetInstPatternNode(const DAGInstruction &Ins, const TreePatternNode *N); - + void EmitResultOperand(const TreePatternNode *N, SmallVectorImpl &ResultOps); void EmitResultOfNamedOperand(const TreePatternNode *N, @@ -135,7 +135,7 @@ void EmitResultSDNodeXFormAsOperand(const TreePatternNode *N, SmallVectorImpl &ResultOps); }; - + } // end anon namespace. MatcherGen::MatcherGen(const PatternToMatch &pattern, @@ -156,7 +156,7 @@ // PatWithNoTypes = Pattern.getSrcPattern()->clone(); PatWithNoTypes->RemoveAllTypes(); - + // If there are types that are manifestly known, infer them. InferPossibleTypes(); } @@ -169,7 +169,7 @@ // TP - Get *SOME* tree pattern, we don't care which. It is only used for // diagnostics, which we know are impossible at this point. TreePattern &TP = *CGP.pf_begin()->second; - + try { bool MadeChange = true; while (MadeChange) @@ -182,7 +182,7 @@ } -/// AddMatcher - Add a matcher node to the current graph we're building. +/// AddMatcher - Add a matcher node to the current graph we're building. void MatcherGen::AddMatcher(Matcher *NewNode) { if (CurPredicate != 0) CurPredicate->setNext(NewNode); @@ -199,7 +199,7 @@ /// EmitLeafMatchCode - Generate matching code for leaf nodes. void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { assert(N->isLeaf() && "Not a leaf?"); - + // Direct match against an integer constant. if (IntInit *II = dynamic_cast(N->getLeafValue())) { // If this is the root of the dag we're matching, we emit a redundant opcode @@ -212,16 +212,16 @@ return AddMatcher(new CheckIntegerMatcher(II->getValue())); } - + DefInit *DI = dynamic_cast(N->getLeafValue()); if (DI == 0) { errs() << "Unknown leaf kind: " << *DI << "\n"; abort(); } - + Record *LeafRec = DI->getDef(); if (// Handle register references. Nothing to do here, they always match. - LeafRec->isSubClassOf("RegisterClass") || + LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("PointerLikeRegClass") || LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. @@ -229,20 +229,20 @@ return; // If we have a physreg reference like (mul gpr:$src, EAX) then we need to - // record the register + // record the register if (LeafRec->isSubClassOf("Register")) { AddMatcher(new RecordMatcher("physreg input "+LeafRec->getName(), NextRecordedOperandNo)); PhysRegInputs.push_back(std::make_pair(LeafRec, NextRecordedOperandNo++)); return; } - + if (LeafRec->isSubClassOf("ValueType")) return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName())); - + if (LeafRec->isSubClassOf("CondCode")) return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName())); - + if (LeafRec->isSubClassOf("ComplexPattern")) { // We can't model ComplexPattern uses that don't have their name taken yet. // The OPC_CheckComplexPattern operation implicitly records the results. @@ -256,7 +256,7 @@ MatchedComplexPatterns.push_back(std::make_pair(N, 0)); return; } - + errs() << "Unknown leaf kind: " << *N << "\n"; abort(); } @@ -265,7 +265,7 @@ TreePatternNode *NodeNoTypes) { assert(!N->isLeaf() && "Not an operator?"); const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator()); - + // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is // a constant without a predicate fn that has more that one bit set, handle // this as a special case. This is usually for targets that have special @@ -276,7 +276,7 @@ // them from the mask in the dag. For example, it might turn 'AND X, 255' // into 'AND X, 254' if it knows the low bit is set. Emit code that checks // to handle this. - if ((N->getOperator()->getName() == "and" || + if ((N->getOperator()->getName() == "and" || N->getOperator()->getName() == "or") && N->getChild(1)->isLeaf() && N->getChild(1)->getPredicateFns().empty() && N->getPredicateFns().empty()) { @@ -302,15 +302,15 @@ } } } - + // Check that the current opcode lines up. AddMatcher(new CheckOpcodeMatcher(CInfo)); - + // If this node has memory references (i.e. is a load or store), tell the // interpreter to capture them in the memref array. if (N->NodeHasProperty(SDNPMemOperand, CGP)) AddMatcher(new RecordMemRefMatcher()); - + // If this node has a chain, then the chain is operand #0 is the SDNode, and // the child numbers of the node are all offset by one. unsigned OpNo = 0; @@ -321,7 +321,7 @@ NextRecordedOperandNo)); // Remember all of the input chains our pattern will match. MatchedChainNodes.push_back(NextRecordedOperandNo++); - + // Don't look at the input chain when matching the tree pattern to the // SDNode. OpNo = 1; @@ -352,7 +352,7 @@ // If there is a node between the root and this node, then we definitely // need to emit the check. bool NeedCheck = !Root->hasChild(N); - + // If it *is* an immediate child of the root, we can still need a check if // the root SDNode has multiple inputs. For us, this means that it is an // intrinsic, has multiple operands, or has other inputs like chain or @@ -368,17 +368,17 @@ PInfo.hasProperty(SDNPInFlag) || PInfo.hasProperty(SDNPOptInFlag); } - + if (NeedCheck) AddMatcher(new CheckFoldableChainNodeMatcher()); } } // If this node has an output flag and isn't the root, remember it. - if (N->NodeHasProperty(SDNPOutFlag, CGP) && + if (N->NodeHasProperty(SDNPOutFlag, CGP) && N != Pattern.getSrcPattern()) { // TODO: This redundantly records nodes with both flags and chains. - + // Record the node and remember it in our chained nodes list. AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() + "' flag output node", @@ -386,13 +386,13 @@ // Remember all of the nodes with output flags our pattern will match. MatchedFlagResultNodes.push_back(NextRecordedOperandNo++); } - + // If this node is known to have an input flag or if it *might* have an input // flag, capture it as the flag input of the pattern. if (N->NodeHasProperty(SDNPOptInFlag, CGP) || N->NodeHasProperty(SDNPInFlag, CGP)) AddMatcher(new CaptureFlagInputMatcher()); - + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { // Get the code suitable for matching this child. Move to the child, check // it then move back to the parent. @@ -409,14 +409,14 @@ // need to do a type check. Emit the check, apply the tyep to NodeNoTypes and // reinfer any correlated types. SmallVector ResultsToTypeCheck; - + for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) { if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue; NodeNoTypes->setType(i, N->getExtType(i)); InferPossibleTypes(); ResultsToTypeCheck.push_back(i); } - + // If this node has a name associated with it, capture it in VariableMap. If // we already saw this in the pattern, emit code to verify dagness. if (!N->getName().empty()) { @@ -434,16 +434,16 @@ return; } } - + if (N->isLeaf()) EmitLeafMatchCode(N); else EmitOperatorMatchCode(N, NodeNoTypes); - + // If there are node predicates for this node, generate their checks. for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i) AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i])); - + for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i) AddMatcher(new CheckTypeMatcher(N->getType(ResultsToTypeCheck[i]), ResultsToTypeCheck[i])); @@ -462,27 +462,27 @@ const std::vector &OpNodes = CP->getRootNodes(); assert(!OpNodes.empty() &&"Complex Pattern must specify what it can match"); if (Variant >= OpNodes.size()) return true; - + AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant]))); } else { if (Variant != 0) return true; } - + // Emit the matcher for the pattern structure and types. EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes); - + // If the pattern has a predicate on it (e.g. only enabled when a subtarget // feature is around, do the check). if (!Pattern.getPredicateCheck().empty()) AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck())); - + // Now that we've completed the structural type match, emit any ComplexPattern // checks (e.g. addrmode matches). We emit this after the structural match // because they are generally more expensive to evaluate and more difficult to // factor. for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i) { const TreePatternNode *N = MatchedComplexPatterns[i].first; - + // Remember where the results of this match get stuck. MatchedComplexPatterns[i].second = NextRecordedOperandNo; @@ -491,15 +491,15 @@ assert(!N->getName().empty() && RecNodeEntry && "Complex pattern should have a name and slot"); --RecNodeEntry; // Entries in VariableMap are biased. - + const ComplexPattern &CP = CGP.getComplexPattern(((DefInit*)N->getLeafValue())->getDef()); - + // Emit a CheckComplexPat operation, which does the match (aborting if it // fails) and pushes the matched operands onto the recorded nodes list. AddMatcher(new CheckComplexPatMatcher(CP, RecNodeEntry, N->getName(), NextRecordedOperandNo)); - + // Record the right number of operands. NextRecordedOperandNo += CP.getNumOperands(); if (CP.hasProperty(SDNPHasChain)) { @@ -507,17 +507,17 @@ // fact that we just recorded a chain input. The chain input will be // matched as the last operand of the predicate if it was successful. ++NextRecordedOperandNo; // Chained node operand. - + // It is the last operand recorded. assert(NextRecordedOperandNo > 1 && "Should have recorded input/result chains at least!"); MatchedChainNodes.push_back(NextRecordedOperandNo-1); } - + // TODO: Complex patterns can't have output flags, if they did, we'd want // to record them. } - + return false; } @@ -529,7 +529,7 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N, SmallVectorImpl &ResultOps){ assert(!N->getName().empty() && "Operand not named!"); - + // A reference to a complex pattern gets all of the results of the complex // pattern's match. if (const ComplexPattern *CP = N->getComplexPatternInfo(CGP)) { @@ -540,7 +540,7 @@ break; } assert(SlotNo != 0 && "Didn't get a slot number assigned?"); - + // The first slot entry is the node itself, the subsequent entries are the // matched values. for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) @@ -561,20 +561,20 @@ return; } } - + ResultOps.push_back(SlotNo); } void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, SmallVectorImpl &ResultOps) { assert(N->isLeaf() && "Must be a leaf"); - + if (IntInit *II = dynamic_cast(N->getLeafValue())) { AddMatcher(new EmitIntegerMatcher(II->getValue(), N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } - + // If this is an explicit register reference, handle it. if (DefInit *DI = dynamic_cast(N->getLeafValue())) { if (DI->getDef()->isSubClassOf("Register")) { @@ -582,13 +582,13 @@ ResultOps.push_back(NextRecordedOperandNo++); return; } - + if (DI->getDef()->getName() == "zero_reg") { AddMatcher(new EmitRegisterMatcher(0, N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } - + // Handle a reference to a register class. This is used // in COPY_TO_SUBREG instructions. if (DI->getDef()->isSubClassOf("RegisterClass")) { @@ -606,17 +606,17 @@ return; } } - + errs() << "unhandled leaf node: \n"; N->dump(); } /// GetInstPatternNode - Get the pattern for an instruction. -/// +/// const TreePatternNode *MatcherGen:: GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) { const TreePattern *InstPat = Inst.getPattern(); - + // FIXME2?: Assume actual pattern comes before "implicit". TreePatternNode *InstPatNode; if (InstPat) @@ -625,11 +625,11 @@ InstPatNode = Pattern.getSrcPattern(); else return 0; - + if (InstPatNode && !InstPatNode->isLeaf() && InstPatNode->getOperator()->getName() == "set") InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1); - + return InstPatNode; } @@ -640,7 +640,7 @@ const CodeGenTarget &CGT = CGP.getTargetInfo(); CodeGenInstruction &II = CGT.getInstruction(Op); const DAGInstruction &Inst = CGP.getInstruction(Op); - + // If we can, get the pattern for the instruction we're generating. We derive // a variety of information from this pattern, such as whether it has a chain. // @@ -649,10 +649,10 @@ // nodes can't duplicate. const TreePatternNode *InstPatNode = GetInstPatternNode(Inst, N); - // NodeHasChain - Whether the instruction node we're creating takes chains. + // NodeHasChain - Whether the instruction node we're creating takes chains. bool NodeHasChain = InstPatNode && InstPatNode->TreeHasProperty(SDNPHasChain, CGP); - + bool isRoot = N == Pattern.getDstPattern(); // TreeHasOutFlag - True if this tree has a flag. @@ -661,7 +661,7 @@ const TreePatternNode *SrcPat = Pattern.getSrcPattern(); TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) || SrcPat->TreeHasProperty(SDNPInFlag, CGP); - + // FIXME2: this is checking the entire pattern, not just the node in // question, doing this just for the root seems like a total hack. TreeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP); @@ -669,7 +669,7 @@ // NumResults - This is the number of results produced by the instruction in // the "outs" list. - unsigned NumResults = Inst.getNumResults(); + unsigned NumResults = Inst.getNumResults(); // Loop over all of the operands of the instruction pattern, emitting code // to fill them all in. The node 'N' usually has number children equal to @@ -680,7 +680,7 @@ SmallVector InstOps; for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.Operands.size(); InstOpNo != e; ++InstOpNo) { - + // Determine what to emit for this operand. Record *OperandNode = II.Operands[InstOpNo].Rec; if ((OperandNode->isSubClassOf("PredicateOperand") || @@ -689,28 +689,28 @@ // This is a predicate or optional def operand; emit the // 'default ops' operands. const DAGDefaultOperand &DefaultOp - = CGP.getDefaultOperand(OperandNode); + = CGP.getDefaultOperand(OperandNode); for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i) EmitResultOperand(DefaultOp.DefaultOps[i], InstOps); continue; } - + const TreePatternNode *Child = N->getChild(ChildNo); - + // Otherwise this is a normal operand or a predicate operand without // 'execute always'; emit it. unsigned BeforeAddingNumOps = InstOps.size(); EmitResultOperand(Child, InstOps); assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands"); - + // If the operand is an instruction and it produced multiple results, just // take the first one. if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction")) InstOps.resize(BeforeAddingNumOps+1); - + ++ChildNo; } - + // If this node has an input flag or explicitly specified input physregs, we // need to add chained and flagged copyfromreg nodes and materialize the flag // input. @@ -724,14 +724,14 @@ // flagged to the CopyFromReg nodes we just generated. TreeHasInFlag = true; } - + // Result order: node results, chain, flags - + // Determine the result types. SmallVector ResultVTs; for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) ResultVTs.push_back(N->getType(i)); - + // If this is the root instruction of a pattern that has physical registers in // its result pattern, add output VTs for them. For example, X86 has: // (set AL, (mul ...)) @@ -743,7 +743,7 @@ Record *HandledReg = 0; if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) HandledReg = II.ImplicitDefs[0]; - + for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { Record *Reg = Pattern.getDstRegs()[i]; if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; @@ -758,7 +758,7 @@ if (isRoot && (Pattern.getSrcPattern()->NodeHasProperty(SDNPVariadic, CGP))) NumFixedArityOperands = Pattern.getSrcPattern()->getNumChildren(); - + // If this is the root node and any of the nodes matched nodes in the input // pattern have MemRefs in them, have the interpreter collect them and plop // them onto this node. @@ -777,14 +777,14 @@ assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) && "Node has no result"); - + AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(), ResultVTs.data(), ResultVTs.size(), InstOps.data(), InstOps.size(), NodeHasChain, TreeHasInFlag, TreeHasOutFlag, NodeHasMemRefs, NumFixedArityOperands, NextRecordedOperandNo)); - + // The non-chain and non-flag results of the newly emitted node get recorded. for (unsigned i = 0, e = ResultVTs.size(); i != e; ++i) { if (ResultVTs[i] == MVT::Other || ResultVTs[i] == MVT::Glue) break; @@ -799,7 +799,7 @@ // Emit the operand. SmallVector InputOps; - + // FIXME2: Could easily generalize this to support multiple inputs and outputs // to the SDNodeXForm. For now we just support one input and one output like // the old instruction selector. @@ -838,7 +838,7 @@ if (!MatchedChainNodes.empty()) AddMatcher(new EmitMergeInputChainsMatcher (MatchedChainNodes.data(), MatchedChainNodes.size())); - + // Codegen the root of the result pattern, capturing the resulting values. SmallVector Ops; EmitResultOperand(Pattern.getDstPattern(), Ops); @@ -850,7 +850,7 @@ // explicit results. // unsigned NumSrcResults = Pattern.getSrcPattern()->getNumTypes(); - + // If the pattern also has (implicit) results, count them as well. if (!Pattern.getDstRegs().empty()) { // If the root came from an implicit def in the instruction handling stuff, @@ -864,14 +864,14 @@ if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) HandledReg = II.ImplicitDefs[0]; } - + for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { Record *Reg = Pattern.getDstRegs()[i]; if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; ++NumSrcResults; } - } - + } + assert(Ops.size() >= NumSrcResults && "Didn't provide enough results"); Ops.resize(NumSrcResults); @@ -880,7 +880,7 @@ if (!MatchedFlagResultNodes.empty()) AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(), MatchedFlagResultNodes.size())); - + AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern)); } @@ -895,12 +895,12 @@ // Generate the code for the matcher. if (Gen.EmitMatcherCode(Variant)) return 0; - + // FIXME2: Kill extra MoveParent commands at the end of the matcher sequence. // FIXME2: Split result code out to another table, and make the matcher end // with an "Emit " command. This allows result generation stuff to be // shared and factored? - + // If the match succeeds, then we generate Pattern. Gen.EmitResultCode(); From baldrick at free.fr Tue Dec 21 10:19:28 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 17:19:28 +0100 Subject: [llvm-commits] [llvm] r122264 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Utils/CMakeLists.txt lib/Transforms/Utils/Utils.cpp In-Reply-To: <4D101E6D.9030701@mxc.ca> References: <20101220205437.585452A6C12C@llvm.org> <4D101E6D.9030701@mxc.ca> Message-ID: <4D10D390.9000209@free.fr> Hi Nick, >> Add a new convenience pass for testing InstructionSimplify. Previously >> it could only be tested indirectly, via instcombine, gvn or some other >> pass that makes use of InstructionSimplify, which means that testcases >> had to be carefully contrived to dance around any other transformations >> that that pass did. > > If you're interested, you could also test it with the unit testing framework by > making calls to SimplifyInstruction. It would look something like: thanks for the interesting suggestion but I think using a pass is simpler. Ciao, Duncan. > > TEST(InstructionSimplify, AddTest) { > LLVMContext context; > Argument *A = new Argument(Type::Int64Ty); > Instruction *I = BinaryOperator::CreateNeg( > BinaryOperator::CreateSub( > ConstantInt::get(Type::Int64Ty, -1), > A > ) > ); > Instruction *J = SimplifyInstruction(I); > EXPECT_EQ(J->getOpcode(), Instruction::Add); > EXPECT_EQ(J->getOperand(0), A); > EXPECT_EQ(J->getOperand(1), ConstantInt::get(Type::Int64Ty), 1)); > } > > Since the C++ API is bulky, you can also use ParseAssemblyString to produce a > Module from inline .ll, see unittests/ExecutionEngine/JIT/JITTest.cpp for > inspiration. > > Nick From greened at obbligato.org Tue Dec 21 10:35:22 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 10:35:22 -0600 Subject: [llvm-commits] [LLVMdev] PR 8199 - Can we get patches reviewed? In-Reply-To: (David A. Greene's message of "Wed, 15 Dec 2010 15:10:59 -0600") References: Message-ID: A non-text attachment was scrubbed... Name: lit.patch Type: text/x-patch Size: 4439 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101221/cbdf9ad2/attachment.bin From greened at obbligato.org Tue Dec 21 10:55:53 2010 From: greened at obbligato.org (David Greene) Date: Tue, 21 Dec 2010 16:55:53 -0000 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py Message-ID: <20101221165554.21B872A6C12C@llvm.org> Author: greened Date: Tue Dec 21 10:55:53 2010 New Revision: 122341 URL: http://llvm.org/viewvc/llvm-project?rev=122341&view=rev Log: Fix PR 8199. This patch prepends the build tool dir to LLVM programs being tested. This ensures that we test the tools just built and not some random tools that might happen to be in the user's PATH. This makes LLVM testing much more stable and predictable. Modified: llvm/trunk/docs/TestingGuide.html llvm/trunk/test/lit.cfg llvm/trunk/utils/lit/lit/TestRunner.py Modified: llvm/trunk/docs/TestingGuide.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TestingGuide.html?rev=122341&r1=122340&r2=122341&view=diff ============================================================================== --- llvm/trunk/docs/TestingGuide.html (original) +++ llvm/trunk/docs/TestingGuide.html Tue Dec 21 10:55:53 2010 @@ -376,6 +376,11 @@ shell. Consequently the syntax differs from normal shell script syntax in a few ways. You can specify as many RUN lines as needed.

+

lit performs substitution on each RUN line to replace LLVM tool + names with the full paths to the executable built for each tool (in + $(LLVM_OBJ_ROOT)/$(BuildMode)/bin). This ensures that lit does not + invoke any stray LLVM tools in the user's path during testing.

+

Each RUN line is executed on its own, distinct from other lines unless its last character is \. This continuation character causes the RUN line to be concatenated with the next one. In this way you can build up long Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122341&r1=122340&r2=122341&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Tue Dec 21 10:55:53 2010 @@ -4,6 +4,7 @@ import os import sys +import re # name: The name of this test suite. config.name = 'LLVM' @@ -148,6 +149,44 @@ else: config.substitutions.append(('%' + sub, site_exp[sub])) +# For each occurrence of an llvm tool name as its own word, replace it +# with the full path to the build directory holding that tool. This +# ensures that we are testing the tools just built and not some random +# tools that might happen to be in the user's PATH. Thus this list +# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin +# (llvm_tools_dir in lit parlance). + # Don't match 'bugpoint-'. +for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b", + r"\bedis\b", r"\bgold\b", + r"\bllc\b", r"\blli\b", + r"\bllvm-ar\b", r"\bllvm-as\b", + r"\bllvm-bcanalyzer\b", r"\bllvm-config\b", + r"\bllvm-diff\b", r"\bllvm-dis\b", + r"\bllvm-extract\b", r"\bllvm-ld\b", + r"\bllvm-link\b", r"\bllvm-mc\b", + r"\bllvm-nm\b", r"\bllvm-prof\b", + r"\bllvm-ranlib\b", r"\bllvm-shlib\b", + r"\bllvm-stub\b", r"\bllvm2cpp\b", + # Don't match '-llvmc'. + r"(? Author: stuart Date: Tue Dec 21 11:07:24 2010 New Revision: 122342 URL: http://llvm.org/viewvc/llvm-project?rev=122342&view=rev Log: Missing logic for nested CALLSEQ_START/END. 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=122342&r1=122341&r2=122342&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 21 11:07:24 2010 @@ -255,8 +255,11 @@ static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { if (Node->getOpcode() == ISD::CALLSEQ_START) depth++; - if ((Node->getOpcode() == ISD::CALLSEQ_END) && (depth == 1)) - return Node; + else if (Node->getOpcode() == ISD::CALLSEQ_END) { + depth--; + if (depth == 0) + return Node; + } if (Node->use_empty()) return 0; // No CallSeqEnd From clattner at apple.com Tue Dec 21 11:10:43 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 09:10:43 -0800 Subject: [llvm-commits] [llvm] r122336 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <20101221161203.EE25D2A6C12C@llvm.org> References: <20101221161203.EE25D2A6C12C@llvm.org> Message-ID: <74700AA3-7E30-4B6C-8282-6B2C68481FE9@apple.com> On Dec 21, 2010, at 8:12 AM, Duncan Sands wrote: > Author: baldrick > Date: Tue Dec 21 10:12:03 2010 > New Revision: 122336 > > URL: http://llvm.org/viewvc/llvm-project?rev=122336&view=rev > Log: > If an instruction simplifies, try again to simplify any uses of it. This is > not very important since the pass is only used for testing, but it does make > it more realistic. Suggested by Frits van Bommel. Cool thanks. > + // Add all interesting instructions to the worklist. > + std::set Worklist; Using an std::set for this will cause the pass to work nondeterminstically (based on pointer addresses). How about using an std::vector like instcombine? The cost is that deleting an instruction requires scanning (linear time) the vector to see if an instruction is in the worklist multiple times. If you want to get really crazy, you can use a smallptrset + vector to prevent that. -Chris > for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) > for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { > Instruction *I = BI++; > - if (Value *V = SimplifyInstruction(I, TD, DT)) { > - I->replaceAllUsesWith(V); > + // Zap any dead instructions. > + if (isInstructionTriviallyDead(I)) { > I->eraseFromParent(); > Changed = true; > - ++NumSimplified; > + continue; > } > + // Add all others to the worklist. > + Worklist.insert(I); > } > + > + // Simplify everything in the worklist until the cows come home. > + while (!Worklist.empty()) { > + Instruction *I = *Worklist.begin(); > + Worklist.erase(Worklist.begin()); > + Value *V = SimplifyInstruction(I, TD, DT); > + if (!V) continue; > + > + // This instruction simplifies! Replace it with its simplification and > + // add all uses to the worklist, since they may now simplify. > + I->replaceAllUsesWith(V); > + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); > + UI != UE; ++UI) > + // In unreachable code an instruction can use itself, in which case > + // don't add it to the worklist since we are about to erase it. > + if (*UI != I) Worklist.insert(cast(*UI)); > + if (isInstructionTriviallyDead(I)) > + I->eraseFromParent(); > + ++NumSimplified; > + Changed = true; > + } > + > return Changed; > } > }; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue Dec 21 11:08:55 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 17:08:55 -0000 Subject: [llvm-commits] [llvm] r122343 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Message-ID: <20101221170855.588E82A6C131@llvm.org> Author: baldrick Date: Tue Dec 21 11:08:55 2010 New Revision: 122343 URL: http://llvm.org/viewvc/llvm-project?rev=122343&view=rev Log: Visit instructions deterministically. Use a FIFO so as to approximately visit instructions before their uses, since InstructionSimplify does a better job in that case. All this prompted by Frits van Bommel. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122343&r1=122342&r2=122343&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Tue Dec 21 11:08:55 2010 @@ -24,6 +24,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" +#include using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions removed"); @@ -45,8 +46,9 @@ const DominatorTree *DT = getAnalysisIfAvailable(); bool Changed = false; - // Add all interesting instructions to the worklist. - std::set Worklist; + // Add all interesting instructions to the worklist. These are processed + // in FIFO order, so instructions are usually visited before their uses. + std::queue Worklist; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; @@ -57,30 +59,38 @@ continue; } // Add all others to the worklist. - Worklist.insert(I); + Worklist.push(I); } // Simplify everything in the worklist until the cows come home. while (!Worklist.empty()) { - Instruction *I = *Worklist.begin(); - Worklist.erase(Worklist.begin()); + Instruction *I = Worklist.front(); + Worklist.pop(); + // Don't bother simplifying unused instructions. + if (I->use_empty()) continue; Value *V = SimplifyInstruction(I, TD, DT); if (!V) continue; // This instruction simplifies! Replace it with its simplification and // add all uses to the worklist, since they may now simplify. + ++NumSimplified; I->replaceAllUsesWith(V); for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE; ++UI) - // In unreachable code an instruction can use itself, in which case - // don't add it to the worklist since we are about to erase it. - if (*UI != I) Worklist.insert(cast(*UI)); - if (isInstructionTriviallyDead(I)) - I->eraseFromParent(); - ++NumSimplified; + Worklist.push(cast(*UI)); Changed = true; } + // Finally, run over the function zapping any dead instructions. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { + Instruction *I = BI++; + if (isInstructionTriviallyDead(I)) { + I->eraseFromParent(); + Changed = true; + } + } + return Changed; } }; From grosser at fim.uni-passau.de Tue Dec 21 11:12:49 2010 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 21 Dec 2010 12:12:49 -0500 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: <20101221165554.21B872A6C12C@llvm.org> References: <20101221165554.21B872A6C12C@llvm.org> Message-ID: <4D10E011.1080201@fim.uni-passau.de> On 12/21/2010 11:55 AM, David Greene wrote: > Author: greened > Date: Tue Dec 21 10:55:53 2010 > New Revision: 122341 > > URL: http://llvm.org/viewvc/llvm-project?rev=122341&view=rev > Log: > > Fix PR 8199. This patch prepends the build tool dir to LLVM programs > being tested. This ensures that we test the tools just built and not > some random tools that might happen to be in the user's PATH. This > makes LLVM testing much more stable and predictable. Hey David, sorry for not having responded to your replies on the bug report. I forgot to add myself to the CC, so did not get the replies. I just read your replies and have still an open question. You replied the patch provided by me, that prepends the llvm tools directory to the path will not solve the problem as it is too brittle. Can you explain this. I know that the path can contain arbitray binaries and libraries, however they are always searched first in the leftmost directories of the path. So by prepending /our/new/tools/dir: we will always get the right binaries. The problem of this bug was, that we created PATH=/system/path/with/llvm-gcc/:/our/new/tools/dir:... So any old llvm tools that where installed next to llvm-gcc where preferred over the ones in /our/new/tools/dir. This can be solved by always putting /our/new/tools/dir leftmost. Like: PATH=/usr/new/tools/dir:/system/path/with/llvm-gcc:... This seems for me to solve the issue without having to add a lot of subsitutions. Why do you think this solution is brittle? Cheers Tobi P.S.: Again, sorry for missing the bug report replies > Modified: > llvm/trunk/docs/TestingGuide.html > llvm/trunk/test/lit.cfg > llvm/trunk/utils/lit/lit/TestRunner.py > > Modified: llvm/trunk/docs/TestingGuide.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TestingGuide.html?rev=122341&r1=122340&r2=122341&view=diff > ============================================================================== > --- llvm/trunk/docs/TestingGuide.html (original) > +++ llvm/trunk/docs/TestingGuide.html Tue Dec 21 10:55:53 2010 > @@ -376,6 +376,11 @@ > shell. Consequently the syntax differs from normal shell script syntax in a > few ways. You can specify as many RUN lines as needed.

> > +

lit performs substitution on each RUN line to replace LLVM tool > + names with the full paths to the executable built for each tool (in > + $(LLVM_OBJ_ROOT)/$(BuildMode)/bin). This ensures that lit does not > + invoke any stray LLVM tools in the user's path during testing.

> + >

Each RUN line is executed on its own, distinct from other lines unless > its last character is\. This continuation character causes the RUN > line to be concatenated with the next one. In this way you can build up long > > Modified: llvm/trunk/test/lit.cfg > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122341&r1=122340&r2=122341&view=diff > ============================================================================== > --- llvm/trunk/test/lit.cfg (original) > +++ llvm/trunk/test/lit.cfg Tue Dec 21 10:55:53 2010 > @@ -4,6 +4,7 @@ > > import os > import sys > +import re > > # name: The name of this test suite. > config.name = 'LLVM' > @@ -148,6 +149,44 @@ > else: > config.substitutions.append(('%' + sub, site_exp[sub])) > > +# For each occurrence of an llvm tool name as its own word, replace it > +# with the full path to the build directory holding that tool. This > +# ensures that we are testing the tools just built and not some random > +# tools that might happen to be in the user's PATH. Thus this list > +# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin > +# (llvm_tools_dir in lit parlance). > + # Don't match 'bugpoint-'. > +for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b", > + r"\bedis\b", r"\bgold\b", > + r"\bllc\b", r"\blli\b", > + r"\bllvm-ar\b", r"\bllvm-as\b", > + r"\bllvm-bcanalyzer\b", r"\bllvm-config\b", > + r"\bllvm-diff\b", r"\bllvm-dis\b", > + r"\bllvm-extract\b", r"\bllvm-ld\b", > + r"\bllvm-link\b", r"\bllvm-mc\b", > + r"\bllvm-nm\b", r"\bllvm-prof\b", > + r"\bllvm-ranlib\b", r"\bllvm-shlib\b", > + r"\bllvm-stub\b", r"\bllvm2cpp\b", > + # Don't match '-llvmc'. > + r"(? + # Don't match '.opt', '-opt' > + # or '^opt'. > + r"\bmacho-dump\b", r"(? + r"\btblgen\b", r"\bFileCheck\b", > + r"\bFileUpdate\b", r"\bc-index-test\b", > + r"\bfpcmp\b", r"\bllvm-PerfectShuffle\b", > + # Handle these specially as they are strings searched > + # for during testing. > + r"\| \bcount\b", r"\| \bnot\b"]: > + # Extract the tool name from the pattern. This relies on the tool > + # name being surrounded by \b word match operators. If the > + # pattern starts with "| ", include it in the string to be > + # substituted. > + substitution = re.sub(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$", > + r"\2" + llvm_tools_dir + "/" + r"\4", > + pattern) > + config.substitutions.append((pattern, substitution)) > + > excludes = [] > > # Provide target_triple for use in XFAIL and XTARGET. > > Modified: llvm/trunk/utils/lit/lit/TestRunner.py > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestRunner.py?rev=122341&r1=122340&r2=122341&view=diff > ============================================================================== > --- llvm/trunk/utils/lit/lit/TestRunner.py (original) > +++ llvm/trunk/utils/lit/lit/TestRunner.py Tue Dec 21 10:55:53 2010 > @@ -8,6 +8,8 @@ > import platform > import tempfile > > +import re > + > class InternalShellError(Exception): > def __init__(self, command, message): > self.command = command > @@ -444,11 +446,13 @@ > if ln[ln.index('END.'):].strip() == 'END.': > break > > - # Apply substitutions to the script. > + # Apply substitutions to the script. Allow full regular > + # expression syntax. Replace each matching occurrence of regular > + # expression pattern a with substitution b in line ln. > def processLine(ln): > # Apply substitutions > for a,b in substitutions: > - ln = ln.replace(a,b) > + ln = re.sub(a, b, ln) > > # Strip the trailing newline and any extra whitespace. > return ln.strip() > > > _______________________________________________ > 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 Dec 21 11:13:00 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 09:13:00 -0800 Subject: [llvm-commits] [llvm] r122326 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/ test/Transforms/InstSimplify/2010-12-20-Reassociate.ll test/Transforms/InstSimplify/dg.exp In-Reply-To: <20101221084900.DFBF42A6C12D@llvm.org> References: <20101221084900.DFBF42A6C12D@llvm.org> Message-ID: <8378C911-1AA6-4372-995A-0CB82FCEF42C@apple.com> On Dec 21, 2010, at 12:49 AM, Duncan Sands wrote: > Author: baldrick > Date: Tue Dec 21 02:49:00 2010 > New Revision: 122326 > > URL: http://llvm.org/viewvc/llvm-project?rev=122326&view=rev > Log: > Add generic simplification of associative operations, generalizing > a couple of existing transforms. This fires surprisingly often, for > example when compiling gcc "(X+(-1))+1->X" fires quite a lot as well > as various "and" simplifications (usually with a phi node operand). > Most of the time this doesn't make a real difference since the same > thing would have been done elsewhere anyway, eg: by instcombine, but > there are a few places where this results in simplifications that we > were not doing before. Nice. Should the related logic get ripped out of instcombine? It is probably a little more general, but if it doesn't matter in practice, we should remove it. -Chris From clattner at apple.com Tue Dec 21 11:14:20 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 09:14:20 -0800 Subject: [llvm-commits] [llvm] r122342 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: <20101221170724.47CE72A6C131@llvm.org> References: <20101221170724.47CE72A6C131@llvm.org> Message-ID: On Dec 21, 2010, at 9:07 AM, Stuart Hastings wrote: > Author: stuart > Date: Tue Dec 21 11:07:24 2010 > New Revision: 122342 > > URL: http://llvm.org/viewvc/llvm-project?rev=122342&view=rev > Log: > Missing logic for nested CALLSEQ_START/END. Ok, but please indent the code properly and add some comments explaining what this is doing. -Chris > > 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=122342&r1=122341&r2=122342&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 21 11:07:24 2010 > @@ -255,8 +255,11 @@ > static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { > if (Node->getOpcode() == ISD::CALLSEQ_START) > depth++; > - if ((Node->getOpcode() == ISD::CALLSEQ_END) && (depth == 1)) > - return Node; > + else if (Node->getOpcode() == ISD::CALLSEQ_END) { > + depth--; > + if (depth == 0) > + return Node; > + } > if (Node->use_empty()) > return 0; // No CallSeqEnd > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From aggarwa4 at illinois.edu Tue Dec 21 11:13:02 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 17:13:02 -0000 Subject: [llvm-commits] [poolalloc] r122344 - in /poolalloc/trunk: include/dsa/DSGraph.h lib/DSA/BottomUpClosure.cpp lib/DSA/CompleteBottomUp.cpp lib/DSA/DSGraph.cpp Message-ID: <20101221171302.84EFD2A6C131@llvm.org> Author: aggarwa4 Date: Tue Dec 21 11:13:02 2010 New Revision: 122344 URL: http://llvm.org/viewvc/llvm-project?rev=122344&view=rev Log: 1. DSCallGraph should only default to adding the whole GlobalFunction list(all address taken functions) once we have finished BU. 2. We do not need to build SCCs in BU. Push to CBU. Modified: poolalloc/trunk/include/dsa/DSGraph.h poolalloc/trunk/lib/DSA/BottomUpClosure.cpp poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp poolalloc/trunk/lib/DSA/DSGraph.cpp Modified: poolalloc/trunk/include/dsa/DSGraph.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=122344&r1=122343&r2=122344&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DSGraph.h (original) +++ poolalloc/trunk/include/dsa/DSGraph.h Tue Dec 21 11:13:02 2010 @@ -346,6 +346,7 @@ void addAuxFunctionCall(DSCallSite D) { AuxFunctionCalls.push_front(D); } void buildCallGraph(DSCallGraph& DCG, std::vector &GlobalFunctionList, bool filter) const; + void buildCompleteCallGraph(DSCallGraph& DCG, std::vector &GlobalFunctionList, bool filter) const; /// removeFunction - Specify that all call sites to the function have been /// fully specified by a pass such as StdLibPass. Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=122344&r1=122343&r2=122344&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Dec 21 11:13:02 2010 @@ -59,12 +59,6 @@ bool BUDataStructures::runOnModuleInternal(Module& M) { // - // Put the callgraph into canonical form by finding SCCs. - // - callgraph.buildSCCs(); - callgraph.buildRoots(); - - // // Make sure we have a DSGraph for all declared functions in the Module. // While we may not need them in this DSA pass, a later DSA pass may ask us // for their DSGraphs, and we want to have them if asked. @@ -121,13 +115,6 @@ NumCallEdges += callgraph.size(); - // - // Put the callgraph into canonical form by finding SCCs. It has been - // updated since we did this last. - // - callgraph.buildSCCs(); - callgraph.buildRoots(); - return false; } @@ -615,7 +602,7 @@ // Update the callgraph with the new information that we have gleaned. // NOTE : This must be called before removeDeadNodes, so that no // information is lost due to deletion of DSCallNodes. - Graph->buildCallGraph(callgraph,GlobalFunctionList, filterCallees); + Graph->buildCallGraph(callgraph, GlobalFunctionList, filterCallees); // Delete dead nodes. Treat globals that are unreachable but that can // reach live nodes as live. Modified: poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp?rev=122344&r1=122343&r2=122344&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original) +++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Tue Dec 21 11:13:02 2010 @@ -51,9 +51,13 @@ // DSgraphs for all the functions. for (Module::iterator F = M.begin(); F != M.end(); ++F) { - if (!(F->isDeclaration())) - getOrCreateGraph(F); + if (!(F->isDeclaration())){ + DSGraph *Graph = getOrCreateGraph(F); + Graph->buildCompleteCallGraph(callgraph, GlobalFunctionList, filterCallees); + } } + callgraph.buildSCCs(); + callgraph.buildRoots(); buildIndirectFunctionSets(); formGlobalECs(); @@ -80,6 +84,10 @@ // Do bottom-up propagation. // bool modified = runOnModuleInternal(M); + + callgraph.buildSCCs(); + callgraph.buildRoots(); + return modified; } Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122344&r1=122343&r2=122344&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Tue Dec 21 11:13:02 2010 @@ -1626,14 +1626,12 @@ CallSite CS = ii->getCallSite(); std::vector MaybeTargets; + if(ii->getCalleeNode()->isIncompleteNode()) + continue; // // Get the list of known targets of this function. // - if(ii->getCalleeNode()->isIncompleteNode()) { - MaybeTargets.assign(GlobalFunctionList.begin(), GlobalFunctionList.end()); - } else { - ii->getCalleeNode()->addFullFunctionList(MaybeTargets); - } + ii->getCalleeNode()->addFullFunctionList(MaybeTargets); // // Ensure that the call graph at least knows about (has a record of) this @@ -1663,3 +1661,42 @@ } } } +void DSGraph::buildCompleteCallGraph(DSCallGraph& DCG, std::vector& GlobalFunctionList, bool filter) const { + // + // Get the list of unresolved call sites. + // + const std::list& Calls = getAuxFunctionCalls(); + for (std::list::const_iterator ii = Calls.begin(), + ee = Calls.end(); + ii != ee; ++ii) { + + if (ii->isDirectCall()) continue; + if (ii->getCalleeNode()->isCompleteNode()) continue; + CallSite CS = ii->getCallSite(); + if (DCG.callee_size(CS) != 0) continue; + std::vector MaybeTargets; + MaybeTargets.assign(GlobalFunctionList.begin(), GlobalFunctionList.end()); + + DCG.insert(CS, 0); + // + // Add to the call graph only function targets that have well-defined + // behavior using LLVM semantics. + // + for (std::vector::iterator Fi = MaybeTargets.begin(), + Fe = MaybeTargets.end(); Fi != Fe; ++Fi) + if (!filter || functionIsCallable(CS, *Fi)) + DCG.insert(CS, *Fi); + else + ++NumFiltered; + for (unsigned i = 0; i < ii->getNumMappedSites(); i++) { + CallSite MCS = ii->getMappedCallSite(i); + for (std::vector::iterator Fi = MaybeTargets.begin(), + Fe = MaybeTargets.end(); Fi != Fe; ++Fi){ + if (!filter || functionIsCallable(MCS, *Fi)) + DCG.insert(MCS, *Fi); + else + ++NumFiltered; + } + } + } +} From clattner at apple.com Tue Dec 21 11:16:03 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 09:16:03 -0800 Subject: [llvm-commits] [llvm] r122343 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <20101221170855.588E82A6C131@llvm.org> References: <20101221170855.588E82A6C131@llvm.org> Message-ID: <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> On Dec 21, 2010, at 9:08 AM, Duncan Sands wrote: > Author: baldrick > Date: Tue Dec 21 11:08:55 2010 > New Revision: 122343 > > URL: http://llvm.org/viewvc/llvm-project?rev=122343&view=rev > Log: > Visit instructions deterministically. Use a FIFO so as to approximately > visit instructions before their uses, since InstructionSimplify does a > better job in that case. All this prompted by Frits van Bommel. Ok. If you're going to delay deleting instructions, it might be worthwhile to drop their operands so that "dead" instructions don't cause hasOneUse() checks to fail. -Chris > > Modified: > llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp > > Modified: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp?rev=122343&r1=122342&r2=122343&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp Tue Dec 21 11:08:55 2010 > @@ -24,6 +24,7 @@ > #include "llvm/Target/TargetData.h" > #include "llvm/Transforms/Scalar.h" > #include "llvm/Transforms/Utils/Local.h" > +#include > using namespace llvm; > > STATISTIC(NumSimplified, "Number of redundant instructions removed"); > @@ -45,8 +46,9 @@ > const DominatorTree *DT = getAnalysisIfAvailable(); > bool Changed = false; > > - // Add all interesting instructions to the worklist. > - std::set Worklist; > + // Add all interesting instructions to the worklist. These are processed > + // in FIFO order, so instructions are usually visited before their uses. > + std::queue Worklist; > for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) > for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { > Instruction *I = BI++; > @@ -57,30 +59,38 @@ > continue; > } > // Add all others to the worklist. > - Worklist.insert(I); > + Worklist.push(I); > } > > // Simplify everything in the worklist until the cows come home. > while (!Worklist.empty()) { > - Instruction *I = *Worklist.begin(); > - Worklist.erase(Worklist.begin()); > + Instruction *I = Worklist.front(); > + Worklist.pop(); > + // Don't bother simplifying unused instructions. > + if (I->use_empty()) continue; > Value *V = SimplifyInstruction(I, TD, DT); > if (!V) continue; > > // This instruction simplifies! Replace it with its simplification and > // add all uses to the worklist, since they may now simplify. > + ++NumSimplified; > I->replaceAllUsesWith(V); > for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); > UI != UE; ++UI) > - // In unreachable code an instruction can use itself, in which case > - // don't add it to the worklist since we are about to erase it. > - if (*UI != I) Worklist.insert(cast(*UI)); > - if (isInstructionTriviallyDead(I)) > - I->eraseFromParent(); > - ++NumSimplified; > + Worklist.push(cast(*UI)); > Changed = true; > } > > + // Finally, run over the function zapping any dead instructions. > + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) > + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { > + Instruction *I = BI++; > + if (isInstructionTriviallyDead(I)) { > + I->eraseFromParent(); > + Changed = true; > + } > + } > + > return Changed; > } > }; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From stuart at apple.com Tue Dec 21 11:16:59 2010 From: stuart at apple.com (Stuart Hastings) Date: Tue, 21 Dec 2010 17:16:59 -0000 Subject: [llvm-commits] [llvm] r122345 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <20101221171659.0FD392A6C131@llvm.org> Author: stuart Date: Tue Dec 21 11:16:58 2010 New Revision: 122345 URL: http://llvm.org/viewvc/llvm-project?rev=122345&view=rev Log: Fix indentation, add comment. 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=122345&r1=122344&r2=122345&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 21 11:16:58 2010 @@ -253,13 +253,15 @@ /// FindCallEndFromCallStart - Given a chained node that is part of a call /// sequence, find the CALLSEQ_END node that terminates the call sequence. static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { + // Nested CALLSEQ_START/END constructs aren't yet legal, + // but we can DTRT and handle them correctly here. if (Node->getOpcode() == ISD::CALLSEQ_START) depth++; else if (Node->getOpcode() == ISD::CALLSEQ_END) { - depth--; - if (depth == 0) - return Node; - } + depth--; + if (depth == 0) + return Node; + } if (Node->use_empty()) return 0; // No CallSeqEnd From greened at obbligato.org Tue Dec 21 11:25:43 2010 From: greened at obbligato.org (David Greene) Date: Tue, 21 Dec 2010 17:25:43 -0000 Subject: [llvm-commits] [llvm] r122346 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py Message-ID: <20101221172543.D9C952A6C131@llvm.org> Author: greened Date: Tue Dec 21 11:25:43 2010 New Revision: 122346 URL: http://llvm.org/viewvc/llvm-project?rev=122346&view=rev Log: Revert 122341. It breaks some darwin tests. Modified: llvm/trunk/docs/TestingGuide.html llvm/trunk/test/lit.cfg llvm/trunk/utils/lit/lit/TestRunner.py Modified: llvm/trunk/docs/TestingGuide.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TestingGuide.html?rev=122346&r1=122345&r2=122346&view=diff ============================================================================== --- llvm/trunk/docs/TestingGuide.html (original) +++ llvm/trunk/docs/TestingGuide.html Tue Dec 21 11:25:43 2010 @@ -376,11 +376,6 @@ shell. Consequently the syntax differs from normal shell script syntax in a few ways. You can specify as many RUN lines as needed.

-

lit performs substitution on each RUN line to replace LLVM tool - names with the full paths to the executable built for each tool (in - $(LLVM_OBJ_ROOT)/$(BuildMode)/bin). This ensures that lit does not - invoke any stray LLVM tools in the user's path during testing.

-

Each RUN line is executed on its own, distinct from other lines unless its last character is \. This continuation character causes the RUN line to be concatenated with the next one. In this way you can build up long Modified: llvm/trunk/test/lit.cfg URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=122346&r1=122345&r2=122346&view=diff ============================================================================== --- llvm/trunk/test/lit.cfg (original) +++ llvm/trunk/test/lit.cfg Tue Dec 21 11:25:43 2010 @@ -4,7 +4,6 @@ import os import sys -import re # name: The name of this test suite. config.name = 'LLVM' @@ -149,44 +148,6 @@ else: config.substitutions.append(('%' + sub, site_exp[sub])) -# For each occurrence of an llvm tool name as its own word, replace it -# with the full path to the build directory holding that tool. This -# ensures that we are testing the tools just built and not some random -# tools that might happen to be in the user's PATH. Thus this list -# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin -# (llvm_tools_dir in lit parlance). - # Don't match 'bugpoint-'. -for pattern in [r"\bbugpoint\b(?!-)", r"\bclang\b", - r"\bedis\b", r"\bgold\b", - r"\bllc\b", r"\blli\b", - r"\bllvm-ar\b", r"\bllvm-as\b", - r"\bllvm-bcanalyzer\b", r"\bllvm-config\b", - r"\bllvm-diff\b", r"\bllvm-dis\b", - r"\bllvm-extract\b", r"\bllvm-ld\b", - r"\bllvm-link\b", r"\bllvm-mc\b", - r"\bllvm-nm\b", r"\bllvm-prof\b", - r"\bllvm-ranlib\b", r"\bllvm-shlib\b", - r"\bllvm-stub\b", r"\bllvm2cpp\b", - # Don't match '-llvmc'. - r"(? References: <20101221161203.EE25D2A6C12C@llvm.org> <74700AA3-7E30-4B6C-8282-6B2C68481FE9@apple.com> Message-ID: On Dec 21, 2010, at 9:10 AM, Chris Lattner wrote: > Using an std::set for this will cause the pass to work nondeterminstically (based on pointer addresses). How about using an std::vector like instcombine? The cost is that deleting an instruction requires scanning (linear time) the vector to see if an instruction is in the worklist multiple times. If you want to get really crazy, you can use a smallptrset + vector to prevent that. AKA llvm::SetVector ;-) /jakob From greened at obbligato.org Tue Dec 21 11:37:00 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 11:37:00 -0600 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: <4D10E011.1080201@fim.uni-passau.de> (Tobias Grosser's message of "Tue, 21 Dec 2010 12:12:49 -0500") References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> Message-ID: Tobias Grosser writes: > I just read your replies and have still an open question. You replied > the patch provided by me, that prepends the llvm tools directory to the > path will not solve the problem as it is too brittle. Can you explain this. Because you never really know what else lit might prepend to the PATH, as the PR demonstrates. It's just more solid to say what you really mean. As a bonus, when things fail, the run script output by lit will include the full paths so you know exactly what ran. BTW, I just reverted the patch as it causes some darwin failures. I don't have a darwin system to test on and all the error message says is "multiple repeat." It means something is wrong with a regexp but I don't have an easy way to figure out what. Is anyone with a darwin system able to investigate? I'll blindly poke around for now. :) -Dave From greened at obbligato.org Tue Dec 21 11:48:34 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 11:48:34 -0600 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: (David A. Greene's message of "Tue, 21 Dec 2010 11:37:00 -0600") References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> Message-ID: greened at obbligato.org (David A. Greene) writes: > BTW, I just reverted the patch as it causes some darwin failures. I > don't have a darwin system to test on and all the error message says is > "multiple repeat." It means something is wrong with a regexp but I > don't have an easy way to figure out what. Is anyone with a darwin > system able to investigate? I'll blindly poke around for now. :) Hmm, this looks suspicious: TMPDIR=/var/folders/vv/vvnmCGV-Esqto-WzbFXyMU+++TM/-Tmp-/ What is TMPDIR used for on the darwin buildbot? -Dave From clattner at apple.com Tue Dec 21 11:50:49 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 09:50:49 -0800 Subject: [llvm-commits] [llvm] r122336 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: References: <20101221161203.EE25D2A6C12C@llvm.org> <74700AA3-7E30-4B6C-8282-6B2C68481FE9@apple.com> Message-ID: <7B90A8C9-CF2B-4046-94F1-34A075531D32@apple.com> On Dec 21, 2010, at 9:33 AM, Jakob Stoklund Olesen wrote: > > On Dec 21, 2010, at 9:10 AM, Chris Lattner wrote: > >> Using an std::set for this will cause the pass to work nondeterminstically (based on pointer addresses). How about using an std::vector like instcombine? The cost is that deleting an instruction requires scanning (linear time) the vector to see if an instruction is in the worklist multiple times. If you want to get really crazy, you can use a smallptrset + vector to prevent that. > > AKA llvm::SetVector ;-) Yeah, that! :) -Chris From fvbommel at gmail.com Tue Dec 21 11:53:00 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Tue, 21 Dec 2010 18:53:00 +0100 Subject: [llvm-commits] [llvm] r122343 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> References: <20101221170855.588E82A6C131@llvm.org> <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> Message-ID: On Tue, Dec 21, 2010 at 6:16 PM, Chris Lattner wrote: > Ok. ?If you're going to delay deleting instructions, it might be worthwhile to drop their operands so that "dead" instructions don't cause hasOneUse() checks to fail. SimplifyInstruction() doesn't create any new instructions, so it shouldn't have any need for hasOneUse(). 'grep hasOneUse InstructionSimplify.cpp ConstantFolding.cpp' seems to confirms this. From sabre at nondot.org Tue Dec 21 12:05:22 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Dec 2010 18:05:22 -0000 Subject: [llvm-commits] [llvm] r122349 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20101221180522.DE8F02A6C12C@llvm.org> Author: lattner Date: Tue Dec 21 12:05:22 2010 New Revision: 122349 URL: http://llvm.org/viewvc/llvm-project?rev=122349&view=rev Log: fix some typos 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=122349&r1=122348&r2=122349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 12:05:22 2010 @@ -4186,8 +4186,7 @@ if (LegalOperations && !TLI.isLoadExtLegal(ISD::SEXTLOAD, ExtVT)) return SDValue(); } else if (Opc == ISD::SRL) { - // Annother special-case: SRL is basically zero-extending a narrower - // value. + // Another special-case: SRL is basically zero-extending a narrower value. ExtType = ISD::ZEXTLOAD; N0 = SDValue(N, 0); ConstantSDNode *N01 = dyn_cast(N0.getOperand(1)); From grosser at fim.uni-passau.de Tue Dec 21 13:00:25 2010 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 21 Dec 2010 14:00:25 -0500 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> Message-ID: <4D10F949.9080301@fim.uni-passau.de> On 12/21/2010 12:37 PM, David A. Greene wrote: > Tobias Grosser writes: > >> I just read your replies and have still an open question. You replied >> the patch provided by me, that prepends the llvm tools directory to the >> path will not solve the problem as it is too brittle. Can you explain this. > > Because you never really know what else lit might prepend to the PATH, > as the PR demonstrates. This is something we can control and nothing I expect to happen very often. Lit is prepending exactly three items. > It's just more solid to say what you really > mean. Sure. However replacing strings like " opt " is nothing that I would expect while writing test files. So this step is not 100% solid. However, as it would probably fail in an obvious way, there is no need to worry about this. Especially as you documented the change. Defining the correct path however is also saying what we really mean, and we can rely on the parsing of the shell to prepend this path to the binaries, but not to arbitrary strings somewhere in the command line. So in case of test case writing this is probably more solid. We just need to make sure lit does not use a wrong path. > As a bonus, when things fail, the run script output by lit will > include the full paths so you know exactly what ran. This is a valid point. I am just worried we gonna forget to add tools to this explicit list. Do you think we can in addition fix the PATH order as proposed in my patch? In case we forget to add some tools, it would still do the right thing. We just do not get the convenient absolute path and are doomed if someone prepends another path. I believe this will not happen too often and I think this would be a bug in lit. We can e.g. add a test case, that tests that the first component of the path is the tools directory. Furthermore it will fix the problem for the moment, without failing any builds. So you have some time to figure out what went wrong. Cheers Tobi From greened at obbligato.org Tue Dec 21 13:07:51 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 13:07:51 -0600 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: <4D10F949.9080301@fim.uni-passau.de> (Tobias Grosser's message of "Tue, 21 Dec 2010 14:00:25 -0500") References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> <4D10F949.9080301@fim.uni-passau.de> Message-ID: Tobias Grosser writes: > On 12/21/2010 12:37 PM, David A. Greene wrote: >> Tobias Grosser writes: >> >>> I just read your replies and have still an open question. You replied >>> the patch provided by me, that prepends the llvm tools directory to the >>> path will not solve the problem as it is too brittle. Can you explain this. >> >> Because you never really know what else lit might prepend to the PATH, >> as the PR demonstrates. > This is something we can control and nothing I expect to happen very > often. Lit is prepending exactly three items. Except testing was broken for over a year for me and we could never figure out why. I really, really don't trust magic paths. >> It's just more solid to say what you really >> mean. > Sure. However replacing strings like " opt " is nothing that I would > expect while writing test files. So this step is not 100% solid. Why not? It's a tool name, right? > I am just worried we gonna forget to add tools to this explicit list. Yes, that's a risk. > Do you think we can in addition fix the PATH order as proposed in my > patch? In case we forget to add some tools, it would still do the > right thing. We just do not get the convenient absolute path and are > doomed if someone prepends another path. I believe this will not > happen too often and I think this would be a bug in lit. We can > e.g. add a test case, that tests that the first component of the path > is the tools directory. I'm a little hesitant to do this fix two different ways. I'm not the owner of lit though, so go ahead and propose/commit it if you want. > Furthermore it will fix the problem for the moment, without failing > any builds. So you have some time to figure out what went wrong. I think I know what went wrong. Just have to go fix it now. :) -Dave From grosser at fim.uni-passau.de Tue Dec 21 13:25:15 2010 From: grosser at fim.uni-passau.de (Tobias Grosser) Date: Tue, 21 Dec 2010 14:25:15 -0500 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> <4D10F949.9080301@fim.uni-passau.de> Message-ID: <4D10FF1B.2020300@fim.uni-passau.de> On 12/21/2010 02:07 PM, David A. Greene wrote: > Tobias Grosser writes: > >> On 12/21/2010 12:37 PM, David A. Greene wrote: >>> Tobias Grosser writes: >>> >>>> I just read your replies and have still an open question. You replied >>>> the patch provided by me, that prepends the llvm tools directory to the >>>> path will not solve the problem as it is too brittle. Can you explain this. >>> >>> Because you never really know what else lit might prepend to the PATH, >>> as the PR demonstrates. >> This is something we can control and nothing I expect to happen very >> often. Lit is prepending exactly three items. > > Except testing was broken for over a year for me and we could never > figure out why. I really, really don't trust magic paths. OK. >>> It's just more solid to say what you really >>> mean. >> Sure. However replacing strings like " opt " is nothing that I would >> expect while writing test files. So this step is not 100% solid. > > Why not? It's a tool name, right? Because until now only things prepended with % where replaced. So a check: ; RUN: opt %s -pass -analyze | grep "loop1: opt simple, loop2: opt none" Here 'opt' would be replaced, right? Or if the tool is not freestanding. Maybe someone is using a shell subexpression to execute a tool: ; RUN: if `opt %s -pass -analyze | grep marker` : ... Whould 'opt' be replaced in this line? Those are definitely not very common use case, however they are valid test files, if not documented otherwise. The failure will be obvious for the first one, however less obvious for the second one (where still the wrong opt is gonna be executed) In any case I just wanted to point out, that this might happen. I am OK with taking the risk, as it is very convenient to have the absolute paths in the command line, and the cases I where your solution is incorrect could be forbidden by policy. Using %opt instead of opt is probably more obvious, however I believe this would complicate the test files unnecessarily. >> I am just worried we gonna forget to add tools to this explicit list. > > Yes, that's a risk. > >> Do you think we can in addition fix the PATH order as proposed in my >> patch? In case we forget to add some tools, it would still do the >> right thing. We just do not get the convenient absolute path and are >> doomed if someone prepends another path. I believe this will not >> happen too often and I think this would be a bug in lit. We can >> e.g. add a test case, that tests that the first component of the path >> is the tools directory. > > I'm a little hesitant to do this fix two different ways. I'm not the > owner of lit though, so go ahead and propose/commit it if you want. No need to push my changes in. However if you agree it is a good thing, or at least does not hurt to fix the path order, I would go ahead and commit. >> Furthermore it will fix the problem for the moment, without failing >> any builds. So you have some time to figure out what went wrong. > > I think I know what went wrong. Just have to go fix it now. :) Good luck. Tobi From dalej at apple.com Tue Dec 21 14:00:06 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 21 Dec 2010 20:00:06 -0000 Subject: [llvm-commits] [llvm] r122353 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20101221200006.D16D32A6C12C@llvm.org> Author: johannes Date: Tue Dec 21 14:00:06 2010 New Revision: 122353 URL: http://llvm.org/viewvc/llvm-project?rev=122353&view=rev Log: Shift by the word size is invalid IR; don't create it. 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=122353&r1=122352&r2=122353&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 14:00:06 2010 @@ -2967,7 +2967,7 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 > OpSizeInBits) + if (c1 + c2 >= OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); @@ -3165,7 +3165,7 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 > OpSizeInBits) + if (c1 + c2 >= OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); From dalej at apple.com Tue Dec 21 14:06:20 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 21 Dec 2010 20:06:20 -0000 Subject: [llvm-commits] [llvm] r122354 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/divide-by-constant.ll Message-ID: <20101221200620.2580D2A6C12C@llvm.org> Author: johannes Date: Tue Dec 21 14:06:19 2010 New Revision: 122354 URL: http://llvm.org/viewvc/llvm-project?rev=122354&view=rev Log: Get the type of a shift from the shift, not from its shift count operand. These should be the same but apparently are not always, and this is cleaner anyway. This improves the code in an existing test. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122354&r1=122353&r2=122354&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 14:06:19 2010 @@ -3178,7 +3178,7 @@ uint64_t c1 = cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType(); + EVT InnerShiftVT = N0.getOperand(0).getValueType(); uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); // This is only valid if the OpSizeInBits + c1 = size of inner shift. if (c1 + OpSizeInBits == InnerShiftSize) { Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=122354&r1=122353&r2=122354&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original) +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Tue Dec 21 14:06:19 2010 @@ -29,9 +29,9 @@ ret i8 %div ; CHECK: test3: -; CHECK: imull $171, %eax, %eax -; CHECK-NEXT: shrb %ah -; CHECK-NEXT: movzbl %ah, %eax +; CHECK: movzbl 8(%esp), %eax +; CHECK-NEXT: imull $171, %eax, %eax +; CHECK-NEXT: shrl $9, %eax ; CHECK-NEXT: ret } From dalej at apple.com Tue Dec 21 14:10:51 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 21 Dec 2010 20:10:51 -0000 Subject: [llvm-commits] [llvm] r122355 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/x86-64-extend-shift.ll Message-ID: <20101221201051.9AF342A6C12C@llvm.org> Author: johannes Date: Tue Dec 21 14:10:51 2010 New Revision: 122355 URL: http://llvm.org/viewvc/llvm-project?rev=122355&view=rev Log: Add a new transform to DAGCombiner. Added: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll 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=122355&r1=122354&r2=122355&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 14:10:51 2010 @@ -2972,6 +2972,32 @@ return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); } + + // fold (shl (ext (shl x, c1)), c2) -> (ext (shl x, (add c1, c2))) + // For this to be valid, the second form must not preserve any of the bits + // that are shifted out by the inner shift in the first form. This means + // the outer shift size must be >= the number of bits added by the ext. + // As a corollary, we don't care what kind of ext it is. + if (N1C && (N0.getOpcode() == ISD::ZERO_EXTEND || + N0.getOpcode() == ISD::ANY_EXTEND || + N0.getOpcode() == ISD::SIGN_EXTEND) && + N0.getOperand(0).getOpcode() == ISD::SHL && + isa(N0.getOperand(0)->getOperand(1))) { + uint64_t c1 = + cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); + uint64_t c2 = N1C->getZExtValue(); + EVT InnerShiftVT = N0.getOperand(0).getValueType(); + uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); + if (c2 >= OpSizeInBits - InnerShiftSize) { + if (c1 + c2 >= OpSizeInBits) + return DAG.getConstant(0, VT); + return DAG.getNode(ISD::SHL, N0->getDebugLoc(), VT, + DAG.getNode(N0.getOpcode(), N0->getDebugLoc(), VT, + N0.getOperand(0)->getOperand(0)), + DAG.getConstant(c1 + c2, VT)); + } + } + // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or // (srl (and x, (shl -1, c1)), (sub c1, c2)) if (N1C && N0.getOpcode() == ISD::SRL && Added: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll?rev=122355&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll (added) +++ llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll Tue Dec 21 14:10:51 2010 @@ -0,0 +1,10 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; Formerly there were two shifts. + +define i64 @baz(i32 %A) nounwind { +; CHECK: shlq $49, %rax + %tmp1 = shl i32 %A, 17 + %tmp2 = zext i32 %tmp1 to i64 + %tmp3 = shl i64 %tmp2, 32 + ret i64 %tmp3 +} From baldrick at free.fr Tue Dec 21 14:16:05 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 21:16:05 +0100 Subject: [llvm-commits] [llvm] r122336 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <74700AA3-7E30-4B6C-8282-6B2C68481FE9@apple.com> References: <20101221161203.EE25D2A6C12C@llvm.org> <74700AA3-7E30-4B6C-8282-6B2C68481FE9@apple.com> Message-ID: <4D110B05.6090106@free.fr> Hi Chris, >> If an instruction simplifies, try again to simplify any uses of it. This is >> not very important since the pass is only used for testing, but it does make >> it more realistic. Suggested by Frits van Bommel. > > Cool thanks. > >> + // Add all interesting instructions to the worklist. >> + std::set Worklist; > > Using an std::set for this will cause the pass to work nondeterminstically (based on pointer addresses). How about using an std::vector like instcombine? The cost is that deleting an instruction requires scanning (linear time) the vector to see if an instruction is in the worklist multiple times. If you want to get really crazy, you can use a smallptrset + vector to prevent that. Frits pointed this out too. Rather than using a SetVector I went for a queue to get FIFO semantics, as a simple way of approximately visiting instructions before their uses (InstructionSimplify works better if operands are simplified before the instruction). I don't know what the memory usage and speed of queue are like, but it doesn't really matter since this pass is just for testing. Ciao, Duncan. From baldrick at free.fr Tue Dec 21 14:18:14 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 21:18:14 +0100 Subject: [llvm-commits] [llvm] r122343 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> References: <20101221170855.588E82A6C131@llvm.org> <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> Message-ID: <4D110B86.6000300@free.fr> Hi Chris, >> Visit instructions deterministically. Use a FIFO so as to approximately >> visit instructions before their uses, since InstructionSimplify does a >> better job in that case. All this prompted by Frits van Bommel. > > Ok. If you're going to delay deleting instructions, it might be worthwhile to drop their operands so that "dead" instructions don't cause hasOneUse() checks to fail. since InstructionSimplify doesn't pay any attention to uses (it doesn't need to since it only returns existing instructions) this doesn't matter. Ciao, Duncan. From greened at obbligato.org Tue Dec 21 14:21:28 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 14:21:28 -0600 Subject: [llvm-commits] Need A Clang Developer [was: Re: [llvm] r122346 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py] In-Reply-To: <20101221172543.D9C952A6C131@llvm.org> (David Greene's message of "Tue, 21 Dec 2010 17:25:43 -0000") References: <20101221172543.D9C952A6C131@llvm.org> Message-ID: David Greene writes: > Author: greened > Date: Tue Dec 21 11:25:43 2010 > New Revision: 122346 > > URL: http://llvm.org/viewvc/llvm-project?rev=122346&view=rev > Log: > > Revert 122341. It breaks some darwin tests. I found the problem. In clang/test/lit.cfg: config.substitutions.append( (' clang++ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***""")) Since TestRunner.py will use regexp substitution to fix lit issues, "clang++" needs to be escaped as "clang\+\+." I don't believe I have commit permission to cfe. The change will need to be coordinated with the change to lit in the LLVM tree. Who can fix this on the cfe end? -Dave From baldrick at free.fr Tue Dec 21 14:26:59 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Dec 2010 21:26:59 +0100 Subject: [llvm-commits] [llvm] r122354 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/divide-by-constant.ll In-Reply-To: <20101221200620.2580D2A6C12C@llvm.org> References: <20101221200620.2580D2A6C12C@llvm.org> Message-ID: <4D110D93.6010602@free.fr> Hi Dale, > Get the type of a shift from the shift, not from its shift > count operand. These should be the same but apparently are > not always, and this is cleaner anyway. This improves the > code in an existing test. IIRC on x86 the shift amount has to be i8 for the operation to be legal, so might this change cause problems if run after legalization? Ciao, Duncan. From greened at obbligato.org Tue Dec 21 14:28:09 2010 From: greened at obbligato.org (David A. Greene) Date: Tue, 21 Dec 2010 14:28:09 -0600 Subject: [llvm-commits] [llvm] r122341 - in /llvm/trunk: docs/TestingGuide.html test/lit.cfg utils/lit/lit/TestRunner.py In-Reply-To: <4D10FF1B.2020300@fim.uni-passau.de> (Tobias Grosser's message of "Tue, 21 Dec 2010 14:25:15 -0500") References: <20101221165554.21B872A6C12C@llvm.org> <4D10E011.1080201@fim.uni-passau.de> <4D10F949.9080301@fim.uni-passau.de> <4D10FF1B.2020300@fim.uni-passau.de> Message-ID: Tobias Grosser writes: >> Why not? It's a tool name, right? > > Because until now only things prepended with % where replaced. So a > check: > > ; RUN: opt %s -pass -analyze | grep "loop1: opt simple, loop2: opt none" > > Here 'opt' would be replaced, right? Correct. > Or if the tool is not freestanding. Maybe someone is using a shell > subexpression to execute a tool: > > ; RUN: if `opt %s -pass -analyze | grep marker` : ... > > Whould 'opt' be replaced in this line? Yes. The matcher will replace "opt" in any "word" context, ewxcept for some special cases (".opt", "-opt" and "^opt"). > Using %opt instead of opt is probably more obvious, however I believe > this would complicate the test files unnecessarily. Right. A goal of this patch was to not require rewrites of all the tests. > No need to push my changes in. However if you agree it is a good > thing, or at least does not hurt to fix the path order, I would go > ahead and commit. Go for it. It shouldn't hurt anything. -Dave From rafael.espindola at gmail.com Tue Dec 21 14:35:18 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 21 Dec 2010 20:35:18 -0000 Subject: [llvm-commits] [llvm] r122356 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp Message-ID: <20101221203518.ED2622A6C12E@llvm.org> Author: rafael Date: Tue Dec 21 14:35:18 2010 New Revision: 122356 URL: http://llvm.org/viewvc/llvm-project?rev=122356&view=rev Log: Don't relax org or align. They change size as the relaxation happens, but they are not actually relaxed. For example, a section with only alignments will never needs relaxation. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/lib/MC/MCAssembler.cpp Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=122356&r1=122355&r2=122356&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Tue Dec 21 14:35:18 2010 @@ -227,9 +227,6 @@ /// cannot be satisfied in this width then this fragment is ignored. unsigned MaxBytesToEmit; - /// Size - The current estimate of the size. - unsigned Size; - /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead /// of using the provided value. The exact interpretation of this flag is /// target dependent. @@ -240,7 +237,7 @@ unsigned _MaxBytesToEmit, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), Size(0), EmitNops(false) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} /// @name Accessors /// @{ @@ -251,10 +248,6 @@ unsigned getValueSize() const { return ValueSize; } - unsigned getSize() const { return Size; } - - void setSize(unsigned Size_) { Size = Size_; } - unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } bool hasEmitNops() const { return EmitNops; } @@ -312,13 +305,10 @@ /// Value - Value to use for filling bytes. int8_t Value; - /// Size - The current estimate of the size. - unsigned Size; - public: MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) : MCFragment(FT_Org, SD), - Offset(&_Offset), Value(_Value), Size(0) {} + Offset(&_Offset), Value(_Value) {} /// @name Accessors /// @{ @@ -327,9 +317,6 @@ uint8_t getValue() const { return Value; } - unsigned getSize() const { return Size; } - - void setSize(unsigned Size_) { Size = Size_; } /// @} static bool classof(const MCFragment *F) { @@ -715,14 +702,10 @@ bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); - bool RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF); - bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); - bool RelaxAlignment(MCAsmLayout &Layout, MCAlignFragment &DF); - /// FinishLayout - Finalize a layout, including fragment lowering. void FinishLayout(MCAsmLayout &Layout); @@ -732,7 +715,7 @@ public: /// Compute the effective fragment size assuming it is layed out at the given /// \arg SectionAddress and \arg FragmentOffset. - uint64_t ComputeFragmentSize(const MCFragment &F) const; + uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; /// Find the symbol which defines the atom containing the given symbol, or /// null if there is no such symbol. Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122356&r1=122355&r2=122356&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Tue Dec 21 14:35:18 2010 @@ -109,7 +109,7 @@ uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { // The size is the last fragment's end offset. const MCFragment &F = SD->getFragmentList().back(); - return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(F); + return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(*this, F); } uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { @@ -272,7 +272,8 @@ return IsResolved; } -uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F) const { +uint64_t MCAssembler::ComputeFragmentSize(const MCAsmLayout &Layout, + const MCFragment &F) const { switch (F.getKind()) { case MCFragment::FT_Data: return cast(F).getContents().size(); @@ -284,11 +285,29 @@ case MCFragment::FT_LEB: return cast(F).getContents().size(); - case MCFragment::FT_Align: - return cast(F).getSize(); + case MCFragment::FT_Align: { + const MCAlignFragment &AF = cast(F); + unsigned Offset = Layout.getFragmentOffset(&AF); + unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); + if (Size > AF.getMaxBytesToEmit()) + return 0; + return Size; + } - case MCFragment::FT_Org: - return cast(F).getSize(); + case MCFragment::FT_Org: { + MCOrgFragment &OF = cast(F); + int64_t TargetLocation; + if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout)) + report_fatal_error("expected assembly-time absolute expression"); + + // FIXME: We need a way to communicate this error. + uint64_t FragmentOffset = Layout.getFragmentOffset(&OF); + int64_t Size = TargetLocation - FragmentOffset; + if (Size < 0 || Size >= 0x40000000) + report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + + "' (at offset '" + Twine(FragmentOffset) + "')"); + return Size; + } case MCFragment::FT_Dwarf: return cast(F).getContents().size(); @@ -313,7 +332,7 @@ // Compute fragment offset and size. uint64_t Offset = 0; if (Prev) - Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*Prev); + Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*this, *Prev); F->Offset = Offset; LastValidFragment[F->getParent()] = F; @@ -329,7 +348,7 @@ ++stats::EmittedFragments; // FIXME: Embed in fragments instead? - uint64_t FragmentSize = Asm.ComputeFragmentSize(F); + uint64_t FragmentSize = Asm.ComputeFragmentSize(Layout, F); switch (F.getKind()) { case MCFragment::FT_Align: { MCAlignFragment &AF = cast(F); @@ -649,23 +668,6 @@ return true; } -bool MCAssembler::RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF) { - int64_t TargetLocation; - if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout)) - report_fatal_error("expected assembly-time absolute expression"); - - // FIXME: We need a way to communicate this error. - uint64_t FragmentOffset = Layout.getFragmentOffset(&OF); - int64_t Offset = TargetLocation - FragmentOffset; - if (Offset < 0 || Offset >= 0x40000000) - report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + - "' (at offset '" + Twine(FragmentOffset) + "')"); - - unsigned OldSize = OF.getSize(); - OF.setSize(Offset); - return OldSize != OF.getSize(); -} - bool MCAssembler::RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { int64_t Value = 0; uint64_t OldSize = LF.getContents().size(); @@ -696,17 +698,6 @@ return OldSize != Data.size(); } -bool MCAssembler::RelaxAlignment(MCAsmLayout &Layout, - MCAlignFragment &AF) { - unsigned Offset = Layout.getFragmentOffset(&AF); - unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); - if (Size > AF.getMaxBytesToEmit()) - Size = 0; - unsigned OldSize = AF.getSize(); - AF.setSize(Size); - return OldSize != Size; -} - bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { MCFragment *FirstInvalidFragment = NULL; @@ -718,15 +709,9 @@ switch(it2->getKind()) { default: break; - case MCFragment::FT_Align: - relaxedFrag = RelaxAlignment(Layout, *cast(it2)); - break; case MCFragment::FT_Inst: relaxedFrag = RelaxInstruction(Layout, *cast(it2)); break; - case MCFragment::FT_Org: - relaxedFrag = RelaxOrg(Layout, *cast(it2)); - break; case MCFragment::FT_Dwarf: relaxedFrag = RelaxDwarfLineAddr(Layout, *cast(it2)); From aggarwa4 at illinois.edu Tue Dec 21 14:43:12 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 20:43:12 -0000 Subject: [llvm-commits] [poolalloc] r122357 - /poolalloc/trunk/lib/DSA/DSGraph.cpp Message-ID: <20101221204313.006C92A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 14:43:12 2010 New Revision: 122357 URL: http://llvm.org/viewvc/llvm-project?rev=122357&view=rev Log: For any call site that we do not know callees for set it to call all address taken functions. Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122357&r1=122356&r2=122357&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Tue Dec 21 14:43:12 2010 @@ -1620,6 +1620,7 @@ // // Direct calls are easy. We know to where they go. // + if (ii->isDirectCall()) { DCG.insert(ii->getCallSite(), ii->getCalleeFunc()); } else { @@ -1671,7 +1672,6 @@ ii != ee; ++ii) { if (ii->isDirectCall()) continue; - if (ii->getCalleeNode()->isCompleteNode()) continue; CallSite CS = ii->getCallSite(); if (DCG.callee_size(CS) != 0) continue; std::vector MaybeTargets; From aggarwa4 at illinois.edu Tue Dec 21 14:46:03 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 20:46:03 -0000 Subject: [llvm-commits] [poolalloc] r122358 - /poolalloc/trunk/lib/DSA/Local.cpp Message-ID: <20101221204603.20C8F2A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 14:46:02 2010 New Revision: 122358 URL: http://llvm.org/viewvc/llvm-project?rev=122358&view=rev Log: 1. Do not merge call sites in Local. This handles the case where a call site that could be resolved, was getting merged with a call site that could not be resolved because their callees were identical. 2. Better handling of AddressTaken for functions. Modified: poolalloc/trunk/lib/DSA/Local.cpp Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=122358&r1=122357&r2=122358&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Tue Dec 21 14:46:02 2010 @@ -189,7 +189,7 @@ g.computeIntPtrFlags(); // Remove any nodes made dead due to merging... - g.removeDeadNodes(DSGraph::KeepUnreachableGlobals); + //g.removeDeadNodes(DSGraph::KeepUnreachableGlobals); } // GraphBuilder ctor for working on the globals graph @@ -1195,9 +1195,21 @@ GGB.mergeInGlobalInitializer(I); } // Add Functions to the globals graph. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasAddressTaken()) - GGB.mergeFunction(I); + for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI){ + for (Value::use_iterator I = (*FI).use_begin(), E = (*FI).use_end(); I != E; ++I) { + User *U = *I; + if (!isa(U) && !isa(U)){ + if(U->getNumUses() == 0) + continue; + GGB.mergeFunction(FI); + continue; + } + CallSite CS(cast(U)); + if (!CS.isCallee(I)){ + GGB.mergeFunction(FI); + } + } + } } if (hasMagicSections.size()) @@ -1225,7 +1237,7 @@ DEBUG(G->AssertGraphOK()); } - GlobalsGraph->removeTriviallyDeadNodes(); + //GlobalsGraph->removeTriviallyDeadNodes(); GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs); GlobalsGraph->computeExternalFlags(DSGraph::ProcessCallSites); From rafael.espindola at gmail.com Tue Dec 21 14:51:42 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 21 Dec 2010 20:51:42 -0000 Subject: [llvm-commits] [llvm] r122359 - /llvm/trunk/lib/MC/MCExpr.cpp Message-ID: <20101221205142.449662A6C12C@llvm.org> Author: rafael Date: Tue Dec 21 14:51:42 2010 New Revision: 122359 URL: http://llvm.org/viewvc/llvm-project?rev=122359&view=rev Log: Simplify EvaluateAsAbsolute now that EvaluateAsRelocatableImpl does all the folding it can. Modified: llvm/trunk/lib/MC/MCExpr.cpp Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=122359&r1=122358&r2=122359&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Tue Dec 21 14:51:42 2010 @@ -269,27 +269,13 @@ // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us // absolutize differences across sections and that is what the MachO writer // uses Addrs for. - if (!EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs) || - !Value.isAbsolute()) { - // EvaluateAsAbsolute is defined to return the "current value" of - // the expression if we are given a Layout object, even in cases - // when the value is not fixed. - if (Layout) { - Res = Value.getConstant(); - if (Value.getSymA()) { - Res += Layout->getSymbolOffset( - &Layout->getAssembler().getSymbolData(Value.getSymA()->getSymbol())); - } - if (Value.getSymB()) { - Res -= Layout->getSymbolOffset( - &Layout->getAssembler().getSymbolData(Value.getSymB()->getSymbol())); - } - } - return false; - } + bool IsRelocatable = + EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs); + // Record the current value. Res = Value.getConstant(); - return true; + + return IsRelocatable && Value.isAbsolute(); } /// \brief Helper method for \see EvaluateSymbolAdd(). From dalej at apple.com Tue Dec 21 15:22:27 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 21 Dec 2010 21:22:27 -0000 Subject: [llvm-commits] [llvm] r122360 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/divide-by-constant.ll test/CodeGen/X86/x86-64-extend-shift.ll Message-ID: <20101221212227.629652A6C12C@llvm.org> Author: johannes Date: Tue Dec 21 15:22:27 2010 New Revision: 122360 URL: http://llvm.org/viewvc/llvm-project?rev=122360&view=rev Log: Revert 122353-122355 for the moment, they broke stuff. Removed: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122360&r1=122359&r2=122360&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 15:22:27 2010 @@ -2967,37 +2967,11 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 >= OpSizeInBits) + if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); } - - // fold (shl (ext (shl x, c1)), c2) -> (ext (shl x, (add c1, c2))) - // For this to be valid, the second form must not preserve any of the bits - // that are shifted out by the inner shift in the first form. This means - // the outer shift size must be >= the number of bits added by the ext. - // As a corollary, we don't care what kind of ext it is. - if (N1C && (N0.getOpcode() == ISD::ZERO_EXTEND || - N0.getOpcode() == ISD::ANY_EXTEND || - N0.getOpcode() == ISD::SIGN_EXTEND) && - N0.getOperand(0).getOpcode() == ISD::SHL && - isa(N0.getOperand(0)->getOperand(1))) { - uint64_t c1 = - cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); - uint64_t c2 = N1C->getZExtValue(); - EVT InnerShiftVT = N0.getOperand(0).getValueType(); - uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); - if (c2 >= OpSizeInBits - InnerShiftSize) { - if (c1 + c2 >= OpSizeInBits) - return DAG.getConstant(0, VT); - return DAG.getNode(ISD::SHL, N0->getDebugLoc(), VT, - DAG.getNode(N0.getOpcode(), N0->getDebugLoc(), VT, - N0.getOperand(0)->getOperand(0)), - DAG.getConstant(c1 + c2, VT)); - } - } - // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or // (srl (and x, (shl -1, c1)), (sub c1, c2)) if (N1C && N0.getOpcode() == ISD::SRL && @@ -3191,7 +3165,7 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 >= OpSizeInBits) + if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); @@ -3204,7 +3178,7 @@ uint64_t c1 = cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - EVT InnerShiftVT = N0.getOperand(0).getValueType(); + EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType(); uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); // This is only valid if the OpSizeInBits + c1 = size of inner shift. if (c1 + OpSizeInBits == InnerShiftSize) { Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=122360&r1=122359&r2=122360&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original) +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Tue Dec 21 15:22:27 2010 @@ -29,9 +29,9 @@ ret i8 %div ; CHECK: test3: -; CHECK: movzbl 8(%esp), %eax -; CHECK-NEXT: imull $171, %eax, %eax -; CHECK-NEXT: shrl $9, %eax +; CHECK: imull $171, %eax, %eax +; CHECK-NEXT: shrb %ah +; CHECK-NEXT: movzbl %ah, %eax ; CHECK-NEXT: ret } Removed: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll?rev=122359&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll (original) +++ llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll (removed) @@ -1,10 +0,0 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -; Formerly there were two shifts. - -define i64 @baz(i32 %A) nounwind { -; CHECK: shlq $49, %rax - %tmp1 = shl i32 %A, 17 - %tmp2 = zext i32 %tmp1 to i64 - %tmp3 = shl i64 %tmp2, 32 - ret i64 %tmp3 -} From benny.kra at googlemail.com Tue Dec 21 15:30:19 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 21 Dec 2010 21:30:19 -0000 Subject: [llvm-commits] [llvm] r122362 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20101221213019.C2BD82A6C12C@llvm.org> Author: d0k Date: Tue Dec 21 15:30:19 2010 New Revision: 122362 URL: http://llvm.org/viewvc/llvm-project?rev=122362&view=rev Log: GVN's Expression is not POD-like (it contains a SmallVector). Simplify code while at it. 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=122362&r1=122361&r2=122362&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 21 15:30:19 2010 @@ -127,16 +127,9 @@ return false; else if (function != other.function) return false; - else { - if (varargs.size() != other.varargs.size()) - return false; - - for (size_t i = 0; i < varargs.size(); ++i) - if (varargs[i] != other.varargs[i]) - return false; - - return true; - } + else if (varargs != other.varargs) + return false; + return true; } /*bool operator!=(const Expression &other) const { @@ -214,9 +207,6 @@ return LHS == RHS; } }; - -template <> -struct isPodLike { static const bool value = true; }; } From benny.kra at googlemail.com Tue Dec 21 15:41:44 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 21 Dec 2010 21:41:44 -0000 Subject: [llvm-commits] [llvm] r122364 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/conditional-indecrement.ll Message-ID: <20101221214144.536632A6C12C@llvm.org> Author: d0k Date: Tue Dec 21 15:41:44 2010 New Revision: 122364 URL: http://llvm.org/viewvc/llvm-project?rev=122364&view=rev Log: Add some x86 specific dagcombines for conditional increments. (add Y, (sete X, 0)) -> cmp X, 1; adc 0, Y (add Y, (setne X, 0)) -> cmp X, 1; sbb -1, Y (sub (sete X, 0), Y) -> cmp X, 1; sbb 0, Y (sub (setne X, 0), Y) -> cmp X, 1; adc -1, Y for unsigned foo(unsigned a, unsigned b) { if (a == 0) b++; return b; } we now get: foo: cmpl $1, %edi movl %esi, %eax adcl $0, %eax ret instead of: foo: testl %edi, %edi sete %al movzbl %al, %eax addl %esi, %eax ret Added: llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll 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=122364&r1=122363&r2=122364&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 21 15:41:44 2010 @@ -969,6 +969,8 @@ setTargetDAGCombine(ISD::SRL); setTargetDAGCombine(ISD::OR); setTargetDAGCombine(ISD::AND); + setTargetDAGCombine(ISD::ADD); + setTargetDAGCombine(ISD::SUB); setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::ZERO_EXTEND); if (Subtarget->is64Bit()) @@ -11513,6 +11515,44 @@ return SDValue(); } +// fold (add Y, (sete X, 0)) -> adc 0, Y +// (add Y, (setne X, 0)) -> sbb -1, Y +// (sub (sete X, 0), Y) -> sbb 0, Y +// (sub (setne X, 0), Y) -> adc -1, Y +static SDValue OptimizeConditonalInDecrement(SDNode *N, SelectionDAG &DAG) { + DebugLoc DL = N->getDebugLoc(); + + // Look through ZExts. + SDValue Ext = N->getOperand(N->getOpcode() == ISD::SUB ? 1 : 0); + if (Ext.getOpcode() != ISD::ZERO_EXTEND || !Ext.hasOneUse()) + return SDValue(); + + SDValue SetCC = Ext.getOperand(0); + if (SetCC.getOpcode() != X86ISD::SETCC || !SetCC.hasOneUse()) + return SDValue(); + + X86::CondCode CC = (X86::CondCode)SetCC.getConstantOperandVal(0); + if (CC != X86::COND_E && CC != X86::COND_NE) + return SDValue(); + + SDValue Cmp = SetCC.getOperand(1); + if (Cmp.getOpcode() != X86ISD::CMP || !Cmp.hasOneUse() || + !X86::isZeroNode(Cmp.getOperand(1))) + return SDValue(); + + SDValue CmpOp0 = Cmp.getOperand(0); + SDValue NewCmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, CmpOp0, + DAG.getConstant(1, CmpOp0.getValueType())); + + SDValue OtherVal = N->getOperand(N->getOpcode() == ISD::SUB ? 0 : 1); + if (CC == X86::COND_NE) + return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::ADC : X86ISD::SBB, + DL, OtherVal.getValueType(), OtherVal, + DAG.getConstant(-1ULL, OtherVal.getValueType()), NewCmp); + return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::SBB : X86ISD::ADC, + DL, OtherVal.getValueType(), OtherVal, + DAG.getConstant(0, OtherVal.getValueType()), NewCmp); +} SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { @@ -11523,6 +11563,8 @@ return PerformEXTRACT_VECTOR_ELTCombine(N, DAG, *this); case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget); case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI); + case ISD::ADD: + case ISD::SUB: return OptimizeConditonalInDecrement(N, DAG); case X86ISD::ADC: return PerformADCCombine(N, DAG, DCI); case ISD::MUL: return PerformMulCombine(N, DAG, DCI); case ISD::SHL: Added: llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll?rev=122364&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll (added) +++ llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll Tue Dec 21 15:41:44 2010 @@ -0,0 +1,89 @@ +; RUN: llc -march=x86 < %s | FileCheck %s + +define i32 @test1(i32 %a, i32 %b) nounwind readnone { + %not.cmp = icmp ne i32 %a, 0 + %inc = zext i1 %not.cmp to i32 + %retval.0 = add i32 %inc, %b + ret i32 %retval.0 +; CHECK: test1: +; CHECK: cmpl $1 +; CHECK: sbbl $-1 +; CHECK: ret +} + +define i32 @test2(i32 %a, i32 %b) nounwind readnone { + %cmp = icmp eq i32 %a, 0 + %inc = zext i1 %cmp to i32 + %retval.0 = add i32 %inc, %b + ret i32 %retval.0 +; CHECK: test2: +; CHECK: cmpl $1 +; CHECK: adcl $0 +; CHECK: ret +} + +define i32 @test3(i32 %a, i32 %b) nounwind readnone { + %cmp = icmp eq i32 %a, 0 + %inc = zext i1 %cmp to i32 + %retval.0 = add i32 %inc, %b + ret i32 %retval.0 +; CHECK: test3: +; CHECK: cmpl $1 +; CHECK: adcl $0 +; CHECK: ret +} + +define i32 @test4(i32 %a, i32 %b) nounwind readnone { + %not.cmp = icmp ne i32 %a, 0 + %inc = zext i1 %not.cmp to i32 + %retval.0 = add i32 %inc, %b + ret i32 %retval.0 +; CHECK: test4: +; CHECK: cmpl $1 +; CHECK: sbbl $-1 +; CHECK: ret +} + +define i32 @test5(i32 %a, i32 %b) nounwind readnone { + %not.cmp = icmp ne i32 %a, 0 + %inc = zext i1 %not.cmp to i32 + %retval.0 = sub i32 %b, %inc + ret i32 %retval.0 +; CHECK: test5: +; CHECK: cmpl $1 +; CHECK: adcl $-1 +; CHECK: ret +} + +define i32 @test6(i32 %a, i32 %b) nounwind readnone { + %cmp = icmp eq i32 %a, 0 + %inc = zext i1 %cmp to i32 + %retval.0 = sub i32 %b, %inc + ret i32 %retval.0 +; CHECK: test6: +; CHECK: cmpl $1 +; CHECK: sbbl $0 +; CHECK: ret +} + +define i32 @test7(i32 %a, i32 %b) nounwind readnone { + %cmp = icmp eq i32 %a, 0 + %inc = zext i1 %cmp to i32 + %retval.0 = sub i32 %b, %inc + ret i32 %retval.0 +; CHECK: test7: +; CHECK: cmpl $1 +; CHECK: sbbl $0 +; CHECK: ret +} + +define i32 @test8(i32 %a, i32 %b) nounwind readnone { + %not.cmp = icmp ne i32 %a, 0 + %inc = zext i1 %not.cmp to i32 + %retval.0 = sub i32 %b, %inc + ret i32 %retval.0 +; CHECK: test8: +; CHECK: cmpl $1 +; CHECK: adcl $-1 +; CHECK: ret +} From dalej at apple.com Tue Dec 21 15:55:50 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 21 Dec 2010 21:55:50 -0000 Subject: [llvm-commits] [llvm] r122366 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/divide-by-constant.ll test/CodeGen/X86/x86-64-extend-shift.ll Message-ID: <20101221215550.494322A6C12C@llvm.org> Author: johannes Date: Tue Dec 21 15:55:50 2010 New Revision: 122366 URL: http://llvm.org/viewvc/llvm-project?rev=122366&view=rev Log: Reapply 122353-122355 with fixes. 122354 was wrong; the shift type was needed one place, the shift count type another. The transform in 123555 had the same problem. Added: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122366&r1=122365&r2=122366&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 21 15:55:50 2010 @@ -2967,11 +2967,37 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 > OpSizeInBits) + if (c1 + c2 >= OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); } + + // fold (shl (ext (shl x, c1)), c2) -> (ext (shl x, (add c1, c2))) + // For this to be valid, the second form must not preserve any of the bits + // that are shifted out by the inner shift in the first form. This means + // the outer shift size must be >= the number of bits added by the ext. + // As a corollary, we don't care what kind of ext it is. + if (N1C && (N0.getOpcode() == ISD::ZERO_EXTEND || + N0.getOpcode() == ISD::ANY_EXTEND || + N0.getOpcode() == ISD::SIGN_EXTEND) && + N0.getOperand(0).getOpcode() == ISD::SHL && + isa(N0.getOperand(0)->getOperand(1))) { + uint64_t c1 = + cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); + uint64_t c2 = N1C->getZExtValue(); + EVT InnerShiftVT = N0.getOperand(0).getValueType(); + uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); + if (c2 >= OpSizeInBits - InnerShiftSize) { + if (c1 + c2 >= OpSizeInBits) + return DAG.getConstant(0, VT); + return DAG.getNode(ISD::SHL, N0->getDebugLoc(), VT, + DAG.getNode(N0.getOpcode(), N0->getDebugLoc(), VT, + N0.getOperand(0)->getOperand(0)), + DAG.getConstant(c1 + c2, N1.getValueType())); + } + } + // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or // (srl (and x, (shl -1, c1)), (sub c1, c2)) if (N1C && N0.getOpcode() == ISD::SRL && @@ -3165,7 +3191,7 @@ N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - if (c1 + c2 > OpSizeInBits) + if (c1 + c2 >= OpSizeInBits) return DAG.getConstant(0, VT); return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); @@ -3178,7 +3204,8 @@ uint64_t c1 = cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType(); + EVT InnerShiftVT = N0.getOperand(0).getValueType(); + EVT ShiftCountVT = N0.getOperand(0)->getOperand(1).getValueType(); uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits(); // This is only valid if the OpSizeInBits + c1 = size of inner shift. if (c1 + OpSizeInBits == InnerShiftSize) { @@ -3187,7 +3214,7 @@ return DAG.getNode(ISD::TRUNCATE, N0->getDebugLoc(), VT, DAG.getNode(ISD::SRL, N0->getDebugLoc(), InnerShiftVT, N0.getOperand(0)->getOperand(0), - DAG.getConstant(c1 + c2, InnerShiftVT))); + DAG.getConstant(c1 + c2, ShiftCountVT))); } } Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=122366&r1=122365&r2=122366&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original) +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Tue Dec 21 15:55:50 2010 @@ -29,9 +29,9 @@ ret i8 %div ; CHECK: test3: -; CHECK: imull $171, %eax, %eax -; CHECK-NEXT: shrb %ah -; CHECK-NEXT: movzbl %ah, %eax +; CHECK: movzbl 8(%esp), %eax +; CHECK-NEXT: imull $171, %eax, %eax +; CHECK-NEXT: shrl $9, %eax ; CHECK-NEXT: ret } Added: llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll?rev=122366&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll (added) +++ llvm/trunk/test/CodeGen/X86/x86-64-extend-shift.ll Tue Dec 21 15:55:50 2010 @@ -0,0 +1,10 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; Formerly there were two shifts. + +define i64 @baz(i32 %A) nounwind { +; CHECK: shlq $49, %rax + %tmp1 = shl i32 %A, 17 + %tmp2 = zext i32 %tmp1 to i64 + %tmp3 = shl i64 %tmp2, 32 + ret i64 %tmp3 +} From atrick at apple.com Tue Dec 21 16:25:04 2010 From: atrick at apple.com (Andrew Trick) Date: Tue, 21 Dec 2010 22:25:04 -0000 Subject: [llvm-commits] [llvm] r122368 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101221222504.E58CE2A6C12C@llvm.org> Author: atrick Date: Tue Dec 21 16:25:04 2010 New Revision: 122368 URL: http://llvm.org/viewvc/llvm-project?rev=122368&view=rev Log: whitespace Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122368&r1=122367&r2=122368&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Dec 21 16:25:04 2010 @@ -193,7 +193,7 @@ << " '" << BB->getName() << "' **********\n"); NumLiveRegs = 0; - LiveRegDefs.resize(TRI->getNumRegs(), NULL); + LiveRegDefs.resize(TRI->getNumRegs(), NULL); LiveRegCycles.resize(TRI->getNumRegs(), 0); // Build the scheduling graph. @@ -204,13 +204,13 @@ Topo.InitDAGTopologicalSorting(); AvailableQueue->initNodes(SUnits); - + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) ListScheduleBottomUp(); else ListScheduleTopDown(); - + AvailableQueue->releaseState(); } @@ -254,7 +254,7 @@ ReleasePred(SU, &*I); if (I->isAssignedRegDep()) { // This is a physical register dependency and it's impossible or - // expensive to copy the register. Make sure nothing that can + // expensive to copy the register. Make sure nothing that can // clobber the register is scheduled between the predecessor and // this node. if (!LiveRegDefs[I->getReg()]) { @@ -307,7 +307,7 @@ /// CapturePred - This does the opposite of ReleasePred. Since SU is being /// unscheduled, incrcease the succ left count of its predecessors. Remove /// them from AvailableQueue if necessary. -void ScheduleDAGRRList::CapturePred(SDep *PredEdge) { +void ScheduleDAGRRList::CapturePred(SDep *PredEdge) { SUnit *PredSU = PredEdge->getSUnit(); if (PredSU->isAvailable) { PredSU->isAvailable = false; @@ -447,7 +447,7 @@ SUnit *NewSU = CreateNewSUnit(N); assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NewSU->NodeNum); - + const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); for (unsigned i = 0; i != TID.getNumOperands(); ++i) { if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { @@ -517,7 +517,7 @@ D.setSUnit(LoadSU); AddPred(SuccDep, D); } - } + } // Add a data dependency to reflect that NewSU reads the value defined // by LoadSU. @@ -702,21 +702,21 @@ for (const unsigned *Reg = TID.ImplicitDefs; *Reg; ++Reg) CheckForLiveRegDef(SU, *Reg, LiveRegDefs, RegAdded, LRegs, TRI); } - - + + // Okay, we now know all of the live registers that are defined by an // immediate predecessor. It is ok to kill these registers if we are also // using it. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isAssignedRegDep() && + if (I->isAssignedRegDep() && LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) { unsigned Reg = I->getReg(); if (RegAdded.erase(Reg)) LRegs.erase(std::find(LRegs.begin(), LRegs.end(), Reg)); } } - + return !LRegs.empty(); } @@ -867,7 +867,7 @@ // Reverse the order if it is bottom up. std::reverse(Sequence.begin(), Sequence.end()); - + #ifndef NDEBUG VerifySchedule(isBottomUp); #endif @@ -944,19 +944,19 @@ SUnits[i].isAvailable = true; } } - + // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. Sequence.reserve(SUnits.size()); while (!AvailableQueue->empty()) { SUnit *CurSU = AvailableQueue->pop(); - + if (CurSU) ScheduleNodeTopDown(CurSU, CurCycle); ++CurCycle; AvailableQueue->setCurCycle(CurCycle); } - + #ifndef NDEBUG VerifySchedule(isBottomUp); #endif @@ -969,18 +969,18 @@ // // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers // to reduce register pressure. -// +// namespace { template class RegReductionPriorityQueue; - + /// bu_ls_rr_sort - Priority function for bottom up register pressure // reduction scheduler. struct bu_ls_rr_sort : public std::binary_function { RegReductionPriorityQueue *SPQ; bu_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} - + bool operator()(const SUnit* left, const SUnit* right) const; }; @@ -990,7 +990,7 @@ RegReductionPriorityQueue *SPQ; td_ls_rr_sort(RegReductionPriorityQueue *spq) : SPQ(spq) {} td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} - + bool operator()(const SUnit* left, const SUnit* right) const; }; @@ -1001,7 +1001,7 @@ : SPQ(spq) {} src_ls_rr_sort(const src_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} - + bool operator()(const SUnit* left, const SUnit* right) const; }; @@ -1054,7 +1054,7 @@ if (SethiUllmanNumber == 0) SethiUllmanNumber = 1; - + return SethiUllmanNumber; } @@ -1106,7 +1106,7 @@ RegLimit[(*I)->getID()] = tli->getRegPressureLimit(*I, MF); } } - + void initNodes(std::vector &sunits) { SUnits = &sunits; // Add pseudo dependency edges for two-address nodes. @@ -1167,7 +1167,7 @@ } bool empty() const { return Queue.empty(); } - + void push(SUnit *U) { assert(!U->NodeQueueId && "Node in the queue already"); U->NodeQueueId = ++CurQueueId; @@ -1231,7 +1231,7 @@ // class to the point where it would cause spills. if ((RegPressure[RCId] + Cost) >= RegLimit[RCId]) return true; - continue; + continue; } else if (POpc == TargetOpcode::INSERT_SUBREG || POpc == TargetOpcode::SUBREG_TO_REG) { EVT VT = PN->getValueType(0); @@ -1303,7 +1303,7 @@ EVT VT = PN->getOperand(0).getValueType(); unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); RegPressure[RCId] += TLI->getRepRegClassCostFor(VT); - continue; + continue; } else if (POpc == TargetOpcode::INSERT_SUBREG || POpc == TargetOpcode::SUBREG_TO_REG) { EVT VT = PN->getValueType(0); @@ -1382,7 +1382,7 @@ EVT VT = PN->getOperand(0).getValueType(); unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); RegPressure[RCId] += TLI->getRepRegClassCostFor(VT); - continue; + continue; } else if (POpc == TargetOpcode::INSERT_SUBREG || POpc == TargetOpcode::SUBREG_TO_REG) { EVT VT = PN->getValueType(0); @@ -1422,8 +1422,8 @@ dumpRegPressure(); } - void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { - scheduleDAG = scheduleDag; + void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { + scheduleDAG = scheduleDag; } void dumpRegPressure() const { @@ -1570,11 +1570,11 @@ if (left->getHeight() != right->getHeight()) return left->getHeight() > right->getHeight(); - + if (left->getDepth() != right->getDepth()) return left->getDepth() < right->getDepth(); - assert(left->NodeQueueId && right->NodeQueueId && + assert(left->NodeQueueId && right->NodeQueueId && "NodeQueueId cannot be zero"); return (left->NodeQueueId > right->NodeQueueId); } @@ -1944,7 +1944,7 @@ template void RegReductionPriorityQueue::CalculateSethiUllmanNumbers() { SethiUllmanNumbers.assign(SUnits->size(), 0); - + for (unsigned i = 0, e = SUnits->size(); i != e; ++i) CalcNodeSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); } @@ -1952,7 +1952,7 @@ /// LimitedSumOfUnscheduledPredsOfSuccs - Compute the sum of the unscheduled /// predecessors of the successors of the SUnit SU. Stop when the provided /// limit is exceeded. -static unsigned LimitedSumOfUnscheduledPredsOfSuccs(const SUnit *SU, +static unsigned LimitedSumOfUnscheduledPredsOfSuccs(const SUnit *SU, unsigned Limit) { unsigned Sum = 0; for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); @@ -2004,7 +2004,7 @@ if (left->NumSuccsLeft != right->NumSuccsLeft) return left->NumSuccsLeft > right->NumSuccsLeft; - assert(left->NodeQueueId && right->NodeQueueId && + assert(left->NodeQueueId && right->NodeQueueId && "NodeQueueId cannot be zero"); return (left->NodeQueueId > right->NodeQueueId); } @@ -2018,12 +2018,12 @@ const TargetMachine &TM = IS->TM; const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); - + BURegReductionPriorityQueue *PQ = new BURegReductionPriorityQueue(*IS->MF, false, TII, TRI, 0); ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, false, PQ); PQ->setScheduleDAG(SD); - return SD; + return SD; } llvm::ScheduleDAGSDNodes * @@ -2031,7 +2031,7 @@ const TargetMachine &TM = IS->TM; const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); - + TDRegReductionPriorityQueue *PQ = new TDRegReductionPriorityQueue(*IS->MF, false, TII, TRI, 0); ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, false, PQ); @@ -2044,12 +2044,12 @@ const TargetMachine &TM = IS->TM; const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); - + SrcRegReductionPriorityQueue *PQ = new SrcRegReductionPriorityQueue(*IS->MF, false, TII, TRI, 0); ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, false, PQ); PQ->setScheduleDAG(SD); - return SD; + return SD; } llvm::ScheduleDAGSDNodes * @@ -2058,12 +2058,12 @@ const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); const TargetLowering *TLI = &IS->getTargetLowering(); - + HybridBURRPriorityQueue *PQ = new HybridBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); PQ->setScheduleDAG(SD); - return SD; + return SD; } llvm::ScheduleDAGSDNodes * @@ -2072,10 +2072,10 @@ const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterInfo *TRI = TM.getRegisterInfo(); const TargetLowering *TLI = &IS->getTargetLowering(); - + ILPBURRPriorityQueue *PQ = new ILPBURRPriorityQueue(*IS->MF, true, TII, TRI, TLI); ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ); PQ->setScheduleDAG(SD); - return SD; + return SD; } From atrick at apple.com Tue Dec 21 16:27:44 2010 From: atrick at apple.com (Andrew Trick) Date: Tue, 21 Dec 2010 22:27:44 -0000 Subject: [llvm-commits] [llvm] r122370 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101221222744.B008D2A6C12C@llvm.org> Author: atrick Date: Tue Dec 21 16:27:44 2010 New Revision: 122370 URL: http://llvm.org/viewvc/llvm-project?rev=122370&view=rev Log: In DelayForLiveRegsBottomUp, handle instructions that read and write the same physical register. Simplifies the fix from the previous checkin r122211. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122370&r1=122369&r2=122370&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Dec 21 16:27:44 2010 @@ -660,9 +660,12 @@ SmallSet RegAdded; // If this node would clobber any "live" register, then it's not ready. + // + // If SU is the currently live definition of the same register that it uses, + // then we are free to schedule it. for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { - if (I->isAssignedRegDep()) + if (I->isAssignedRegDep() && LiveRegDefs[I->getReg()] != SU) CheckForLiveRegDef(I->getSUnit(), I->getReg(), LiveRegDefs, RegAdded, LRegs, TRI); } @@ -703,20 +706,6 @@ CheckForLiveRegDef(SU, *Reg, LiveRegDefs, RegAdded, LRegs, TRI); } - - // Okay, we now know all of the live registers that are defined by an - // immediate predecessor. It is ok to kill these registers if we are also - // using it. - for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); - I != E; ++I) { - if (I->isAssignedRegDep() && - LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) { - unsigned Reg = I->getReg(); - if (RegAdded.erase(Reg)) - LRegs.erase(std::find(LRegs.begin(), LRegs.end(), Reg)); - } - } - return !LRegs.empty(); } From gohman at apple.com Tue Dec 21 16:32:37 2010 From: gohman at apple.com (Dan Gohman) Date: Tue, 21 Dec 2010 14:32:37 -0800 Subject: [llvm-commits] [llvm] r122170 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/critical-edge-split-2.ll In-Reply-To: <7D6F7CDD-0766-4A3C-A58D-29FDD92DD038@apple.com> References: <20101219045857.D53B42A6C12C@llvm.org> <17985F09-30C1-417A-A29C-65F2BE81C797@2pi.dk> <4C148651-8777-4184-BC9E-EE746893C005@nondot.org> <5DB97C7B-B207-421E-A7F7-903A9285FECF@apple.com> <7D6F7CDD-0766-4A3C-A58D-29FDD92DD038@apple.com> Message-ID: <139D700C-8AB4-4D13-8B47-CFE320317126@apple.com> On Dec 20, 2010, at 6:12 PM, Chris Lattner wrote: > On Dec 20, 2010, at 10:54 AM, Dan Gohman wrote: >>>>> fix PR8642: if a critical edge has a PHI value that can trap, >>>>> isel is *required* to split the edge. PHI values get evaluated >>>>> on the edge, not in their predecessor block. >>>> >>>> What happens if the predecessor block is terminated by indirectbr, so the edge can't be split? >>> >>> Huh, good question... I don't see a really robust answer... >> >> Why does LLVM need the concept of trapping constants? Prohibiting >> them would be a robust answer, at seemingly little practical cost. > > It's a good question: the only real answer that I have is that ConstantExpr::get() is our current "constant folding API". Perhaps that's a bug, not a feature. What do you think about eliminating div and rem as valid constant exprs? It'd probably be ok. An alternative would be to permit div and rem constants only when the denominator is a ConstantInt. Dan From resistor at mac.com Tue Dec 21 16:31:24 2010 From: resistor at mac.com (Owen Anderson) Date: Tue, 21 Dec 2010 22:31:24 -0000 Subject: [llvm-commits] [llvm] r122371 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20101221223124.970FF2A6C12C@llvm.org> Author: resistor Date: Tue Dec 21 16:31:24 2010 New Revision: 122371 URL: http://llvm.org/viewvc/llvm-project?rev=122371&view=rev Log: Remove dead code. 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=122371&r1=122370&r2=122371&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 21 16:31:24 2010 @@ -637,15 +637,6 @@ //===----------------------------------------------------------------------===// namespace { - struct ValueNumberScope { - ValueNumberScope* parent; - DenseMap table; - - ValueNumberScope(ValueNumberScope* p) : parent(p) { } - }; -} - -namespace { class GVN : public FunctionPass { bool runOnFunction(Function &F); From aggarwa4 at illinois.edu Tue Dec 21 17:22:34 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 23:22:34 -0000 Subject: [llvm-commits] [poolalloc] r122372 - /poolalloc/trunk/lib/DSA/Local.cpp Message-ID: <20101221232235.03BF92A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 17:22:34 2010 New Revision: 122372 URL: http://llvm.org/viewvc/llvm-project?rev=122372&view=rev Log: Make handling of address taken values a separate pass. Leave for later. Modified: poolalloc/trunk/lib/DSA/Local.cpp Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=122372&r1=122371&r2=122372&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Tue Dec 21 17:22:34 2010 @@ -1195,19 +1195,10 @@ GGB.mergeInGlobalInitializer(I); } // Add Functions to the globals graph. + // FIXME: Write a separate pass to handle address taken property better. for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI){ - for (Value::use_iterator I = (*FI).use_begin(), E = (*FI).use_end(); I != E; ++I) { - User *U = *I; - if (!isa(U) && !isa(U)){ - if(U->getNumUses() == 0) - continue; + if(FI->hasAddressTaken()) { GGB.mergeFunction(FI); - continue; - } - CallSite CS(cast(U)); - if (!CS.isCallee(I)){ - GGB.mergeFunction(FI); - } } } } From aggarwa4 at illinois.edu Tue Dec 21 17:26:30 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 23:26:30 -0000 Subject: [llvm-commits] [poolalloc] r122373 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Message-ID: <20101221232630.479D82A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 17:26:30 2010 New Revision: 122373 URL: http://llvm.org/viewvc/llvm-project?rev=122373&view=rev Log: Calculate complete callgraph at end of BU too. For clients that use results of BU, not EQBU. Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=122373&r1=122372&r2=122373&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Dec 21 17:26:30 2010 @@ -112,6 +112,12 @@ Graph->computeIntPtrFlags(); } } + for (Module::iterator F = M.begin(); F != M.end(); ++F) { + if (!(F->isDeclaration())){ + DSGraph *Graph = getOrCreateGraph(F); + Graph->buildCompleteCallGraph(callgraph, GlobalFunctionList, filterCallees); + } + } NumCallEdges += callgraph.size(); From aggarwa4 at illinois.edu Tue Dec 21 17:27:23 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 23:27:23 -0000 Subject: [llvm-commits] [poolalloc] r122374 - /poolalloc/trunk/lib/DSA/DSGraph.cpp Message-ID: <20101221232723.0DC722A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 17:27:22 2010 New Revision: 122374 URL: http://llvm.org/viewvc/llvm-project?rev=122374&view=rev Log: Added a statistic, to know the number of unresolved indirect call sites. Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122374&r1=122373&r2=122374&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Tue Dec 21 17:27:22 2010 @@ -39,11 +39,12 @@ #define COLLAPSE_ARRAYS_AGGRESSIVELY 0 namespace { - STATISTIC (NumCallNodesMerged , "Number of call nodes merged"); - STATISTIC (NumDNE , "Number of nodes removed by reachability"); - STATISTIC (NumTrivialDNE , "Number of nodes trivially removed"); - STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed"); - STATISTIC (NumFiltered , "Number of calls filtered"); + STATISTIC (NumCallNodesMerged , "Number of call nodes merged"); + STATISTIC (NumDNE , "Number of nodes removed by reachability"); + STATISTIC (NumTrivialDNE , "Number of nodes trivially removed"); + STATISTIC (NumTrivialGlobalDNE , "Number of globals trivially removed"); + STATISTIC (NumFiltered , "Number of calls filtered"); + STATISTIC (NumIndirectIncompleteCallSites , "Number of calls that could not be resolved"); static cl::opt noDSACallConv("dsa-no-filter-callcc", cl::desc("Don't filter call sites based on calling convention."), cl::Hidden, @@ -1678,6 +1679,7 @@ MaybeTargets.assign(GlobalFunctionList.begin(), GlobalFunctionList.end()); DCG.insert(CS, 0); + NumIndirectIncompleteCallSites++; // // Add to the call graph only function targets that have well-defined // behavior using LLVM semantics. From aggarwa4 at illinois.edu Tue Dec 21 17:27:56 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 23:27:56 -0000 Subject: [llvm-commits] [poolalloc] r122375 - /poolalloc/trunk/test/TEST.poolalloc.report Message-ID: <20101221232756.1142D2A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 17:27:55 2010 New Revision: 122375 URL: http://llvm.org/viewvc/llvm-project?rev=122375&view=rev Log: Also report how many call sites could not be resolved. Modified: poolalloc/trunk/test/TEST.poolalloc.report Modified: poolalloc/trunk/test/TEST.poolalloc.report URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.report?rev=122375&r1=122374&r2=122375&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.poolalloc.report (original) +++ poolalloc/trunk/test/TEST.poolalloc.report Tue Dec 21 17:27:55 2010 @@ -102,6 +102,7 @@ ["PFE", '([0-9]+).*Number of poolfree.s elided'], ["NumArgs", '([0-9]+).*Number of function arguments added'], ["MaxArgs", '([0-9]+).*Maximum function arguments added'], + ["UnresolvedCalls",'([0-9]+).*Number of calls that could not be resolved'], #["Nonprofit", '([0-9]+).*Number of DSNodes not profitable'], [] ); From aggarwa4 at illinois.edu Tue Dec 21 17:32:04 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 21 Dec 2010 23:32:04 -0000 Subject: [llvm-commits] [poolalloc] r122376 - /poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <20101221233204.103022A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 17:32:03 2010 New Revision: 122376 URL: http://llvm.org/viewvc/llvm-project?rev=122376&view=rev Log: Do not pass pool args to functions that are in the same equivalence class as an external function. Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=122376&r1=122375&r2=122376&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Tue Dec 21 17:32:03 2010 @@ -664,6 +664,7 @@ for (DSCallGraph::callee_key_iterator ii = callgraph.key_begin(), ee = callgraph.key_end(); ii != ee; ++ii) { bool isIndirect = ((*ii).getCalledFunction() == NULL); + bool externFunctionFound = false; if (isIndirect) { std::vector Functions; @@ -675,7 +676,11 @@ sccee = callgraph.scc_end(F); for(;sccii != sccee; ++sccii) { DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii)); - if (I != SM.end() && !((*sccii)->isDeclaration())) { + if (I != SM.end()) { + if ((*sccii)->isDeclaration()) { + externFunctionFound = true; + break; + } Functions.push_back (*sccii); } } @@ -688,14 +693,36 @@ sccee = callgraph.scc_end(F1); for(;sccii != sccee; ++sccii) { DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii)); - if (I != SM.end() && !((*sccii)->isDeclaration())) { + if (I != SM.end()) { + if ((*sccii)->isDeclaration()) { + externFunctionFound = true; + break; + } Functions.push_back (*sccii); } } - - FindFunctionPoolArgs (Functions); + if(!externFunctionFound) + FindFunctionPoolArgs (Functions); + else { + // For functions that are in the same equivalence class as an + // external function, we cannot pass pool args. Because we + // cannot know which function the call site calls, the + // internal function or the external ones. + // FIXME: Solve this by devirtualizing the call site. + for (unsigned index = 0; index < Functions.size(); ++index) { + Function * F = (Function *) Functions[index]; + if (FunctionInfo.find (F) != FunctionInfo.end()) { + FuncInfo & FI = FunctionInfo.find(F)->second; + assert(FI.ArgNodes.size() == 0); + continue; + } + FunctionInfo.insert(std::make_pair(F, FuncInfo(*F))).first->second; + } + } + } } + /* EquivalenceClasses & GlobalECs = Graphs->getGlobalECs(); EquivalenceClasses::iterator EQSI = GlobalECs.begin(); From matthewbg at google.com Tue Dec 21 17:43:23 2010 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Tue, 21 Dec 2010 23:43:23 -0000 Subject: [llvm-commits] [llvm] r122377 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101221234323.AC6272A6C12C@llvm.org> Author: matthewbg Date: Tue Dec 21 17:43:23 2010 New Revision: 122377 URL: http://llvm.org/viewvc/llvm-project?rev=122377&view=rev Log: GCC objects to the two sides of a conditional expression having different enum types, but they're just getting converted to unsigned anyway, so cast first (and ask questions later). Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122377&r1=122376&r2=122377&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Tue Dec 21 17:43:23 2010 @@ -765,8 +765,8 @@ // Note that there is no longer any semantic difference between these two // relocation types from the linkers point of view, this is done solely // for pedantic compatibility with 'as'. - Type = A_SD->isExternal() ? macho::RIT_Difference : - macho::RIT_Generic_LocalDifference; + Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference : + (unsigned)macho::RIT_Generic_LocalDifference; Value2 = getSymbolAddress(B_SD, Layout); FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); } From resistor at mac.com Tue Dec 21 17:54:34 2010 From: resistor at mac.com (Owen Anderson) Date: Tue, 21 Dec 2010 23:54:34 -0000 Subject: [llvm-commits] [llvm] r122378 - in /llvm/trunk: lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/condprop.ll Message-ID: <20101221235434.7E7B02A6C12C@llvm.org> Author: resistor Date: Tue Dec 21 17:54:34 2010 New Revision: 122378 URL: http://llvm.org/viewvc/llvm-project?rev=122378&view=rev Log: Give GVN back the ability to perform simple conditional propagation on conditional branch values. I still think that LVI should be handling this, but that capability is some ways off in the future, and this matters for some significant benchmarks. Added: llvm/trunk/test/Transforms/GVN/condprop.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=122378&r1=122377&r2=122378&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 21 17:54:34 2010 @@ -657,46 +657,52 @@ /// NumberTable - A mapping from value numers to lists of Value*'s that /// have that value number. Use lookupNumber to query it. - DenseMap > NumberTable; + struct NumberTableEntry { + Value *Val; + BasicBlock *BB; + NumberTableEntry *Next; + }; + DenseMap NumberTable; BumpPtrAllocator TableAllocator; /// insert_table - Push a new Value to the NumberTable onto the list for /// its value number. - void insert_table(uint32_t N, Value *V) { - std::pair& Curr = NumberTable[N]; - if (!Curr.first) { - Curr.first = V; + void insert_table(uint32_t N, Value *V, BasicBlock *BB) { + NumberTableEntry& Curr = NumberTable[N]; + if (!Curr.Val) { + Curr.Val = V; + Curr.BB = BB; return; } - std::pair* Node = - TableAllocator.Allocate >(); - Node->first = V; - Node->second = Curr.second; - Curr.second = Node; + NumberTableEntry* Node = TableAllocator.Allocate(); + Node->Val = V; + Node->BB = BB; + Node->Next = Curr.Next; + Curr.Next = Node; } /// erase_table - Scan the list of values corresponding to a given value /// number, and remove the given value if encountered. - void erase_table(uint32_t N, Value *V) { - std::pair* Prev = 0; - std::pair* Curr = &NumberTable[N]; + void erase_table(uint32_t N, Value *V, BasicBlock *BB) { + NumberTableEntry* Prev = 0; + NumberTableEntry* Curr = &NumberTable[N]; - while (Curr->first != V) { + while (Curr->Val != V || Curr->BB != BB) { Prev = Curr; - Curr = static_cast*>(Curr->second); + Curr = Curr->Next; } if (Prev) { - Prev->second = Curr->second; + Prev->Next = Curr->Next; } else { - if (!Curr->second) { - Curr->first = 0; + if (!Curr->Next) { + Curr->Val = 0; + Curr->BB = 0; } else { - std::pair* Next = - static_cast*>(Curr->second); - Curr->first = Next->first; - Curr->second = Next->second; + NumberTableEntry* Next = Curr->Next; + Curr->Val = Next->Val; + Curr->BB = Next->BB; } } } @@ -1837,28 +1843,26 @@ // question. This is fast because dominator tree queries consist of only // a few comparisons of DFS numbers. Value *GVN::lookupNumber(BasicBlock *BB, uint32_t num) { - std::pair Vals = NumberTable[num]; - if (!Vals.first) return 0; - Instruction *Inst = dyn_cast(Vals.first); - if (!Inst) return Vals.first; - BasicBlock *Parent = Inst->getParent(); - if (DT->dominates(Parent, BB)) - return Inst; + NumberTableEntry Vals = NumberTable[num]; + if (!Vals.Val) return 0; - std::pair* Next = - static_cast*>(Vals.second); + Value *Val = 0; + if (DT->dominates(Vals.BB, BB)) { + Val = Vals.Val; + if (isa(Val)) return Val; + } + + NumberTableEntry* Next = Vals.Next; while (Next) { - Instruction *CurrInst = dyn_cast(Next->first); - if (!CurrInst) return Next->first; - - BasicBlock *Parent = CurrInst->getParent(); - if (DT->dominates(Parent, BB)) - return CurrInst; + if (DT->dominates(Next->BB, BB)) { + if (isa(Next->Val)) return Next->Val; + if (!Val) Val = Next->Val; + } - Next = static_cast*>(Next->second); + Next = Next->Next; } - return 0; + return Val; } @@ -1888,7 +1892,7 @@ if (!Changed) { unsigned Num = VN.lookup_or_add(LI); - insert_table(Num, LI); + insert_table(Num, LI, LI->getParent()); } return Changed; @@ -1897,10 +1901,36 @@ uint32_t NextNum = VN.getNextUnusedValueNumber(); unsigned Num = VN.lookup_or_add(I); + // For conditions branches, we can perform simple conditional propagation on + // the condition value itself. + if (BranchInst *BI = dyn_cast(I)) { + insert_table(Num, I, I->getParent()); + + if (!BI->isConditional() || isa(BI->getCondition())) + return false; + + Value *BranchCond = BI->getCondition(); + uint32_t CondVN = VN.lookup_or_add(BranchCond); + + BasicBlock *TrueSucc = BI->getSuccessor(0); + BasicBlock *FalseSucc = BI->getSuccessor(1); + + if (TrueSucc->getSinglePredecessor()) + insert_table(CondVN, + ConstantInt::getTrue(TrueSucc->getContext()), + TrueSucc); + if (FalseSucc->getSinglePredecessor()) + insert_table(CondVN, + ConstantInt::getFalse(TrueSucc->getContext()), + FalseSucc); + + return false; + } + // Allocations are always uniquely numbered, so we can save time and memory // by fast failing them. if (isa(I) || isa(I) || isa(I)) { - insert_table(Num, I); + insert_table(Num, I, I->getParent()); return false; } @@ -1908,7 +1938,7 @@ // need to do a lookup to see if the number already exists // somewhere in the domtree: it can't! if (Num == NextNum) { - insert_table(Num, I); + insert_table(Num, I, I->getParent()); return false; } @@ -1917,7 +1947,7 @@ Value *repl = lookupNumber(I->getParent(), Num); if (repl == 0) { // Failure, just remember this instance for future use. - insert_table(Num, I); + insert_table(Num, I, I->getParent()); return false; } @@ -2144,7 +2174,7 @@ ++NumGVNPRE; // Update the availability map to include the new instruction. - insert_table(ValNo, PREInstr); + insert_table(ValNo, PREInstr, PREPred); // Create a PHI to make the value available in this block. PHINode* Phi = PHINode::Create(CurInst->getType(), @@ -2157,13 +2187,13 @@ } VN.add(Phi, ValNo); - insert_table(ValNo, Phi); + insert_table(ValNo, Phi, CurrentBlock); CurInst->replaceAllUsesWith(Phi); if (MD && Phi->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(Phi); VN.erase(CurInst); - erase_table(ValNo, CurInst); + erase_table(ValNo, CurInst, CurrentBlock); DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n'); if (MD) MD->removeInstruction(CurInst); @@ -2226,14 +2256,14 @@ // Walk through the value number scope to make sure the instruction isn't // ferreted away in it. - for (DenseMap >::const_iterator + for (DenseMap::const_iterator I = NumberTable.begin(), E = NumberTable.end(); I != E; ++I) { - std::pair const * Node = &I->second; - assert(Node->first != Inst && "Inst still in value numbering scope!"); + const NumberTableEntry *Node = &I->second; + assert(Node->Val != Inst && "Inst still in value numbering scope!"); - while (Node->second) { - Node = static_cast*>(Node->second); - assert(Node->first != Inst && "Inst still in value numbering scope!"); + while (Node->Next) { + Node = Node->Next; + assert(Node->Val != Inst && "Inst still in value numbering scope!"); } } } Added: llvm/trunk/test/Transforms/GVN/condprop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/condprop.ll?rev=122378&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/condprop.ll (added) +++ llvm/trunk/test/Transforms/GVN/condprop.ll Tue Dec 21 17:54:34 2010 @@ -0,0 +1,55 @@ +; RUN: opt < %s -basicaa -gvn -S | FileCheck %s + + at a = external global i32 ; [#uses=7] + +; CHECK: @foo +define i32 @foo() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = icmp eq i32 %0, 4 + br i1 %1, label %bb, label %bb1 + +bb: ; preds = %entry + br label %bb8 + +bb1: ; preds = %entry + %2 = load i32* @a, align 4 + %3 = icmp eq i32 %2, 5 + br i1 %3, label %bb2, label %bb3 + +bb2: ; preds = %bb1 + br label %bb8 + +bb3: ; preds = %bb1 + %4 = load i32* @a, align 4 + %5 = icmp eq i32 %4, 4 +; CHECK: br i1 false, label %bb4, label %bb5 + br i1 %5, label %bb4, label %bb5 + +bb4: ; preds = %bb3 + %6 = load i32* @a, align 4 + %7 = add i32 %6, 5 + br label %bb8 + +bb5: ; preds = %bb3 + %8 = load i32* @a, align 4 + %9 = icmp eq i32 %8, 5 +; CHECK: br i1 false, label %bb6, label %bb7 + br i1 %9, label %bb6, label %bb7 + +bb6: ; preds = %bb5 + %10 = load i32* @a, align 4 + %11 = add i32 %10, 4 + br label %bb8 + +bb7: ; preds = %bb5 + %12 = load i32* @a, align 4 + br label %bb8 + +bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb + %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ] + br label %return + +return: ; preds = %bb8 + ret i32 %.0 +} \ No newline at end of file From peckw at wesleypeck.com Tue Dec 21 18:22:59 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 22 Dec 2010 00:22:59 -0000 Subject: [llvm-commits] [llvm] r122379 - /llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp Message-ID: <20101222002259.579A82A6C12C@llvm.org> Author: peckw Date: Tue Dec 21 18:22:59 2010 New Revision: 122379 URL: http://llvm.org/viewvc/llvm-project?rev=122379&view=rev Log: Fix a regression introduced into the MBlaze delay slot filler. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp Modified: llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp?rev=122379&r1=122378&r2=122379&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp Tue Dec 21 18:22:59 2010 @@ -90,6 +90,20 @@ return false; } +static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) { + switch (instr->getOpcode()) { + default: return instr->getNumOperands(); + + // These instructions have a variable number of operands but the first two + // are the "real" operands that we care about during hazard detection. + case MBlaze::BRLID: + case MBlaze::BRALID: + case MBlaze::BRLD: + case MBlaze::BRALD: + return 2; + } +} + static bool delayHasHazard(MachineBasicBlock::iterator &candidate, MachineBasicBlock::iterator &slot) { // Hazard check @@ -111,17 +125,23 @@ // contains a store operation. bool a_is_memory = desc.mayLoad() || desc.mayStore(); + // Determine the number of operands in the slot instruction and in the + // candidate instruction. + const unsigned aend = getLastRealOperand(a); + const unsigned bend = getLastRealOperand(b); + // Check hazards type 1, 2 and 5 by scanning the middle bit MachineBasicBlock::iterator m = a; for (++m; m != b; ++m) { - for (unsigned aop = 0, aend = a->getNumOperands(); aopgetOperand(aop).isReg(); if (!aop_is_reg) continue; bool aop_is_def = a->getOperand(aop).isDef(); unsigned aop_reg = a->getOperand(aop).getReg(); - for (unsigned mop = 0, mend = m->getNumOperands(); mopgetOperand(mop).isReg(); if (!mop_is_reg) continue; @@ -141,13 +161,12 @@ } // Check hazard type 3 & 4 - for (unsigned aop = 0, aend = a->getNumOperands(); aopgetOperand(aop).isReg()) { unsigned aop_reg = a->getOperand(aop).getReg(); - for (unsigned bop = 0, bend = b->getNumOperands(); bopgetOperand(bop).isReg() && !b->getOperand(bop).isImplicit() && - !b->getOperand(bop).isKill()) { + for (unsigned bop = 0; bopgetOperand(bop).isReg() && !b->getOperand(bop).isImplicit()) { unsigned bop_reg = b->getOperand(bop).getReg(); if (aop_reg == bop_reg) return true; From peckw at wesleypeck.com Tue Dec 21 18:53:07 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 22 Dec 2010 00:53:07 -0000 Subject: [llvm-commits] [llvm] r122381 - in /llvm/trunk/lib/Target/MBlaze: MBlazeInstrFSL.td MBlazeInstrInfo.td MBlazeRegisterInfo.td Message-ID: <20101222005307.5C4182A6C12C@llvm.org> Author: peckw Date: Tue Dec 21 18:53:07 2010 New Revision: 122381 URL: http://llvm.org/viewvc/llvm-project?rev=122381&view=rev Log: Modeling the carry bit in the MSR register of the MicroBlaze. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrFSL.td llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrFSL.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrFSL.td?rev=122381&r1=122380&r2=122381&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrFSL.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrFSL.td Tue Dec 21 18:53:07 2010 @@ -115,14 +115,6 @@ def EAGET : FSLGet<0x1B, 0x03, "eaget ", int_mblaze_fsl_eaget>; def ECGET : FSLGet<0x1B, 0x09, "ecget ", int_mblaze_fsl_ecget>; def ECAGET : FSLGet<0x1B, 0x0B, "ecaget ", int_mblaze_fsl_ecaget>; -def NGET : FSLGet<0x1B, 0x10, "nget ", int_mblaze_fsl_nget>; -def NAGET : FSLGet<0x1B, 0x12, "naget ", int_mblaze_fsl_naget>; -def NCGET : FSLGet<0x1B, 0x18, "ncget ", int_mblaze_fsl_ncget>; -def NCAGET : FSLGet<0x1B, 0x1A, "ncaget ", int_mblaze_fsl_ncaget>; -def NEGET : FSLGet<0x1B, 0x11, "neget ", int_mblaze_fsl_neget>; -def NEAGET : FSLGet<0x1B, 0x13, "neaget ", int_mblaze_fsl_neaget>; -def NECGET : FSLGet<0x1B, 0x19, "necget ", int_mblaze_fsl_necget>; -def NECAGET : FSLGet<0x1B, 0x1B, "necaget ", int_mblaze_fsl_necaget>; def TGET : FSLGet<0x1B, 0x04, "tget ", int_mblaze_fsl_tget>; def TAGET : FSLGet<0x1B, 0x06, "taget ", int_mblaze_fsl_taget>; def TCGET : FSLGet<0x1B, 0x0C, "tcget ", int_mblaze_fsl_tcget>; @@ -131,14 +123,25 @@ def TEAGET : FSLGet<0x1B, 0x07, "teaget ", int_mblaze_fsl_teaget>; def TECGET : FSLGet<0x1B, 0x0D, "tecget ", int_mblaze_fsl_tecget>; def TECAGET : FSLGet<0x1B, 0x0F, "tecaget ", int_mblaze_fsl_tecaget>; -def TNGET : FSLGet<0x1B, 0x14, "tnget ", int_mblaze_fsl_tnget>; -def TNAGET : FSLGet<0x1B, 0x16, "tnaget ", int_mblaze_fsl_tnaget>; -def TNCGET : FSLGet<0x1B, 0x1C, "tncget ", int_mblaze_fsl_tncget>; -def TNCAGET : FSLGet<0x1B, 0x1E, "tncaget ", int_mblaze_fsl_tncaget>; -def TNEGET : FSLGet<0x1B, 0x15, "tneget ", int_mblaze_fsl_tneget>; -def TNEAGET : FSLGet<0x1B, 0x17, "tneaget ", int_mblaze_fsl_tneaget>; -def TNECGET : FSLGet<0x1B, 0x1D, "tnecget ", int_mblaze_fsl_tnecget>; -def TNECAGET : FSLGet<0x1B, 0x1F, "tnecaget ", int_mblaze_fsl_tnecaget>; + +let Defs = [CARRY] in { + def NGET : FSLGet<0x1B, 0x10, "nget ", int_mblaze_fsl_nget>; + def NAGET : FSLGet<0x1B, 0x12, "naget ", int_mblaze_fsl_naget>; + def NCGET : FSLGet<0x1B, 0x18, "ncget ", int_mblaze_fsl_ncget>; + def NCAGET : FSLGet<0x1B, 0x1A, "ncaget ", int_mblaze_fsl_ncaget>; + def NEGET : FSLGet<0x1B, 0x11, "neget ", int_mblaze_fsl_neget>; + def NEAGET : FSLGet<0x1B, 0x13, "neaget ", int_mblaze_fsl_neaget>; + def NECGET : FSLGet<0x1B, 0x19, "necget ", int_mblaze_fsl_necget>; + def NECAGET : FSLGet<0x1B, 0x1B, "necaget ", int_mblaze_fsl_necaget>; + def TNGET : FSLGet<0x1B, 0x14, "tnget ", int_mblaze_fsl_tnget>; + def TNAGET : FSLGet<0x1B, 0x16, "tnaget ", int_mblaze_fsl_tnaget>; + def TNCGET : FSLGet<0x1B, 0x1C, "tncget ", int_mblaze_fsl_tncget>; + def TNCAGET : FSLGet<0x1B, 0x1E, "tncaget ", int_mblaze_fsl_tncaget>; + def TNEGET : FSLGet<0x1B, 0x15, "tneget ", int_mblaze_fsl_tneget>; + def TNEAGET : FSLGet<0x1B, 0x17, "tneaget ", int_mblaze_fsl_tneaget>; + def TNECGET : FSLGet<0x1B, 0x1D, "tnecget ", int_mblaze_fsl_tnecget>; + def TNECAGET : FSLGet<0x1B, 0x1F, "tnecaget ", int_mblaze_fsl_tnecaget>; +} //===----------------------------------------------------------------------===// // FSL Dynamic Get Instructions @@ -151,14 +154,6 @@ def EAGETD : FSLGetD<0x13, 0x03, "eagetd ", int_mblaze_fsl_eaget>; def ECGETD : FSLGetD<0x13, 0x09, "ecgetd ", int_mblaze_fsl_ecget>; def ECAGETD : FSLGetD<0x13, 0x0B, "ecagetd ", int_mblaze_fsl_ecaget>; -def NGETD : FSLGetD<0x13, 0x10, "ngetd ", int_mblaze_fsl_nget>; -def NAGETD : FSLGetD<0x13, 0x12, "nagetd ", int_mblaze_fsl_naget>; -def NCGETD : FSLGetD<0x13, 0x18, "ncgetd ", int_mblaze_fsl_ncget>; -def NCAGETD : FSLGetD<0x13, 0x1A, "ncagetd ", int_mblaze_fsl_ncaget>; -def NEGETD : FSLGetD<0x13, 0x11, "negetd ", int_mblaze_fsl_neget>; -def NEAGETD : FSLGetD<0x13, 0x13, "neagetd ", int_mblaze_fsl_neaget>; -def NECGETD : FSLGetD<0x13, 0x19, "necgetd ", int_mblaze_fsl_necget>; -def NECAGETD : FSLGetD<0x13, 0x1B, "necagetd ", int_mblaze_fsl_necaget>; def TGETD : FSLGetD<0x13, 0x04, "tgetd ", int_mblaze_fsl_tget>; def TAGETD : FSLGetD<0x13, 0x06, "tagetd ", int_mblaze_fsl_taget>; def TCGETD : FSLGetD<0x13, 0x0C, "tcgetd ", int_mblaze_fsl_tcget>; @@ -167,14 +162,25 @@ def TEAGETD : FSLGetD<0x13, 0x07, "teagetd ", int_mblaze_fsl_teaget>; def TECGETD : FSLGetD<0x13, 0x0D, "tecgetd ", int_mblaze_fsl_tecget>; def TECAGETD : FSLGetD<0x13, 0x0F, "tecagetd ", int_mblaze_fsl_tecaget>; -def TNGETD : FSLGetD<0x13, 0x14, "tngetd ", int_mblaze_fsl_tnget>; -def TNAGETD : FSLGetD<0x13, 0x16, "tnagetd ", int_mblaze_fsl_tnaget>; -def TNCGETD : FSLGetD<0x13, 0x1C, "tncgetd ", int_mblaze_fsl_tncget>; -def TNCAGETD : FSLGetD<0x13, 0x1E, "tncagetd ", int_mblaze_fsl_tncaget>; -def TNEGETD : FSLGetD<0x13, 0x15, "tnegetd ", int_mblaze_fsl_tneget>; -def TNEAGETD : FSLGetD<0x13, 0x17, "tneagetd ", int_mblaze_fsl_tneaget>; -def TNECGETD : FSLGetD<0x13, 0x1D, "tnecgetd ", int_mblaze_fsl_tnecget>; -def TNECAGETD : FSLGetD<0x13, 0x1F, "tnecagetd", int_mblaze_fsl_tnecaget>; + +let Defs = [CARRY] in { + def NGETD : FSLGetD<0x13, 0x10, "ngetd ", int_mblaze_fsl_nget>; + def NAGETD : FSLGetD<0x13, 0x12, "nagetd ", int_mblaze_fsl_naget>; + def NCGETD : FSLGetD<0x13, 0x18, "ncgetd ", int_mblaze_fsl_ncget>; + def NCAGETD : FSLGetD<0x13, 0x1A, "ncagetd ", int_mblaze_fsl_ncaget>; + def NEGETD : FSLGetD<0x13, 0x11, "negetd ", int_mblaze_fsl_neget>; + def NEAGETD : FSLGetD<0x13, 0x13, "neagetd ", int_mblaze_fsl_neaget>; + def NECGETD : FSLGetD<0x13, 0x19, "necgetd ", int_mblaze_fsl_necget>; + def NECAGETD : FSLGetD<0x13, 0x1B, "necagetd ", int_mblaze_fsl_necaget>; + def TNGETD : FSLGetD<0x13, 0x14, "tngetd ", int_mblaze_fsl_tnget>; + def TNAGETD : FSLGetD<0x13, 0x16, "tnagetd ", int_mblaze_fsl_tnaget>; + def TNCGETD : FSLGetD<0x13, 0x1C, "tncgetd ", int_mblaze_fsl_tncget>; + def TNCAGETD : FSLGetD<0x13, 0x1E, "tncagetd ", int_mblaze_fsl_tncaget>; + def TNEGETD : FSLGetD<0x13, 0x15, "tnegetd ", int_mblaze_fsl_tneget>; + def TNEAGETD : FSLGetD<0x13, 0x17, "tneagetd ", int_mblaze_fsl_tneaget>; + def TNECGETD : FSLGetD<0x13, 0x1D, "tnecgetd ", int_mblaze_fsl_tnecget>; + def TNECAGETD : FSLGetD<0x13, 0x1F, "tnecagetd", int_mblaze_fsl_tnecaget>; +} //===----------------------------------------------------------------------===// // FSL Put Instructions @@ -183,18 +189,21 @@ def APUT : FSLPut<0x1B, 0x1, "aput ", int_mblaze_fsl_aput>; def CPUT : FSLPut<0x1B, 0x4, "cput ", int_mblaze_fsl_cput>; def CAPUT : FSLPut<0x1B, 0x5, "caput ", int_mblaze_fsl_caput>; -def NPUT : FSLPut<0x1B, 0x8, "nput ", int_mblaze_fsl_nput>; -def NAPUT : FSLPut<0x1B, 0x9, "naput ", int_mblaze_fsl_naput>; -def NCPUT : FSLPut<0x1B, 0xC, "ncput ", int_mblaze_fsl_ncput>; -def NCAPUT : FSLPut<0x1B, 0xD, "ncaput ", int_mblaze_fsl_ncaput>; def TPUT : FSLPutT<0x1B, 0x2, "tput ", int_mblaze_fsl_tput>; def TAPUT : FSLPutT<0x1B, 0x3, "taput ", int_mblaze_fsl_taput>; def TCPUT : FSLPutT<0x1B, 0x6, "tcput ", int_mblaze_fsl_tcput>; def TCAPUT : FSLPutT<0x1B, 0x7, "tcaput ", int_mblaze_fsl_tcaput>; -def TNPUT : FSLPutT<0x1B, 0xA, "tnput ", int_mblaze_fsl_tnput>; -def TNAPUT : FSLPutT<0x1B, 0xB, "tnaput ", int_mblaze_fsl_tnaput>; -def TNCPUT : FSLPutT<0x1B, 0xE, "tncput ", int_mblaze_fsl_tncput>; -def TNCAPUT : FSLPutT<0x1B, 0xF, "tncaput ", int_mblaze_fsl_tncaput>; + +let Defs = [CARRY] in { + def NPUT : FSLPut<0x1B, 0x8, "nput ", int_mblaze_fsl_nput>; + def NAPUT : FSLPut<0x1B, 0x9, "naput ", int_mblaze_fsl_naput>; + def NCPUT : FSLPut<0x1B, 0xC, "ncput ", int_mblaze_fsl_ncput>; + def NCAPUT : FSLPut<0x1B, 0xD, "ncaput ", int_mblaze_fsl_ncaput>; + def TNPUT : FSLPutT<0x1B, 0xA, "tnput ", int_mblaze_fsl_tnput>; + def TNAPUT : FSLPutT<0x1B, 0xB, "tnaput ", int_mblaze_fsl_tnaput>; + def TNCPUT : FSLPutT<0x1B, 0xE, "tncput ", int_mblaze_fsl_tncput>; + def TNCAPUT : FSLPutT<0x1B, 0xF, "tncaput ", int_mblaze_fsl_tncaput>; +} //===----------------------------------------------------------------------===// // FSL Dynamic Put Instructions @@ -203,15 +212,18 @@ def APUTD : FSLPutD<0x13, 0x1, "aputd ", int_mblaze_fsl_aput>; def CPUTD : FSLPutD<0x13, 0x4, "cputd ", int_mblaze_fsl_cput>; def CAPUTD : FSLPutD<0x13, 0x5, "caputd ", int_mblaze_fsl_caput>; -def NPUTD : FSLPutD<0x13, 0x8, "nputd ", int_mblaze_fsl_nput>; -def NAPUTD : FSLPutD<0x13, 0x9, "naputd ", int_mblaze_fsl_naput>; -def NCPUTD : FSLPutD<0x13, 0xC, "ncputd ", int_mblaze_fsl_ncput>; -def NCAPUTD : FSLPutD<0x13, 0xD, "ncaputd ", int_mblaze_fsl_ncaput>; def TPUTD : FSLPutTD<0x13, 0x2, "tputd ", int_mblaze_fsl_tput>; def TAPUTD : FSLPutTD<0x13, 0x3, "taputd ", int_mblaze_fsl_taput>; def TCPUTD : FSLPutTD<0x13, 0x6, "tcputd ", int_mblaze_fsl_tcput>; def TCAPUTD : FSLPutTD<0x13, 0x7, "tcaputd ", int_mblaze_fsl_tcaput>; -def TNPUTD : FSLPutTD<0x13, 0xA, "tnputd ", int_mblaze_fsl_tnput>; -def TNAPUTD : FSLPutTD<0x13, 0xB, "tnaputd ", int_mblaze_fsl_tnaput>; -def TNCPUTD : FSLPutTD<0x13, 0xE, "tncputd ", int_mblaze_fsl_tncput>; -def TNCAPUTD : FSLPutTD<0x13, 0xF, "tncaputd ", int_mblaze_fsl_tncaput>; + +let Defs = [CARRY] in { + def NPUTD : FSLPutD<0x13, 0x8, "nputd ", int_mblaze_fsl_nput>; + def NAPUTD : FSLPutD<0x13, 0x9, "naputd ", int_mblaze_fsl_naput>; + def NCPUTD : FSLPutD<0x13, 0xC, "ncputd ", int_mblaze_fsl_ncput>; + def NCAPUTD : FSLPutD<0x13, 0xD, "ncaputd ", int_mblaze_fsl_ncaput>; + def TNPUTD : FSLPutTD<0x13, 0xA, "tnputd ", int_mblaze_fsl_tnput>; + def TNAPUTD : FSLPutTD<0x13, 0xB, "tnaputd ", int_mblaze_fsl_tnaput>; + def TNCPUTD : FSLPutTD<0x13, 0xE, "tncputd ", int_mblaze_fsl_tncput>; + def TNCAPUTD : FSLPutTD<0x13, 0xF, "tncaputd ", int_mblaze_fsl_tncaput>; +} Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122381&r1=122380&r2=122381&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Tue Dec 21 18:53:07 2010 @@ -330,26 +330,44 @@ //===----------------------------------------------------------------------===// let isCommutable = 1, isAsCheapAsAMove = 1 in { - def ADD : Arith<0x00, 0x000, "add ", addc, IIAlu>; - def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; def ADDK : Arith<0x04, 0x000, "addk ", add, IIAlu>; - def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>; def AND : Logic<0x21, 0x000, "and ", and>; def OR : Logic<0x20, 0x000, "or ", or>; def XOR : Logic<0x22, 0x000, "xor ", xor>; def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">; def PCMPEQ : PatCmp<0x22, 0x400, "pcmpeq ">; def PCMPNE : PatCmp<0x23, 0x400, "pcmpne ">; + + let Defs = [CARRY] in { + def ADD : Arith<0x00, 0x000, "add ", addc, IIAlu>; + + let Uses = [CARRY] in { + def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; + } + } + + let Uses = [CARRY] in { + def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>; + } } let isAsCheapAsAMove = 1 in { def ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>; def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>; def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>; - def RSUB : ArithR<0x01, 0x000, "rsub ", subc, IIAlu>; - def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; def RSUBK : ArithR<0x05, 0x000, "rsubk ", sub, IIAlu>; - def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; + + let Defs = [CARRY] in { + def RSUB : ArithR<0x01, 0x000, "rsub ", subc, IIAlu>; + + let Uses = [CARRY] in { + def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; + } + } + + let Uses = [CARRY] in { + def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; + } } let isCommutable = 1, Predicates=[HasMul] in { @@ -384,18 +402,27 @@ //===----------------------------------------------------------------------===// let isAsCheapAsAMove = 1 in { - def ADDI : ArithI<0x08, "addi ", addc, simm16, immSExt16>; - def ADDIC : ArithI<0x0A, "addic ", adde, simm16, immSExt16>; def ADDIK : ArithI<0x0C, "addik ", add, simm16, immSExt16>; - def ADDIKC : ArithNI<0x0E, "addikc ", simm16, immSExt16>; - def RSUBI : ArithRI<0x09, "rsubi ", subc, simm16, immSExt16>; - def RSUBIC : ArithRI<0x0B, "rsubic ", sube, simm16, immSExt16>; def RSUBIK : ArithRI<0x0D, "rsubik ", sub, simm16, immSExt16>; - def RSUBIKC : ArithRNI<0x0F, "rsubikc", simm16, immSExt16>; def ANDNI : ArithNI<0x2B, "andni ", uimm16, immZExt16>; def ANDI : LogicI<0x29, "andi ", and>; def ORI : LogicI<0x28, "ori ", or>; def XORI : LogicI<0x2A, "xori ", xor>; + + let Defs = [CARRY] in { + def ADDI : ArithI<0x08, "addi ", addc, simm16, immSExt16>; + def RSUBI : ArithRI<0x09, "rsubi ", subc, simm16, immSExt16>; + + let Uses = [CARRY] in { + def ADDIC : ArithI<0x0A, "addic ", adde, simm16, immSExt16>; + def RSUBIC : ArithRI<0x0B, "rsubic ", sube, simm16, immSExt16>; + } + } + + let Uses = [CARRY] in { + def ADDIKC : ArithNI<0x0E, "addikc ", simm16, immSExt16>; + def RSUBIKC : ArithRNI<0x0F, "rsubikc", simm16, immSExt16>; + } } let Predicates=[HasMul] in { @@ -415,26 +442,32 @@ def LW : LoadM<0x32, 0x000, "lw ">; def LWR : LoadM<0x32, 0x200, "lwr ">; - def LWX : LoadM<0x32, 0x400, "lwx ">; + + let Defs = [CARRY] in { + def LWX : LoadM<0x32, 0x400, "lwx ">; + } def LBUI : LoadMI<0x38, "lbui ", zextloadi8>; def LHUI : LoadMI<0x39, "lhui ", zextloadi16>; def LWI : LoadMI<0x3A, "lwi ", load>; } - def SB : StoreM<0x34, 0x000, "sb ">; - def SBR : StoreM<0x34, 0x200, "sbr ">; +def SB : StoreM<0x34, 0x000, "sb ">; +def SBR : StoreM<0x34, 0x200, "sbr ">; + +def SH : StoreM<0x35, 0x000, "sh ">; +def SHR : StoreM<0x35, 0x200, "shr ">; - def SH : StoreM<0x35, 0x000, "sh ">; - def SHR : StoreM<0x35, 0x200, "shr ">; +def SW : StoreM<0x36, 0x000, "sw ">; +def SWR : StoreM<0x36, 0x200, "swr ">; - def SW : StoreM<0x36, 0x000, "sw ">; - def SWR : StoreM<0x36, 0x200, "swr ">; +let Defs = [CARRY] in { def SWX : StoreM<0x36, 0x400, "swx ">; +} - def SBI : StoreMI<0x3C, "sbi ", truncstorei8>; - def SHI : StoreMI<0x3D, "shi ", truncstorei16>; - def SWI : StoreMI<0x3E, "swi ", store>; +def SBI : StoreMI<0x3C, "sbi ", truncstorei8>; +def SHI : StoreMI<0x3D, "shi ", truncstorei16>; +def SWI : StoreMI<0x3E, "swi ", store>; //===----------------------------------------------------------------------===// // MBlaze branch instructions @@ -501,21 +534,21 @@ } let isCall =1, hasDelaySlot = 1, - Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], + Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,CARRY], Uses = [R1] in { def BRLID : BranchLI<0x2E, 0x14, "brlid ">; def BRALID : BranchLI<0x2E, 0x1C, "bralid ">; } let isCall = 1, hasDelaySlot = 1, - Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], + Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,CARRY], Uses = [R1] in { def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">; def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">; } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, - hasCtrlDep=1, rd=0x10, Form=FCRI in { + rd=0x10, Form=FCRI in { def RTSD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), "rtsd $target, $imm", [], @@ -523,7 +556,7 @@ } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, - hasCtrlDep=1, rd=0x11, Form=FCRI in { + rd=0x11, Form=FCRI in { def RTID : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), "rtid $target, $imm", [], @@ -531,7 +564,7 @@ } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, - hasCtrlDep=1, rd=0x12, Form=FCRI in { + rd=0x12, Form=FCRI in { def RTBD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), "rtbd $target, $imm", [], @@ -539,7 +572,7 @@ } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, - hasCtrlDep=1, rd=0x14, Form=FCRI in { + rd=0x14, Form=FCRI in { def RTED : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), "rted $target, $imm", [], @@ -576,18 +609,21 @@ []>; } - let rb = 0 in { def SEXT16 : TA<0x24, 0x061, (outs GPR:$dst), (ins GPR:$src), "sext16 $dst, $src", [], IIAlu>; def SEXT8 : TA<0x24, 0x060, (outs GPR:$dst), (ins GPR:$src), "sext8 $dst, $src", [], IIAlu>; - def SRL : TA<0x24, 0x041, (outs GPR:$dst), (ins GPR:$src), - "srl $dst, $src", [], IIAlu>; - def SRA : TA<0x24, 0x001, (outs GPR:$dst), (ins GPR:$src), - "sra $dst, $src", [], IIAlu>; - def SRC : TA<0x24, 0x021, (outs GPR:$dst), (ins GPR:$src), - "src $dst, $src", [], IIAlu>; + let Defs = [CARRY] in { + def SRL : TA<0x24, 0x041, (outs GPR:$dst), (ins GPR:$src), + "srl $dst, $src", [], IIAlu>; + def SRA : TA<0x24, 0x001, (outs GPR:$dst), (ins GPR:$src), + "sra $dst, $src", [], IIAlu>; + let Uses = [CARRY] in { + def SRC : TA<0x24, 0x021, (outs GPR:$dst), (ins GPR:$src), + "src $dst, $src", [], IIAlu>; + } + } } let isCodeGenOnly=1 in { Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td?rev=122381&r1=122380&r2=122381&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Tue Dec 21 18:53:07 2010 @@ -97,6 +97,11 @@ def RPVR9 : MBlazeSPRReg<0x2009, "rpvr9">, DwarfRegNum<[53]>; def RPVR10 : MBlazeSPRReg<0x200A, "rpvr10">, DwarfRegNum<[54]>; def RPVR11 : MBlazeSPRReg<0x200B, "rpvr11">, DwarfRegNum<[55]>; + + // The carry bit. In the Microblaze this is really bit 29 of the + // MSR register but this is the only bit of that register that we + // are interested in modeling. + def CARRY : MBlazeSPRReg<0x0000, "rmsr[c]">, DwarfRegNum<[33]>; } //===----------------------------------------------------------------------===// @@ -179,3 +184,7 @@ } }]; } + +def CRC : RegisterClass<"MBlaze", [i32], 32, [CARRY]> { + let CopyCost = -1; +} From aggarwa4 at illinois.edu Tue Dec 21 18:58:07 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Dec 2010 00:58:07 -0000 Subject: [llvm-commits] [poolalloc] r122383 - in /poolalloc/trunk/lib/DSA: DSGraph.cpp Local.cpp Message-ID: <20101222005807.894BB2A6C12C@llvm.org> Author: aggarwa4 Date: Tue Dec 21 18:58:07 2010 New Revision: 122383 URL: http://llvm.org/viewvc/llvm-project?rev=122383&view=rev Log: Only merge call sites if arguments also match. Now we can merge call sites in local. Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp poolalloc/trunk/lib/DSA/Local.cpp Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122383&r1=122382&r2=122383&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Tue Dec 21 18:58:07 2010 @@ -852,16 +852,19 @@ // if the callee contains an external function, it will never be // resolvable, just merge the call sites. if (!LastCalleeNode.isNull() && LastCalleeNode.getNode() == Callee) { - // LastCalleeContainsExternalFunction = Callee->isExternFuncNode(); - + // check that arguments also match std::list::iterator PrevIt = OldIt; --PrevIt; - PrevIt->mergeWith(CS); + if(CS == *PrevIt) { + // LastCalleeContainsExternalFunction = Callee->isExternFuncNode(); - // No need to keep this call anymore. - Calls.erase(OldIt); - ++NumDeleted; - continue; + PrevIt->mergeWith(CS); + + // No need to keep this call anymore. + Calls.erase(OldIt); + ++NumDeleted; + continue; + } } else { LastCalleeNode = Callee; } Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=122383&r1=122382&r2=122383&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Tue Dec 21 18:58:07 2010 @@ -189,7 +189,7 @@ g.computeIntPtrFlags(); // Remove any nodes made dead due to merging... - //g.removeDeadNodes(DSGraph::KeepUnreachableGlobals); + g.removeDeadNodes(DSGraph::KeepUnreachableGlobals); } // GraphBuilder ctor for working on the globals graph From peckw at wesleypeck.com Tue Dec 21 19:15:01 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 22 Dec 2010 01:15:01 -0000 Subject: [llvm-commits] [llvm] r122384 - in /llvm/trunk/lib/Target/MBlaze: MBlazeISelLowering.cpp MBlazeISelLowering.h MBlazeInstrInfo.td Message-ID: <20101222011501.AE94C2A6C12C@llvm.org> Author: peckw Date: Tue Dec 21 19:15:01 2010 New Revision: 122384 URL: http://llvm.org/viewvc/llvm-project?rev=122384&view=rev Log: Add support for some of the LLVM atomic operations to the MBlaze backend. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=122384&r1=122383&r2=122384&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp Tue Dec 21 19:15:01 2010 @@ -175,7 +175,6 @@ // Use the default for now setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); // MBlaze doesn't have extending float->double load/store setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); @@ -213,172 +212,353 @@ //===----------------------------------------------------------------------===// MachineBasicBlock* MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - DebugLoc dl = MI->getDebugLoc(); - + MachineBasicBlock *MBB) + const { switch (MI->getOpcode()) { default: assert(false && "Unexpected instr type to insert"); + case MBlaze::ShiftRL: case MBlaze::ShiftRA: - case MBlaze::ShiftL: { - // To "insert" a shift left instruction, we actually have to insert a - // simple loop. The incoming instruction knows the destination vreg to - // set, the source vreg to operate over and the shift amount. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // start: - // andi samt, samt, 31 - // beqid samt, finish - // add dst, src, r0 - // loop: - // addik samt, samt, -1 - // sra dst, dst - // bneid samt, loop - // nop - // finish: - MachineFunction *F = BB->getParent(); - MachineRegisterInfo &R = F->getRegInfo(); - MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB); - F->insert(It, loop); - F->insert(It, finish); - - // Update machine-CFG edges by transfering adding all successors and - // remaining instructions from the current block to the new block which - // will contain the Phi node for the select. - finish->splice(finish->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - finish->transferSuccessorsAndUpdatePHIs(BB); - - // Add the true and fallthrough blocks as its successors. - BB->addSuccessor(loop); - BB->addSuccessor(finish); - - // Next, add the finish block as a successor of the loop block - loop->addSuccessor(finish); - loop->addSuccessor(loop); - - unsigned IAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(BB, dl, TII->get(MBlaze::ANDI), IAMT) - .addReg(MI->getOperand(2).getReg()) - .addImm(31); - - unsigned IVAL = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(BB, dl, TII->get(MBlaze::ADDIK), IVAL) - .addReg(MI->getOperand(1).getReg()) - .addImm(0); - - BuildMI(BB, dl, TII->get(MBlaze::BEQID)) - .addReg(IAMT) - .addMBB(finish); - - unsigned DST = R.createVirtualRegister(MBlaze::GPRRegisterClass); - unsigned NDST = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(loop, dl, TII->get(MBlaze::PHI), DST) - .addReg(IVAL).addMBB(BB) - .addReg(NDST).addMBB(loop); - - unsigned SAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - unsigned NAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); - BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT) - .addReg(IAMT).addMBB(BB) - .addReg(NAMT).addMBB(loop); - - if (MI->getOpcode() == MBlaze::ShiftL) - BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST); - else if (MI->getOpcode() == MBlaze::ShiftRA) - BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST); - else if (MI->getOpcode() == MBlaze::ShiftRL) - BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); - else - llvm_unreachable("Cannot lower unknown shift instruction"); - - BuildMI(loop, dl, TII->get(MBlaze::ADDIK), NAMT) - .addReg(SAMT) - .addImm(-1); - - BuildMI(loop, dl, TII->get(MBlaze::BNEID)) - .addReg(NAMT) - .addMBB(loop); - - BuildMI(*finish, finish->begin(), dl, - TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - .addReg(IVAL).addMBB(BB) - .addReg(NDST).addMBB(loop); + case MBlaze::ShiftL: + return EmitCustomShift(MI, MBB); + + case MBlaze::Select_FCC: + case MBlaze::Select_CC: + return EmitCustomSelect(MI, MBB); - // The pseudo instruction is no longer needed so remove it + case MBlaze::CAS32: + case MBlaze::SWP32: + case MBlaze::LAA32: + case MBlaze::LAS32: + case MBlaze::LAD32: + case MBlaze::LAO32: + case MBlaze::LAX32: + case MBlaze::LAN32: + return EmitCustomAtomic(MI, MBB); + + case MBlaze::MEMBARRIER: + // The Microblaze does not need memory barriers. Just delete the pseudo + // instruction and finish. MI->eraseFromParent(); - return finish; - } + return MBB; + } +} - case MBlaze::Select_FCC: - case MBlaze::Select_CC: { - // To "insert" a SELECT_CC instruction, we actually have to insert the - // diamond control-flow pattern. The incoming instruction knows the - // destination vreg to set, the condition code register to branch on, the - // true/false values to select between, and a branch opcode to use. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // setcc r1, r2, r3 - // bNE r1, r0, copy1MBB - // fallthrough --> copy0MBB - MachineFunction *F = BB->getParent(); - MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB); - - unsigned Opc; - switch (MI->getOperand(4).getImm()) { - default: llvm_unreachable("Unknown branch condition"); - case MBlazeCC::EQ: Opc = MBlaze::BEQID; break; - case MBlazeCC::NE: Opc = MBlaze::BNEID; break; - case MBlazeCC::GT: Opc = MBlaze::BGTID; break; - case MBlazeCC::LT: Opc = MBlaze::BLTID; break; - case MBlazeCC::GE: Opc = MBlaze::BGEID; break; - case MBlazeCC::LE: Opc = MBlaze::BLEID; break; +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomShift(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // To "insert" a shift left instruction, we actually have to insert a + // simple loop. The incoming instruction knows the destination vreg to + // set, the source vreg to operate over and the shift amount. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // start: + // andi samt, samt, 31 + // beqid samt, finish + // add dst, src, r0 + // loop: + // addik samt, samt, -1 + // sra dst, dst + // bneid samt, loop + // nop + // finish: + MachineFunction *F = MBB->getParent(); + MachineRegisterInfo &R = F->getRegInfo(); + MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, loop); + F->insert(It, finish); + + // Update machine-CFG edges by transfering adding all successors and + // remaining instructions from the current block to the new block which + // will contain the Phi node for the select. + finish->splice(finish->begin(), MBB, + llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + finish->transferSuccessorsAndUpdatePHIs(MBB); + + // Add the true and fallthrough blocks as its successors. + MBB->addSuccessor(loop); + MBB->addSuccessor(finish); + + // Next, add the finish block as a successor of the loop block + loop->addSuccessor(finish); + loop->addSuccessor(loop); + + unsigned IAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(MBB, dl, TII->get(MBlaze::ANDI), IAMT) + .addReg(MI->getOperand(2).getReg()) + .addImm(31); + + unsigned IVAL = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(MBB, dl, TII->get(MBlaze::ADDIK), IVAL) + .addReg(MI->getOperand(1).getReg()) + .addImm(0); + + BuildMI(MBB, dl, TII->get(MBlaze::BEQID)) + .addReg(IAMT) + .addMBB(finish); + + unsigned DST = R.createVirtualRegister(MBlaze::GPRRegisterClass); + unsigned NDST = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(loop, dl, TII->get(MBlaze::PHI), DST) + .addReg(IVAL).addMBB(MBB) + .addReg(NDST).addMBB(loop); + + unsigned SAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + unsigned NAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT) + .addReg(IAMT).addMBB(MBB) + .addReg(NAMT).addMBB(loop); + + if (MI->getOpcode() == MBlaze::ShiftL) + BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST); + else if (MI->getOpcode() == MBlaze::ShiftRA) + BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST); + else if (MI->getOpcode() == MBlaze::ShiftRL) + BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); + else + llvm_unreachable("Cannot lower unknown shift instruction"); + + BuildMI(loop, dl, TII->get(MBlaze::ADDIK), NAMT) + .addReg(SAMT) + .addImm(-1); + + BuildMI(loop, dl, TII->get(MBlaze::BNEID)) + .addReg(NAMT) + .addMBB(loop); + + BuildMI(*finish, finish->begin(), dl, + TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + .addReg(IVAL).addMBB(MBB) + .addReg(NDST).addMBB(loop); + + // The pseudo instruction is no longer needed so remove it + MI->eraseFromParent(); + return finish; +} + +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomSelect(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // To "insert" a SELECT_CC instruction, we actually have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // setcc r1, r2, r3 + // bNE r1, r0, copy1MBB + // fallthrough --> copy0MBB + MachineFunction *F = MBB->getParent(); + MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB); + + unsigned Opc; + switch (MI->getOperand(4).getImm()) { + default: llvm_unreachable("Unknown branch condition"); + case MBlazeCC::EQ: Opc = MBlaze::BEQID; break; + case MBlazeCC::NE: Opc = MBlaze::BNEID; break; + case MBlazeCC::GT: Opc = MBlaze::BGTID; break; + case MBlazeCC::LT: Opc = MBlaze::BLTID; break; + case MBlazeCC::GE: Opc = MBlaze::BGEID; break; + case MBlazeCC::LE: Opc = MBlaze::BLEID; break; + } + + F->insert(It, flsBB); + F->insert(It, dneBB); + + // Transfer the remainder of MBB and its successor edges to dneBB. + dneBB->splice(dneBB->begin(), MBB, + llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + dneBB->transferSuccessorsAndUpdatePHIs(MBB); + + MBB->addSuccessor(flsBB); + MBB->addSuccessor(dneBB); + flsBB->addSuccessor(dneBB); + + BuildMI(MBB, dl, TII->get(Opc)) + .addReg(MI->getOperand(3).getReg()) + .addMBB(dneBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB) + // .addReg(MI->getOperand(2).getReg()).addMBB(BB); + + BuildMI(*dneBB, dneBB->begin(), dl, + TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()).addMBB(flsBB) + .addReg(MI->getOperand(1).getReg()).addMBB(MBB); + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return dneBB; +} + +MachineBasicBlock* +MBlazeTargetLowering::EmitCustomAtomic(MachineInstr *MI, + MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + // All atomic instructions on the Microblaze are implemented using the + // load-linked / store-conditional style atomic instruction sequences. + // Thus, all operations will look something like the following: + // + // start: + // lwx RV, RP, 0 + // + // swx RV, RP, 0 + // addic RC, R0, 0 + // bneid RC, start + // + // exit: + // + // To "insert" a shift left instruction, we actually have to insert a + // simple loop. The incoming instruction knows the destination vreg to + // set, the source vreg to operate over and the shift amount. + const BasicBlock *LLVM_BB = MBB->getBasicBlock(); + MachineFunction::iterator It = MBB; + ++It; + + // start: + // andi samt, samt, 31 + // beqid samt, finish + // add dst, src, r0 + // loop: + // addik samt, samt, -1 + // sra dst, dst + // bneid samt, loop + // nop + // finish: + MachineFunction *F = MBB->getParent(); + MachineRegisterInfo &R = F->getRegInfo(); + + // Create the start and exit basic blocks for the atomic operation + MachineBasicBlock *start = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exit = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, start); + F->insert(It, exit); + + // Update machine-CFG edges by transfering adding all successors and + // remaining instructions from the current block to the new block which + // will contain the Phi node for the select. + exit->splice(exit->begin(), MBB, llvm::next(MachineBasicBlock::iterator(MI)), + MBB->end()); + exit->transferSuccessorsAndUpdatePHIs(MBB); + + // Add the fallthrough block as its successors. + MBB->addSuccessor(start); + + BuildMI(start, dl, TII->get(MBlaze::LWX), MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addReg(MBlaze::R0); + + MachineBasicBlock *final = start; + unsigned finalReg = 0; + + switch (MI->getOpcode()) { + default: llvm_unreachable("Cannot lower unknown atomic instruction!"); + + case MBlaze::SWP32: + finalReg = MI->getOperand(2).getReg(); + start->addSuccessor(exit); + start->addSuccessor(start); + break; + + case MBlaze::LAN32: + case MBlaze::LAX32: + case MBlaze::LAO32: + case MBlaze::LAD32: + case MBlaze::LAS32: + case MBlaze::LAA32: { + unsigned opcode = 0; + switch (MI->getOpcode()) { + default: llvm_unreachable("Cannot lower unknown atomic load!"); + case MBlaze::LAA32: opcode = MBlaze::ADDIK; break; + case MBlaze::LAS32: opcode = MBlaze::RSUBIK; break; + case MBlaze::LAD32: opcode = MBlaze::AND; break; + case MBlaze::LAO32: opcode = MBlaze::OR; break; + case MBlaze::LAX32: opcode = MBlaze::XOR; break; + case MBlaze::LAN32: opcode = MBlaze::AND; break; } - F->insert(It, flsBB); - F->insert(It, dneBB); + finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass); + start->addSuccessor(exit); + start->addSuccessor(start); + + BuildMI(start, dl, TII->get(opcode), finalReg) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()); + + if (MI->getOpcode() == MBlaze::LAN32) { + unsigned tmp = finalReg; + finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(start, dl, TII->get(MBlaze::XORI), finalReg) + .addReg(tmp) + .addImm(-1); + } + break; + } - // Transfer the remainder of BB and its successor edges to dneBB. - dneBB->splice(dneBB->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - dneBB->transferSuccessorsAndUpdatePHIs(BB); - - BB->addSuccessor(flsBB); - BB->addSuccessor(dneBB); - flsBB->addSuccessor(dneBB); - - BuildMI(BB, dl, TII->get(Opc)) - .addReg(MI->getOperand(3).getReg()) - .addMBB(dneBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB) - // .addReg(MI->getOperand(2).getReg()).addMBB(BB); - - BuildMI(*dneBB, dneBB->begin(), dl, - TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) - .addReg(MI->getOperand(2).getReg()).addMBB(flsBB) - .addReg(MI->getOperand(1).getReg()).addMBB(BB); + case MBlaze::CAS32: { + finalReg = MI->getOperand(3).getReg(); + final = F->CreateMachineBasicBlock(LLVM_BB); + + F->insert(It, final); + start->addSuccessor(exit); + start->addSuccessor(final); + final->addSuccessor(exit); + final->addSuccessor(start); + + unsigned CMP = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(start, dl, TII->get(MBlaze::CMP), CMP) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(2).getReg()); + + BuildMI(start, dl, TII->get(MBlaze::BNEID)) + .addReg(CMP) + .addMBB(exit); - MI->eraseFromParent(); // The pseudo instruction is gone now. - return dneBB; + final->moveAfter(start); + exit->moveAfter(final); + break; } } + + unsigned CHK = R.createVirtualRegister(MBlaze::GPRRegisterClass); + BuildMI(final, dl, TII->get(MBlaze::SWX)) + .addReg(finalReg) + .addReg(MI->getOperand(1).getReg()) + .addReg(MBlaze::R0); + + BuildMI(final, dl, TII->get(MBlaze::ADDIC), CHK) + .addReg(MBlaze::R0) + .addImm(0); + + BuildMI(final, dl, TII->get(MBlaze::BNEID)) + .addReg(CHK) + .addMBB(start); + + // The pseudo instruction is no longer needed so remove it + MI->eraseFromParent(); + return exit; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h?rev=122384&r1=122383&r2=122384&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.h Tue Dec 21 19:15:01 2010 @@ -149,6 +149,15 @@ const SmallVectorImpl &OutVals, DebugLoc dl, SelectionDAG &DAG) const; + virtual MachineBasicBlock* + EmitCustomShift(MachineInstr *MI, MachineBasicBlock *MBB) const; + + virtual MachineBasicBlock* + EmitCustomSelect(MachineInstr *MI, MachineBasicBlock *MBB) const; + + virtual MachineBasicBlock* + EmitCustomAtomic(MachineInstr *MI, MachineBasicBlock *MBB) const; + virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122384&r1=122383&r2=122384&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Tue Dec 21 19:15:01 2010 @@ -669,6 +669,47 @@ "imm $imm", [], IIAlu>; //===----------------------------------------------------------------------===// +// Pseudo instructions for atomic operations +//===----------------------------------------------------------------------===// +let usesCustomInserter=1 in { + def CAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$cmp, GPR:$swp), + "# atomic compare and swap", + [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$cmp, GPR:$swp))]>; + + def SWP32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$swp), + "# atomic swap", + [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$swp))]>; + + def LAA32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and add", + [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$val))]>; + + def LAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and sub", + [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$val))]>; + + def LAD32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and and", + [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$val))]>; + + def LAO32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and or", + [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$val))]>; + + def LAX32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and xor", + [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$val))]>; + + def LAN32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and nand", + [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$val))]>; + + def MEMBARRIER : MBlazePseudo<(outs), (ins), + "# memory barrier", + [(membarrier (i32 imm), (i32 imm), (i32 imm), (i32 imm), (i32 imm))]>; +} + +//===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// From peckw at wesleypeck.com Tue Dec 21 19:29:32 2010 From: peckw at wesleypeck.com (Wesley Peck) Date: Wed, 22 Dec 2010 01:29:32 -0000 Subject: [llvm-commits] [llvm] r122385 - in /llvm/trunk/lib/Target/MBlaze: MBlazeInstrInfo.cpp MBlazeInstrInfo.td Message-ID: <20101222012932.394042A6C12C@llvm.org> Author: peckw Date: Tue Dec 21 19:29:32 2010 New Revision: 122385 URL: http://llvm.org/viewvc/llvm-project?rev=122385&view=rev Log: Don't generate carry bit when loading immediate values on the Microblaze. Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.cpp?rev=122385&r1=122384&r2=122385&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.cpp Tue Dec 21 19:29:32 2010 @@ -80,7 +80,7 @@ MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const { - llvm::BuildMI(MBB, I, DL, get(MBlaze::ADD), DestReg) + llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0); } Modified: llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td?rev=122385&r1=122384&r2=122385&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeInstrInfo.td Tue Dec 21 19:29:32 2010 @@ -714,7 +714,7 @@ //===----------------------------------------------------------------------===// // Small immediates -def : Pat<(i32 0), (ADD (i32 R0), (i32 R0))>; +def : Pat<(i32 0), (ADDK (i32 R0), (i32 R0))>; def : Pat<(i32 immSExt16:$imm), (ADDIK (i32 R0), imm:$imm)>; def : Pat<(i32 immZExt16:$imm), (ORI (i32 R0), imm:$imm)>; From clattner at apple.com Tue Dec 21 20:04:04 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 18:04:04 -0800 Subject: [llvm-commits] [llvm] r122353 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp In-Reply-To: <20101221200006.D16D32A6C12C@llvm.org> References: <20101221200006.D16D32A6C12C@llvm.org> Message-ID: <38476CE2-6095-4AB5-A50A-B0259B1BEBFB@apple.com> On Dec 21, 2010, at 12:00 PM, Dale Johannesen wrote: > Author: johannes > Date: Tue Dec 21 14:00:06 2010 > New Revision: 122353 > > URL: http://llvm.org/viewvc/llvm-project?rev=122353&view=rev > Log: > Shift by the word size is invalid IR; don't create it. I agree, but testcase? -Chris From clattner at apple.com Tue Dec 21 20:06:29 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 18:06:29 -0800 Subject: [llvm-commits] [llvm] r122370 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp In-Reply-To: <20101221222744.B008D2A6C12C@llvm.org> References: <20101221222744.B008D2A6C12C@llvm.org> Message-ID: <5A6EB962-9AA2-4C64-AB35-B497E8836F0A@apple.com> On Dec 21, 2010, at 2:27 PM, Andrew Trick wrote: > Author: atrick > Date: Tue Dec 21 16:27:44 2010 > New Revision: 122370 > > URL: http://llvm.org/viewvc/llvm-project?rev=122370&view=rev > Log: > In DelayForLiveRegsBottomUp, handle instructions that read and write > the same physical register. Simplifies the fix from the previous > checkin r122211. Great, does this happen to fix PR8823? -Chris > > > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122370&r1=122369&r2=122370&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Dec 21 16:27:44 2010 > @@ -660,9 +660,12 @@ > > SmallSet RegAdded; > // If this node would clobber any "live" register, then it's not ready. > + // > + // If SU is the currently live definition of the same register that it uses, > + // then we are free to schedule it. > for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); > I != E; ++I) { > - if (I->isAssignedRegDep()) > + if (I->isAssignedRegDep() && LiveRegDefs[I->getReg()] != SU) > CheckForLiveRegDef(I->getSUnit(), I->getReg(), LiveRegDefs, > RegAdded, LRegs, TRI); > } > @@ -703,20 +706,6 @@ > CheckForLiveRegDef(SU, *Reg, LiveRegDefs, RegAdded, LRegs, TRI); > } > > - > - // Okay, we now know all of the live registers that are defined by an > - // immediate predecessor. It is ok to kill these registers if we are also > - // using it. > - for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); > - I != E; ++I) { > - if (I->isAssignedRegDep() && > - LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) { > - unsigned Reg = I->getReg(); > - if (RegAdded.erase(Reg)) > - LRegs.erase(std::find(LRegs.begin(), LRegs.end(), Reg)); > - } > - } > - > return !LRegs.empty(); > } > > > > _______________________________________________ > 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 Dec 21 20:10:48 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 18:10:48 -0800 Subject: [llvm-commits] [llvm] r122343 - /llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp In-Reply-To: <4D110B86.6000300@free.fr> References: <20101221170855.588E82A6C131@llvm.org> <59630708-6AE9-4DBF-8BA6-B161CE96B8C5@apple.com> <4D110B86.6000300@free.fr> Message-ID: On Dec 21, 2010, at 12:18 PM, Duncan Sands wrote: > Hi Chris, > >>> Visit instructions deterministically. Use a FIFO so as to approximately >>> visit instructions before their uses, since InstructionSimplify does a >>> better job in that case. All this prompted by Frits van Bommel. >> >> Ok. If you're going to delay deleting instructions, it might be worthwhile to drop their operands so that "dead" instructions don't cause hasOneUse() checks to fail. > > since InstructionSimplify doesn't pay any attention to uses (it doesn't need > to since it only returns existing instructions) this doesn't matter. Ok! From clattner at apple.com Tue Dec 21 20:13:20 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Dec 2010 18:13:20 -0800 Subject: [llvm-commits] [llvm] r122364 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/conditional-indecrement.ll In-Reply-To: <20101221214144.536632A6C12C@llvm.org> References: <20101221214144.536632A6C12C@llvm.org> Message-ID: <7D5EA39D-3D57-46E5-91C1-F0876BC61E85@apple.com> On Dec 21, 2010, at 1:41 PM, Benjamin Kramer wrote: > Author: d0k > Date: Tue Dec 21 15:41:44 2010 > New Revision: 122364 > > URL: http://llvm.org/viewvc/llvm-project?rev=122364&view=rev > Log: > Add some x86 specific dagcombines for conditional increments. > > (add Y, (sete X, 0)) -> cmp X, 1; adc 0, Y > (add Y, (setne X, 0)) -> cmp X, 1; sbb -1, Y > (sub (sete X, 0), Y) -> cmp X, 1; sbb 0, Y > (sub (setne X, 0), Y) -> cmp X, 1; adc -1, Y Very nice. Do we handle the cases when X and Y are the same value? "X == 0 ? X+1 : X" simplifies to "X == 0 ? 1 : X". -Chris > > for > unsigned foo(unsigned a, unsigned b) { > if (a == 0) b++; > return b; > } > we now get: > foo: > cmpl $1, %edi > movl %esi, %eax > adcl $0, %eax > ret > instead of: > foo: > testl %edi, %edi > sete %al > movzbl %al, %eax > addl %esi, %eax > ret > > Added: > llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll > 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=122364&r1=122363&r2=122364&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 21 15:41:44 2010 > @@ -969,6 +969,8 @@ > setTargetDAGCombine(ISD::SRL); > setTargetDAGCombine(ISD::OR); > setTargetDAGCombine(ISD::AND); > + setTargetDAGCombine(ISD::ADD); > + setTargetDAGCombine(ISD::SUB); > setTargetDAGCombine(ISD::STORE); > setTargetDAGCombine(ISD::ZERO_EXTEND); > if (Subtarget->is64Bit()) > @@ -11513,6 +11515,44 @@ > return SDValue(); > } > > +// fold (add Y, (sete X, 0)) -> adc 0, Y > +// (add Y, (setne X, 0)) -> sbb -1, Y > +// (sub (sete X, 0), Y) -> sbb 0, Y > +// (sub (setne X, 0), Y) -> adc -1, Y > +static SDValue OptimizeConditonalInDecrement(SDNode *N, SelectionDAG &DAG) { > + DebugLoc DL = N->getDebugLoc(); > + > + // Look through ZExts. > + SDValue Ext = N->getOperand(N->getOpcode() == ISD::SUB ? 1 : 0); > + if (Ext.getOpcode() != ISD::ZERO_EXTEND || !Ext.hasOneUse()) > + return SDValue(); > + > + SDValue SetCC = Ext.getOperand(0); > + if (SetCC.getOpcode() != X86ISD::SETCC || !SetCC.hasOneUse()) > + return SDValue(); > + > + X86::CondCode CC = (X86::CondCode)SetCC.getConstantOperandVal(0); > + if (CC != X86::COND_E && CC != X86::COND_NE) > + return SDValue(); > + > + SDValue Cmp = SetCC.getOperand(1); > + if (Cmp.getOpcode() != X86ISD::CMP || !Cmp.hasOneUse() || > + !X86::isZeroNode(Cmp.getOperand(1))) > + return SDValue(); > + > + SDValue CmpOp0 = Cmp.getOperand(0); > + SDValue NewCmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, CmpOp0, > + DAG.getConstant(1, CmpOp0.getValueType())); > + > + SDValue OtherVal = N->getOperand(N->getOpcode() == ISD::SUB ? 0 : 1); > + if (CC == X86::COND_NE) > + return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::ADC : X86ISD::SBB, > + DL, OtherVal.getValueType(), OtherVal, > + DAG.getConstant(-1ULL, OtherVal.getValueType()), NewCmp); > + return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::SBB : X86ISD::ADC, > + DL, OtherVal.getValueType(), OtherVal, > + DAG.getConstant(0, OtherVal.getValueType()), NewCmp); > +} > > SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, > DAGCombinerInfo &DCI) const { > @@ -11523,6 +11563,8 @@ > return PerformEXTRACT_VECTOR_ELTCombine(N, DAG, *this); > case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget); > case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI); > + case ISD::ADD: > + case ISD::SUB: return OptimizeConditonalInDecrement(N, DAG); > case X86ISD::ADC: return PerformADCCombine(N, DAG, DCI); > case ISD::MUL: return PerformMulCombine(N, DAG, DCI); > case ISD::SHL: > > Added: llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll?rev=122364&view=auto > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll (added) > +++ llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll Tue Dec 21 15:41:44 2010 > @@ -0,0 +1,89 @@ > +; RUN: llc -march=x86 < %s | FileCheck %s > + > +define i32 @test1(i32 %a, i32 %b) nounwind readnone { > + %not.cmp = icmp ne i32 %a, 0 > + %inc = zext i1 %not.cmp to i32 > + %retval.0 = add i32 %inc, %b > + ret i32 %retval.0 > +; CHECK: test1: > +; CHECK: cmpl $1 > +; CHECK: sbbl $-1 > +; CHECK: ret > +} > + > +define i32 @test2(i32 %a, i32 %b) nounwind readnone { > + %cmp = icmp eq i32 %a, 0 > + %inc = zext i1 %cmp to i32 > + %retval.0 = add i32 %inc, %b > + ret i32 %retval.0 > +; CHECK: test2: > +; CHECK: cmpl $1 > +; CHECK: adcl $0 > +; CHECK: ret > +} > + > +define i32 @test3(i32 %a, i32 %b) nounwind readnone { > + %cmp = icmp eq i32 %a, 0 > + %inc = zext i1 %cmp to i32 > + %retval.0 = add i32 %inc, %b > + ret i32 %retval.0 > +; CHECK: test3: > +; CHECK: cmpl $1 > +; CHECK: adcl $0 > +; CHECK: ret > +} > + > +define i32 @test4(i32 %a, i32 %b) nounwind readnone { > + %not.cmp = icmp ne i32 %a, 0 > + %inc = zext i1 %not.cmp to i32 > + %retval.0 = add i32 %inc, %b > + ret i32 %retval.0 > +; CHECK: test4: > +; CHECK: cmpl $1 > +; CHECK: sbbl $-1 > +; CHECK: ret > +} > + > +define i32 @test5(i32 %a, i32 %b) nounwind readnone { > + %not.cmp = icmp ne i32 %a, 0 > + %inc = zext i1 %not.cmp to i32 > + %retval.0 = sub i32 %b, %inc > + ret i32 %retval.0 > +; CHECK: test5: > +; CHECK: cmpl $1 > +; CHECK: adcl $-1 > +; CHECK: ret > +} > + > +define i32 @test6(i32 %a, i32 %b) nounwind readnone { > + %cmp = icmp eq i32 %a, 0 > + %inc = zext i1 %cmp to i32 > + %retval.0 = sub i32 %b, %inc > + ret i32 %retval.0 > +; CHECK: test6: > +; CHECK: cmpl $1 > +; CHECK: sbbl $0 > +; CHECK: ret > +} > + > +define i32 @test7(i32 %a, i32 %b) nounwind readnone { > + %cmp = icmp eq i32 %a, 0 > + %inc = zext i1 %cmp to i32 > + %retval.0 = sub i32 %b, %inc > + ret i32 %retval.0 > +; CHECK: test7: > +; CHECK: cmpl $1 > +; CHECK: sbbl $0 > +; CHECK: ret > +} > + > +define i32 @test8(i32 %a, i32 %b) nounwind readnone { > + %not.cmp = icmp ne i32 %a, 0 > + %inc = zext i1 %not.cmp to i32 > + %retval.0 = sub i32 %b, %inc > + ret i32 %retval.0 > +; CHECK: test8: > +; CHECK: cmpl $1 > +; CHECK: adcl $-1 > +; CHECK: ret > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Dec 22 01:36:50 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 22 Dec 2010 07:36:50 -0000 Subject: [llvm-commits] [llvm] r122389 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20101222073650.ADD1D2A6C12C@llvm.org> Author: lattner Date: Wed Dec 22 01:36:50 2010 New Revision: 122389 URL: http://llvm.org/viewvc/llvm-project?rev=122389&view=rev Log: reduce indentation and improve comments, no functionality change. 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=122389&r1=122388&r2=122389&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 22 01:36:50 2010 @@ -4242,7 +4242,6 @@ // of the extended byte. This is not worth optimizing for. if (ShAmt >= VT.getSizeInBits()) return SDValue(); - } } @@ -4250,67 +4249,70 @@ // we can fold the truncate through the shift. unsigned ShLeftAmt = 0; if (ShAmt == 0 && N0.getOpcode() == ISD::SHL && N0.hasOneUse() && - ExtVT == VT && - TLI.isNarrowingProfitable(N0.getValueType(), VT)) { + ExtVT == VT && TLI.isNarrowingProfitable(N0.getValueType(), VT)) { if (ConstantSDNode *N01 = dyn_cast(N0.getOperand(1))) { ShLeftAmt = N01->getZExtValue(); N0 = N0.getOperand(0); } } + + // If we haven't found a load, we can't narrow it. Don't transform one with + // multiple uses, this would require adding a new load. + if (!isa(N0) || !N0.hasOneUse() || + // Don't change the width of a volatile load. + cast(N0)->isVolatile()) + return SDValue(); // 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 (isa(N0) && N0.hasOneUse() && ExtVT.isRound() && - cast(N0)->getMemoryVT().getSizeInBits() >= EVTBits && - // Do not change the width of a volatile load. - !cast(N0)->isVolatile()) { - LoadSDNode *LN0 = cast(N0); - EVT PtrType = N0.getOperand(1).getValueType(); - - // For big endian targets, we need to adjust the offset to the pointer to - // load the correct bytes. - if (TLI.isBigEndian()) { - unsigned LVTStoreBits = LN0->getMemoryVT().getStoreSizeInBits(); - unsigned EVTStoreBits = ExtVT.getStoreSizeInBits(); - ShAmt = LVTStoreBits - EVTStoreBits - ShAmt; - } - - uint64_t PtrOff = ShAmt / 8; - unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); - SDValue NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(), - PtrType, LN0->getBasePtr(), - DAG.getConstant(PtrOff, PtrType)); - AddToWorkList(NewPtr.getNode()); - - SDValue Load = (ExtType == ISD::NON_EXTLOAD) - ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, - LN0->getPointerInfo().getWithOffset(PtrOff), - LN0->isVolatile(), LN0->isNonTemporal(), NewAlign) - : DAG.getExtLoad(ExtType, VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, - LN0->getPointerInfo().getWithOffset(PtrOff), - ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), - NewAlign); - - // Replace the old load's chain with the new load's chain. - WorkListRemover DeadNodes(*this); - DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1), - &DeadNodes); + if (!ExtVT.isRound() || + cast(N0)->getMemoryVT().getSizeInBits() < EVTBits) + return SDValue(); + + LoadSDNode *LN0 = cast(N0); + EVT PtrType = N0.getOperand(1).getValueType(); + + // For big endian targets, we need to adjust the offset to the pointer to + // load the correct bytes. + if (TLI.isBigEndian()) { + unsigned LVTStoreBits = LN0->getMemoryVT().getStoreSizeInBits(); + unsigned EVTStoreBits = ExtVT.getStoreSizeInBits(); + ShAmt = LVTStoreBits - EVTStoreBits - ShAmt; + } + + uint64_t PtrOff = ShAmt / 8; + unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); + SDValue NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(), + PtrType, LN0->getBasePtr(), + DAG.getConstant(PtrOff, PtrType)); + AddToWorkList(NewPtr.getNode()); + + SDValue Load = (ExtType == ISD::NON_EXTLOAD) + ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, + LN0->getPointerInfo().getWithOffset(PtrOff), + LN0->isVolatile(), LN0->isNonTemporal(), NewAlign) + : DAG.getExtLoad(ExtType, VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, + LN0->getPointerInfo().getWithOffset(PtrOff), + ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), + NewAlign); - // Shift the result left, if we've swallowed a left shift. - SDValue Result = Load; - if (ShLeftAmt != 0) { - EVT ShImmTy = getShiftAmountTy(); - if (!isUIntN(ShImmTy.getSizeInBits(), ShLeftAmt)) - ShImmTy = VT; - Result = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT, - Result, DAG.getConstant(ShLeftAmt, ShImmTy)); - } + // Replace the old load's chain with the new load's chain. + WorkListRemover DeadNodes(*this); + DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1), + &DeadNodes); - // Return the new loaded value. - return Result; + // Shift the result left, if we've swallowed a left shift. + SDValue Result = Load; + if (ShLeftAmt != 0) { + EVT ShImmTy = getShiftAmountTy(); + if (!isUIntN(ShImmTy.getSizeInBits(), ShLeftAmt)) + ShImmTy = VT; + Result = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT, + Result, DAG.getConstant(ShLeftAmt, ShImmTy)); } - return SDValue(); + // Return the new loaded value. + return Result; } SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { From sabre at nondot.org Wed Dec 22 02:01:44 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 22 Dec 2010 08:01:44 -0000 Subject: [llvm-commits] [llvm] r122391 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20101222080144.63FC42A6C12C@llvm.org> Author: lattner Date: Wed Dec 22 02:01:44 2010 New Revision: 122391 URL: http://llvm.org/viewvc/llvm-project?rev=122391&view=rev Log: more cleanups, move a check for "roundedness" earlier to reject unhanded cases faster and simplify code. 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=122391&r1=122390&r2=122391&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 22 02:01:44 2010 @@ -4223,8 +4223,14 @@ } unsigned EVTBits = ExtVT.getSizeInBits(); + + // 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 (!ExtVT.isRound()) + return SDValue(); + unsigned ShAmt = 0; - if (N0.getOpcode() == ISD::SRL && N0.hasOneUse() && ExtVT.isRound()) { + if (N0.getOpcode() == ISD::SRL && N0.hasOneUse()) { if (ConstantSDNode *N01 = dyn_cast(N0.getOperand(1))) { ShAmt = N01->getZExtValue(); // Is the shift amount a multiple of size of VT? @@ -4262,11 +4268,9 @@ // Don't change the width of a volatile load. cast(N0)->isVolatile()) return SDValue(); - - // 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 (!ExtVT.isRound() || - cast(N0)->getMemoryVT().getSizeInBits() < EVTBits) + + // Verify that we are actually reducing a load width here. + if (cast(N0)->getMemoryVT().getSizeInBits() < EVTBits) return SDValue(); LoadSDNode *LN0 = cast(N0); @@ -4287,14 +4291,16 @@ DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.getNode()); - SDValue Load = (ExtType == ISD::NON_EXTLOAD) - ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, - LN0->getPointerInfo().getWithOffset(PtrOff), - LN0->isVolatile(), LN0->isNonTemporal(), NewAlign) - : DAG.getExtLoad(ExtType, VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, - LN0->getPointerInfo().getWithOffset(PtrOff), - ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), - NewAlign); + SDValue Load; + if (ExtType == ISD::NON_EXTLOAD) + Load = DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, + LN0->getPointerInfo().getWithOffset(PtrOff), + LN0->isVolatile(), LN0->isNonTemporal(), NewAlign); + else + Load = DAG.getExtLoad(ExtType, VT, N0.getDebugLoc(), LN0->getChain(),NewPtr, + LN0->getPointerInfo().getWithOffset(PtrOff), + ExtVT, LN0->isVolatile(), LN0->isNonTemporal(), + NewAlign); // Replace the old load's chain with the new load's chain. WorkListRemover DeadNodes(*this); From sabre at nondot.org Wed Dec 22 02:02:58 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 22 Dec 2010 08:02:58 -0000 Subject: [llvm-commits] [llvm] r122392 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/narrow-shl-load.ll Message-ID: <20101222080258.339232A6C12C@llvm.org> Author: lattner Date: Wed Dec 22 02:02:57 2010 New Revision: 122392 URL: http://llvm.org/viewvc/llvm-project?rev=122392&view=rev Log: Fix a bug in ReduceLoadWidth that wasn't handling extending loads properly. We miscompiled the testcase into: _test: ## @test movl $128, (%rdi) movzbl 1(%rdi), %eax ret Now we get a proper: _test: ## @test movl $128, (%rdi) movsbl (%rdi), %eax movzbl %ah, %eax ret This fixes PR8757. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/narrow-shl-load.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122392&r1=122391&r2=122392&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 22 02:02:57 2010 @@ -4241,12 +4241,15 @@ return SDValue(); } + // At this point, we must have a load or else we can't do the transform. + if (!isa(N0)) return SDValue(); + // If the shift amount is larger than the input type then we're not // accessing any of the loaded bytes. If the load was a zextload/extload // then the result of the shift+trunc is zero/undef (handled elsewhere). // If the load was a sextload then the result is a splat of the sign bit // of the extended byte. This is not worth optimizing for. - if (ShAmt >= VT.getSizeInBits()) + if (ShAmt >= cast(N0)->getMemoryVT().getSizeInBits()) return SDValue(); } } Modified: llvm/trunk/test/CodeGen/X86/narrow-shl-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/narrow-shl-load.ll?rev=122392&r1=122391&r2=122392&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/narrow-shl-load.ll (original) +++ llvm/trunk/test/CodeGen/X86/narrow-shl-load.ll Wed Dec 22 02:02:57 2010 @@ -6,7 +6,7 @@ ; DAGCombiner should fold this code in finite time. ; rdar://8606584 -define void @D() nounwind readnone { +define void @test1() nounwind readnone { bb.nph: br label %while.cond @@ -33,10 +33,10 @@ ; DAGCombiner shouldn't fold the sdiv (ashr) away. ; rdar://8636812 -; CHECK: main: +; CHECK: test2: ; CHECK: sarl -define i32 @main() nounwind { +define i32 @test2() nounwind { entry: %i = alloca i32, align 4 %j = alloca i8, align 1 @@ -63,3 +63,21 @@ declare void @abort() noreturn declare void @exit(i32) noreturn + +; DAG Combiner can't fold this into a load of the 1'th byte. +; PR8757 +define i32 @test3(i32 *%P) nounwind ssp { + volatile store i32 128, i32* %P + %tmp4.pre = load i32* %P + %phitmp = trunc i32 %tmp4.pre to i16 + %phitmp13 = shl i16 %phitmp, 8 + %phitmp14 = ashr i16 %phitmp13, 8 + %phitmp15 = lshr i16 %phitmp14, 8 + %phitmp16 = zext i16 %phitmp15 to i32 + ret i32 %phitmp16 + +; CHECK: movl $128, (%rdi) +; CHECK-NEXT: movsbl (%rdi), %eax +; CHECK-NEXT: movzbl %ah, %eax +; CHECK-NEXT: ret +} From ofv at wanadoo.es Wed Dec 22 02:30:17 2010 From: ofv at wanadoo.es (Oscar Fuentes) Date: Wed, 22 Dec 2010 08:30:17 -0000 Subject: [llvm-commits] [llvm] r122395 - /llvm/trunk/cmake/modules/AddLLVM.cmake Message-ID: <20101222083017.39DB12A6C12D@llvm.org> Author: ofv Date: Wed Dec 22 02:30:17 2010 New Revision: 122395 URL: http://llvm.org/viewvc/llvm-project?rev=122395&view=rev Log: Fixes file extension for loadable modules on OS X. Patch by Wesley Peck! 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=122395&r1=122394&r2=122395&view=diff ============================================================================== --- llvm/trunk/cmake/modules/AddLLVM.cmake (original) +++ llvm/trunk/cmake/modules/AddLLVM.cmake Wed Dec 22 02:30:17 2010 @@ -36,7 +36,13 @@ add_custom_target(${name}) else() llvm_process_sources( ALL_FILES ${ARGN} ) - add_library( ${name} MODULE ${ALL_FILES} ) + if (MODULE) + set(libkind MODULE) + else() + set(libkind SHARED) + endif() + + add_library( ${name} ${libkind} ${ALL_FILES} ) set_target_properties( ${name} PROPERTIES PREFIX "" ) if (APPLE) From baldrick at free.fr Wed Dec 22 03:33:24 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Dec 2010 10:33:24 +0100 Subject: [llvm-commits] [llvm] r122326 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/ test/Transforms/InstSimplify/2010-12-20-Reassociate.ll test/Transforms/InstSimplify/dg.exp In-Reply-To: <8378C911-1AA6-4372-995A-0CB82FCEF42C@apple.com> References: <20101221084900.DFBF42A6C12D@llvm.org> <8378C911-1AA6-4372-995A-0CB82FCEF42C@apple.com> Message-ID: <4D11C5E4.6020601@free.fr> Hi Chris, >> Add generic simplification of associative operations, generalizing >> a couple of existing transforms. This fires surprisingly often, for >> example when compiling gcc "(X+(-1))+1->X" fires quite a lot as well >> as various "and" simplifications (usually with a phi node operand). >> Most of the time this doesn't make a real difference since the same >> thing would have been done elsewhere anyway, eg: by instcombine, but >> there are a few places where this results in simplifications that we >> were not doing before. > > Nice. Should the related logic get ripped out of instcombine? It is probably a little more general, but if it doesn't matter in practice, we should remove it. when running std-compile-opts on gcc-as-one-big-file, this logic in InstructionSimplify succeeds 171 times, while the corresponding logic in InstCombine succeeds 4095 times. As a point of comparison, InstCombine does 3536 constant folds on this testcase. It is not surprising that instcombine succeeds so much more often, as instsimplify is hugely constrained by the requirement that it is only allowed to simplify to existing instructions, it is not allowed to create any new instructions. That said, if instsimplify was allowed to modify instructions in place then I think for reassociation it would catch everything. Ciao, Duncan. From baldrick at free.fr Wed Dec 22 03:40:51 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Dec 2010 09:40:51 -0000 Subject: [llvm-commits] [llvm] r122397 - in /llvm/trunk/lib: Analysis/InstructionSimplify.cpp Transforms/InstCombine/InstructionCombining.cpp Message-ID: <20101222094051.B83F82A6C12C@llvm.org> Author: baldrick Date: Wed Dec 22 03:40:51 2010 New Revision: 122397 URL: http://llvm.org/viewvc/llvm-project?rev=122397&view=rev Log: Add some statistics, good for understanding how much more powerful instcombine is compared to instsimplify. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122397&r1=122396&r2=122397&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed Dec 22 03:40:51 2010 @@ -17,6 +17,8 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "instsimplify" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/Dominators.h" @@ -28,6 +30,10 @@ #define RecursionLimit 3 +STATISTIC(NumExpand, "Number of expansions"); +STATISTIC(NumFactor , "Number of factorizations"); +STATISTIC(NumReassoc, "Number of reassociations"); + static Value *SimplifyAndInst(Value *, Value *, const TargetData *, const DominatorTree *, unsigned); static Value *SimplifyBinOp(unsigned, Value *, Value *, const TargetData *, @@ -81,12 +87,17 @@ if (Value *R = SimplifyBinOp(Opcode, B, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "A op' B" then "L op' R" is just the LHS. - if ((L == A && R == B) || - (Instruction::isCommutative(OpcodeToExpand) && L == B && R == A)) + if ((L == A && R == B) || (Instruction::isCommutative(OpcodeToExpand) + && L == B && R == A)) { + ++NumExpand; return LHS; + } // Otherwise return "L op' R" if it simplifies. - if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse)) + if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT, + MaxRecurse)) { + ++NumExpand; return V; + } } } @@ -100,12 +111,17 @@ if (Value *R = SimplifyBinOp(Opcode, A, C, TD, DT, MaxRecurse)) { // They do! Return "L op' R" if it simplifies or is already available. // If "L op' R" equals "B op' C" then "L op' R" is just the RHS. - if ((L == B && R == C) || - (Instruction::isCommutative(OpcodeToExpand) && L == C && R == B)) + if ((L == B && R == C) || (Instruction::isCommutative(OpcodeToExpand) + && L == C && R == B)) { + ++NumExpand; return RHS; + } // Otherwise return "L op' R" if it simplifies. - if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT,MaxRecurse)) + if (Value *V = SimplifyBinOp(OpcodeToExpand, L, R, TD, DT, + MaxRecurse)) { + ++NumExpand; return V; + } } } @@ -144,10 +160,15 @@ if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) { // It does! Return "A op' V" if it simplifies or is already available. // If V equals B then "A op' V" is just the LHS. - if (V == B) return LHS; + if (V == B) { + ++NumFactor; + return LHS; + } // Otherwise return "A op' V" if it simplifies. - if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) { + ++NumFactor; return W; + } } } @@ -161,10 +182,15 @@ if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) { // It does! Return "V op' B" if it simplifies or is already available. // If V equals A then "V op' B" is just the LHS. - if (V == B) return LHS; + if (V == B) { + ++NumFactor; + return LHS; + } // Otherwise return "V op' B" if it simplifies. - if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) { + ++NumFactor; return W; + } } } @@ -198,8 +224,10 @@ // If V equals B then "A op V" is just the LHS. if (V == B) return LHS; // Otherwise return "A op V" if it simplifies. - if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(Opcode, A, V, TD, DT, MaxRecurse)) { + ++NumReassoc; return W; + } } } @@ -215,8 +243,10 @@ // If V equals B then "V op C" is just the RHS. if (V == B) return RHS; // Otherwise return "V op C" if it simplifies. - if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(Opcode, V, C, TD, DT, MaxRecurse)) { + ++NumReassoc; return W; + } } } @@ -236,8 +266,10 @@ // If V equals A then "V op B" is just the LHS. if (V == A) return LHS; // Otherwise return "V op B" if it simplifies. - if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(Opcode, V, B, TD, DT, MaxRecurse)) { + ++NumReassoc; return W; + } } } @@ -253,8 +285,10 @@ // If V equals C then "B op V" is just the RHS. if (V == C) return RHS; // Otherwise return "B op V" if it simplifies. - if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) + if (Value *W = SimplifyBinOp(Opcode, B, V, TD, DT, MaxRecurse)) { + ++NumReassoc; return W; + } } } Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=122397&r1=122396&r2=122397&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Wed Dec 22 03:40:51 2010 @@ -58,6 +58,8 @@ STATISTIC(NumConstProp, "Number of constant folds"); STATISTIC(NumDeadInst , "Number of dead inst eliminated"); STATISTIC(NumSunkInst , "Number of instructions sunk"); +STATISTIC(NumFactor , "Number of factorizations"); +STATISTIC(NumReassoc , "Number of reassociations"); // Initialization Routines void llvm::initializeInstCombine(PassRegistry &Registry) { @@ -155,6 +157,7 @@ I.setOperand(0, A); I.setOperand(1, V); Changed = true; + ++NumReassoc; continue; } } @@ -171,6 +174,7 @@ I.setOperand(0, V); I.setOperand(1, C); Changed = true; + ++NumReassoc; continue; } } @@ -189,6 +193,7 @@ I.setOperand(0, V); I.setOperand(1, B); Changed = true; + ++NumReassoc; continue; } } @@ -205,6 +210,7 @@ I.setOperand(0, B); I.setOperand(1, V); Changed = true; + ++NumReassoc; continue; } } @@ -321,8 +327,10 @@ // operations "A op' B" and "C op' D" will be zapped since no longer used. if (!RHS && Op0->hasOneUse() && Op1->hasOneUse()) RHS = Builder->CreateBinOp(OuterOpcode, B, D, Op1->getName()); - if (RHS) + if (RHS) { + ++NumFactor; return BinaryOperator::Create(InnerOpcode, A, RHS); + } } // Does "(X op Y) op' Z" always equal "(X op' Z) op (Y op' Z)"? @@ -339,8 +347,10 @@ // operations "A op' B" and "C op' D" will be zapped since no longer used. if (!LHS && Op0->hasOneUse() && Op1->hasOneUse()) LHS = Builder->CreateBinOp(OuterOpcode, A, C, Op0->getName()); - if (LHS) + if (LHS) { + ++NumFactor; return BinaryOperator::Create(InnerOpcode, LHS, B); + } } return 0; From clchiou at gmail.com Wed Dec 22 04:38:51 2010 From: clchiou at gmail.com (Che-Liang Chiou) Date: Wed, 22 Dec 2010 10:38:51 -0000 Subject: [llvm-commits] [llvm] r122398 - in /llvm/trunk: lib/Target/PTX/PTXAsmPrinter.cpp lib/Target/PTX/PTXISelDAGToDAG.cpp lib/Target/PTX/PTXISelLowering.cpp lib/Target/PTX/PTXISelLowering.h lib/Target/PTX/PTXInstrInfo.td lib/Target/PTX/PTXMCAsmStreamer.cpp test/CodeGen/PTX/ld.ll Message-ID: <20101222103851.82DC92A6C12C@llvm.org> Author: clchiou Date: Wed Dec 22 04:38:51 2010 New Revision: 122398 URL: http://llvm.org/viewvc/llvm-project?rev=122398&view=rev Log: ptx: add ld instruction and test Added: llvm/trunk/test/CodeGen/PTX/ld.ll Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp llvm/trunk/lib/Target/PTX/PTXISelLowering.h llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/lib/Target/PTX/PTXMCAsmStreamer.cpp Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Wed Dec 22 04:38:51 2010 @@ -17,7 +17,8 @@ #include "PTX.h" #include "PTXMachineFunctionInfo.h" #include "PTXTargetMachine.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -25,11 +26,13 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -50,6 +53,8 @@ const char *getPassName() const { return "PTX Assembly Printer"; } + bool doFinalization(Module &M); + virtual void EmitStartOfAsmFile(Module &M); virtual bool runOnMachineFunction(MachineFunction &MF); @@ -68,6 +73,7 @@ static const char *getRegisterName(unsigned RegNo); private: + void EmitVariableDeclaration(const GlobalVariable *gv); void EmitFunctionDeclaration(); }; // class PTXAsmPrinter } // namespace @@ -96,11 +102,54 @@ return NULL; } +static const char *getStateSpaceName(unsigned addressSpace) { + if (addressSpace <= 255) + return "global"; + // TODO Add more state spaces + + llvm_unreachable("Unknown state space"); + return NULL; +} + +bool PTXAsmPrinter::doFinalization(Module &M) { + // XXX Temproarily remove global variables so that doFinalization() will not + // emit them again (global variables are emitted at beginning). + + Module::GlobalListType &global_list = M.getGlobalList(); + int i, n = global_list.size(); + GlobalVariable **gv_array = new GlobalVariable* [n]; + + // first, back-up GlobalVariable in gv_array + i = 0; + for (Module::global_iterator I = global_list.begin(), E = global_list.end(); + I != E; ++I) + gv_array[i++] = &*I; + + // second, empty global_list + while (!global_list.empty()) + global_list.remove(global_list.begin()); + + // call doFinalization + bool ret = AsmPrinter::doFinalization(M); + + // now we restore global variables + for (i = 0; i < n; i ++) + global_list.insert(global_list.end(), gv_array[i]); + + delete[] gv_array; + return ret; +} + void PTXAsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer.EmitRawText(Twine("\t.version " + OptPTXVersion)); OutStreamer.EmitRawText(Twine("\t.target " + OptPTXTarget)); OutStreamer.AddBlankLine(); + + // declare global variables + for (Module::const_global_iterator i = M.global_begin(), e = M.global_end(); + i != e; ++i) + EmitVariableDeclaration(i); } bool PTXAsmPrinter::runOnMachineFunction(MachineFunction &MF) { @@ -156,12 +205,15 @@ default: llvm_unreachable(""); break; - case MachineOperand::MO_Register: - OS << getRegisterName(MO.getReg()); + case MachineOperand::MO_GlobalAddress: + OS << *Mang->getSymbol(MO.getGlobal()); break; case MachineOperand::MO_Immediate: OS << (int) MO.getImm(); break; + case MachineOperand::MO_Register: + OS << getRegisterName(MO.getReg()); + break; } } @@ -176,6 +228,49 @@ printOperand(MI, opNum+1, OS); } +void PTXAsmPrinter::EmitVariableDeclaration(const GlobalVariable *gv) { + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(gv)) + return; + + MCSymbol *gvsym = Mang->getSymbol(gv); + + assert(gvsym->isUndefined() && "Cannot define a symbol twice!"); + + std::string decl; + + // check if it is defined in some other translation unit + if (gv->isDeclaration()) + decl += ".extern "; + + // state space: e.g., .global + decl += "."; + decl += getStateSpaceName(gv->getType()->getAddressSpace()); + decl += " "; + + // alignment (optional) + unsigned alignment = gv->getAlignment(); + if (alignment != 0) { + decl += ".align "; + decl += utostr(Log2_32(gv->getAlignment())); + decl += " "; + } + + // TODO: add types + decl += ".s32 "; + + decl += gvsym->getName(); + + if (ArrayType::classof(gv->getType()) || PointerType::classof(gv->getType())) + decl += "[]"; + + decl += ";"; + + OutStreamer.EmitRawText(Twine(decl)); + + OutStreamer.AddBlankLine(); +} + void PTXAsmPrinter::EmitFunctionDeclaration() { // The function label could have already been emitted if two symbols end up // conflicting due to asm renaming. Detect this and emit an error. @@ -212,7 +307,7 @@ for (int i = 0, e = MFI->getNumArg(); i != e; ++i) { if (i != 0) decl += ", "; - decl += ".param .s32 "; // TODO: param's type + decl += ".param .s32 "; // TODO: add types decl += PARAM_PREFIX; decl += utostr(i + 1); } Modified: llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXISelDAGToDAG.cpp Wed Dec 22 04:38:51 2010 @@ -32,6 +32,7 @@ SDNode *Select(SDNode *Node); // Complex Pattern Selectors. + bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2); bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset); bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset); @@ -39,8 +40,8 @@ #include "PTXGenDAGISel.inc" private: - bool isImm (const SDValue &operand); - bool SelectImm (const SDValue &operand, SDValue &imm); + bool isImm(const SDValue &operand); + bool SelectImm(const SDValue &operand, SDValue &imm); }; // class PTXDAGToDAGISel } // namespace @@ -60,35 +61,61 @@ return SelectCode(Node); } -// Match memory operand of the form [reg+reg] and [reg+imm] +// Match memory operand of the form [reg+reg] +bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { + if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || + isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) + return false; + + R1 = Addr.getOperand(0); + R2 = Addr.getOperand(1); + return true; +} + +// Match memory operand of the form [reg], [imm+reg], and [reg+imm] bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset) { + if (Addr.getOpcode() != ISD::ADD) { + if (isImm(Addr)) + return false; + // is [reg] but not [imm] + Base = Addr; + Offset = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + + // let SelectADDRii handle the [imm+imm] case if (Addr.getNumOperands() >= 2 && isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) - return false; // let SelectADDRii handle the [imm+imm] case + return false; // try [reg+imm] and [imm+reg] - if (Addr.getOpcode() == ISD::ADD) - for (int i = 0; i < 2; i ++) - if (SelectImm(Addr.getOperand(1-i), Offset)) { - Base = Addr.getOperand(i); - return true; - } - - // okay, it's [reg+reg] - Base = Addr; - Offset = CurDAG->getTargetConstant(0, MVT::i32); - return true; + for (int i = 0; i < 2; i ++) + if (SelectImm(Addr.getOperand(1-i), Offset)) { + Base = Addr.getOperand(i); + return true; + } + + // either [reg+imm] and [imm+reg] + for (int i = 0; i < 2; i ++) + if (SelectImm(Addr.getOperand(1-i), Offset)) { + Base = Addr.getOperand(i); + return true; + } + + return false; } // Match memory operand of the form [imm+imm] and [imm] bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset) { + // is [imm+imm]? if (Addr.getOpcode() == ISD::ADD) { return SelectImm(Addr.getOperand(0), Base) && SelectImm(Addr.getOperand(1), Offset); } + // is [imm]? if (SelectImm(Addr, Base)) { Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp Wed Dec 22 04:38:51 2010 @@ -29,10 +29,22 @@ addRegisterClass(MVT::i1, PTX::PredsRegisterClass); addRegisterClass(MVT::i32, PTX::RRegs32RegisterClass); + setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); + + // Customize translation of memory addresses + setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + // Compute derived properties from the register classes computeRegisterProperties(); } +SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { + switch (Op.getOpcode()) { + default: llvm_unreachable("Unimplemented operand"); + case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + } +} + const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: llvm_unreachable("Unknown opcode"); @@ -42,6 +54,18 @@ } //===----------------------------------------------------------------------===// +// Custom Lower Operation +//===----------------------------------------------------------------------===// + +SDValue PTXTargetLowering:: +LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { + EVT PtrVT = getPointerTy(); + DebugLoc dl = Op.getDebugLoc(); + const GlobalValue *GV = cast(Op)->getGlobal(); + return DAG.getTargetGlobalAddress(GV, dl, PtrVT); +} + +//===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelLowering.h?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelLowering.h (original) +++ llvm/trunk/lib/Target/PTX/PTXISelLowering.h Wed Dec 22 04:38:51 2010 @@ -38,6 +38,8 @@ virtual unsigned getFunctionAlignment(const Function *F) const { return 2; } + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; + virtual SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, @@ -55,6 +57,9 @@ const SmallVectorImpl &OutVals, DebugLoc dl, SelectionDAG &DAG) const; + + private: + SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; }; // class PTXTargetLowering } // namespace llvm Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Wed Dec 22 04:38:51 2010 @@ -29,10 +29,15 @@ }]>; // Addressing modes. +def ADDRrr : ComplexPattern; def ADDRri : ComplexPattern; def ADDRii : ComplexPattern; // Address operands +def MEMrr : Operand { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops RRegs32, RRegs32); +} def MEMri : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops RRegs32, i32imm); @@ -88,6 +93,10 @@ } multiclass PTX_LD { + def rr : InstPTX<(outs RC:$d), + (ins MEMrr:$a), + !strconcat(opstr, ".%type\t$d, [$a]"), + [(set RC:$d, (pat_load ADDRrr:$a))]>; def ri : InstPTX<(outs RC:$d), (ins MEMri:$a), !strconcat(opstr, ".%type\t$d, [$a]"), Modified: llvm/trunk/lib/Target/PTX/PTXMCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXMCAsmStreamer.cpp?rev=122398&r1=122397&r2=122398&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXMCAsmStreamer.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXMCAsmStreamer.cpp Wed Dec 22 04:38:51 2010 @@ -11,8 +11,8 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" @@ -102,8 +102,7 @@ virtual void SwitchSection(const MCSection *Section); - virtual void InitSections() { - } + virtual void InitSections() {} virtual void EmitLabel(MCSymbol *Symbol); Added: llvm/trunk/test/CodeGen/PTX/ld.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/ld.ll?rev=122398&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PTX/ld.ll (added) +++ llvm/trunk/test/CodeGen/PTX/ld.ll Wed Dec 22 04:38:51 2010 @@ -0,0 +1,44 @@ +; RUN: llc < %s -march=ptx | FileCheck %s + +;CHECK: .extern .global .s32 array[]; + at array = external global [10 x i32] + +define ptx_device i32 @t1(i32* %p) { +entry: +;CHECK: ld.global.s32 r0, [r1]; + %x = load i32* %p + ret i32 %x +} + +define ptx_device i32 @t2(i32* %p) { +entry: +;CHECK: ld.global.s32 r0, [r1+4]; + %i = getelementptr i32* %p, i32 1 + %x = load i32* %i + ret i32 %x +} + +define ptx_device i32 @t3(i32* %p, i32 %q) { +entry: +;CHECK: shl.b32 r0, r2, 2; +;CHECK: ld.global.s32 r0, [r1+r0]; + %i = getelementptr i32* %p, i32 %q + %x = load i32* %i + ret i32 %x +} + +define ptx_device i32 @t4() { +entry: +;CHECK: ld.global.s32 r0, [array]; + %i = getelementptr [10 x i32]* @array, i32 0, i32 0 + %x = load i32* %i + ret i32 %x +} + +define ptx_device i32 @t5() { +entry: +;CHECK: ld.global.s32 r0, [array+4]; + %i = getelementptr [10 x i32]* @array, i32 0, i32 1 + %x = load i32* %i + ret i32 %x +} From benny.kra at googlemail.com Wed Dec 22 06:42:54 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 22 Dec 2010 13:42:54 +0100 Subject: [llvm-commits] [llvm] r122364 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/conditional-indecrement.ll In-Reply-To: <7D5EA39D-3D57-46E5-91C1-F0876BC61E85@apple.com> References: <20101221214144.536632A6C12C@llvm.org> <7D5EA39D-3D57-46E5-91C1-F0876BC61E85@apple.com> Message-ID: <48D6FE29-F6B4-4166-819F-C0B32D087FCC@gmail.com> On 22.12.2010, at 03:13, Chris Lattner wrote: > > On Dec 21, 2010, at 1:41 PM, Benjamin Kramer wrote: > >> Author: d0k >> Date: Tue Dec 21 15:41:44 2010 >> New Revision: 122364 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122364&view=rev >> Log: >> Add some x86 specific dagcombines for conditional increments. >> >> (add Y, (sete X, 0)) -> cmp X, 1; adc 0, Y >> (add Y, (setne X, 0)) -> cmp X, 1; sbb -1, Y >> (sub (sete X, 0), Y) -> cmp X, 1; sbb 0, Y >> (sub (setne X, 0), Y) -> cmp X, 1; adc -1, Y > > Very nice. Do we handle the cases when X and Y are the same value? "X == 0 ? X+1 : X" simplifies to "X == 0 ? 1 : X". $ cat t.c unsigned foo(unsigned x) { if (x == 0) x++; return x; } $ clang -O3 t.c _foo: cmpl $1, %edi movl %edi, %eax adcl $0, %eax ret $ gcc -O3 t.c _foo: testl %edi, %edi movl $1, %eax cmove %eax, %edi movl %edi, %eax ret From baldrick at free.fr Wed Dec 22 07:36:08 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Dec 2010 13:36:08 -0000 Subject: [llvm-commits] [llvm] r122399 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineAddSub.cpp lib/Transforms/InstCombine/InstCombineAndOrXor.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp lib/Transforms/InstCombine/InstructionCombining.cpp test/Transforms/InstCombine/2010-11-23-Distributed.ll Message-ID: <20101222133608.914332A6C12C@llvm.org> Author: baldrick Date: Wed Dec 22 07:36:08 2010 New Revision: 122399 URL: http://llvm.org/viewvc/llvm-project?rev=122399&view=rev Log: Add a generic expansion transform: A op (B op' C) -> (A op B) op' (A op C) if both A op B and A op C simplify. This fires fairly often but doesn't make that much difference. On gcc-as-one-file it removes two "and"s and turns one branch into a select. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/2010-11-23-Distributed.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Wed Dec 22 07:36:08 2010 @@ -290,11 +290,12 @@ /// operators which are associative or commutative. bool SimplifyAssociativeOrCommutative(BinaryOperator &I); - /// SimplifyByFactorizing - This tries to simplify binary operations which - /// some other binary operation distributes over by factorizing out a common - /// term (eg "(A*B)+(A*C)" -> "A*(B+C)"). Returns the simplified value, or - /// null if no simplification was performed. - Instruction *SimplifyByFactorizing(BinaryOperator &I); + /// SimplifyUsingDistributiveLaws - This tries to simplify binary operations + /// which some other binary operation distributes over either by factorizing + /// out common terms (eg "(A*B)+(A*C)" -> "A*(B+C)") or expanding out if this + /// results in simplifications (eg: "A & (B | C) -> (A&B) | (A&C)" if this is + /// a win). Returns the simplified value, or null if it didn't simplify. + Value *SimplifyUsingDistributiveLaws(BinaryOperator &I); /// SimplifyDemandedUseBits - Attempts to replace V with a simpler value /// based on the demanded bits. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Wed Dec 22 07:36:08 2010 @@ -91,9 +91,10 @@ I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); - if (Instruction *NV = SimplifyByFactorizing(I)) // (A*B)+(A*C) -> A*(B+C) - return NV; - + // (A*B)+(A*C) -> A*(B+C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); + if (Constant *RHSC = dyn_cast(RHS)) { if (ConstantInt *CI = dyn_cast(RHSC)) { // X + (signbit) --> X ^ signbit @@ -535,9 +536,10 @@ I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); - if (Instruction *NV = SimplifyByFactorizing(I)) // (A*B)-(A*C) -> A*(B-C) - return NV; - + // (A*B)-(A*C) -> A*(B-C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); + // If this is a 'B = x-(-A)', change to B = x+A. This preserves NSW/NUW. if (Value *V = dyn_castNegVal(Op1)) { BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Wed Dec 22 07:36:08 2010 @@ -984,8 +984,9 @@ if (Value *V = SimplifyAndInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); - if (Instruction *NV = SimplifyByFactorizing(I)) // (A|B)&(A|C) -> A|(B&C) - return NV; + // (A|B)&(A|C) -> A|(B&C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. @@ -1702,8 +1703,9 @@ if (Value *V = SimplifyOrInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); - if (Instruction *NV = SimplifyByFactorizing(I)) // (A&B)|(A&C) -> A&(B|C) - return NV; + // (A&B)|(A&C) -> A&(B|C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. @@ -1973,8 +1975,9 @@ if (Value *V = SimplifyXorInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); - if (Instruction *NV = SimplifyByFactorizing(I)) // (A&B)^(A&C) -> A&(B^C) - return NV; + // (A&B)^(A&C) -> A&(B^C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Wed Dec 22 07:36:08 2010 @@ -54,6 +54,9 @@ if (Value *V = SimplifyMulInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); + if (Value *V = SimplifyUsingDistributiveLaws(I)) + return ReplaceInstUsesWith(I, V); + // Simplify mul instructions with a constant RHS. if (Constant *Op1C = dyn_cast(Op1)) { if (ConstantInt *CI = dyn_cast(Op1C)) { Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Wed Dec 22 07:36:08 2010 @@ -58,6 +58,7 @@ STATISTIC(NumConstProp, "Number of constant folds"); STATISTIC(NumDeadInst , "Number of dead inst eliminated"); STATISTIC(NumSunkInst , "Number of instructions sunk"); +STATISTIC(NumExpand, "Number of expansions"); STATISTIC(NumFactor , "Number of factorizations"); STATISTIC(NumReassoc , "Number of reassociations"); @@ -294,64 +295,123 @@ return false; } -/// SimplifyByFactorizing - This tries to simplify binary operations which -/// some other binary operation distributes over by factorizing out a common -/// term (eg "(A*B)+(A*C)" -> "A*(B+C)"). Returns the simplified value, or -/// null if no simplification was performed. -Instruction *InstCombiner::SimplifyByFactorizing(BinaryOperator &I) { - BinaryOperator *Op0 = dyn_cast(I.getOperand(0)); - BinaryOperator *Op1 = dyn_cast(I.getOperand(1)); - if (!Op0 || !Op1 || Op0->getOpcode() != Op1->getOpcode()) - return 0; +/// SimplifyUsingDistributiveLaws - This tries to simplify binary operations +/// which some other binary operation distributes over either by factorizing +/// out common terms (eg "(A*B)+(A*C)" -> "A*(B+C)") or expanding out if this +/// results in simplifications (eg: "A & (B | C) -> (A&B) | (A&C)" if this is +/// a win). Returns the simplified value, or null if it didn't simplify. +Value *InstCombiner::SimplifyUsingDistributiveLaws(BinaryOperator &I) { + Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); + BinaryOperator *Op0 = dyn_cast(LHS); + BinaryOperator *Op1 = dyn_cast(RHS); + Instruction::BinaryOps TopLevelOpcode = I.getOpcode(); // op + + // Factorization. + if (Op0 && Op1 && Op0->getOpcode() == Op1->getOpcode()) { + // The instruction has the form "(A op' B) op (C op' D)". Try to factorize + // a common term. + Value *A = Op0->getOperand(0), *B = Op0->getOperand(1); + Value *C = Op1->getOperand(0), *D = Op1->getOperand(1); + Instruction::BinaryOps InnerOpcode = Op0->getOpcode(); // op' + + // Does "X op' Y" always equal "Y op' X"? + bool InnerCommutative = Instruction::isCommutative(InnerOpcode); + + // Does "X op' (Y op Z)" always equal "(X op' Y) op (X op' Z)"? + if (LeftDistributesOverRight(InnerOpcode, TopLevelOpcode)) + // Does the instruction have the form "(A op' B) op (A op' D)" or, in the + // commutative case, "(A op' B) op (C op' A)"? + if (A == C || (InnerCommutative && A == D)) { + if (A != C) + std::swap(C, D); + // Consider forming "A op' (B op D)". + // If "B op D" simplifies then it can be formed with no cost. + Value *V = SimplifyBinOp(TopLevelOpcode, B, D, TD); + // If "B op D" doesn't simplify then only go on if both of the existing + // operations "A op' B" and "C op' D" will be zapped as no longer used. + if (!V && Op0->hasOneUse() && Op1->hasOneUse()) + V = Builder->CreateBinOp(TopLevelOpcode, B, D, Op1->getName()); + if (V) { + ++NumFactor; + V = Builder->CreateBinOp(InnerOpcode, A, V); + V->takeName(&I); + return V; + } + } - // The instruction has the form "(A op' B) op (C op' D)". - Value *A = Op0->getOperand(0); Value *B = Op0->getOperand(1); - Value *C = Op1->getOperand(0); Value *D = Op1->getOperand(1); - Instruction::BinaryOps OuterOpcode = I.getOpcode(); // op - Instruction::BinaryOps InnerOpcode = Op0->getOpcode(); // op' - - // Does "X op' Y" always equal "Y op' X"? - bool InnerCommutative = Instruction::isCommutative(InnerOpcode); - - // Does "X op' (Y op Z)" always equal "(X op' Y) op (X op' Z)"? - if (LeftDistributesOverRight(InnerOpcode, OuterOpcode)) - // Does the instruction have the form "(A op' B) op (A op' D)" or, in the - // commutative case, "(A op' B) op (C op' A)"? - if (A == C || (InnerCommutative && A == D)) { - if (A != C) - std::swap(C, D); - // Consider forming "A op' (B op D)". - // If "B op D" simplifies then it can be formed with no cost. - Value *RHS = SimplifyBinOp(OuterOpcode, B, D, TD); - // If "B op D" doesn't simplify then only proceed if both of the existing - // operations "A op' B" and "C op' D" will be zapped since no longer used. - if (!RHS && Op0->hasOneUse() && Op1->hasOneUse()) - RHS = Builder->CreateBinOp(OuterOpcode, B, D, Op1->getName()); - if (RHS) { - ++NumFactor; - return BinaryOperator::Create(InnerOpcode, A, RHS); + // Does "(X op Y) op' Z" always equal "(X op' Z) op (Y op' Z)"? + if (RightDistributesOverLeft(TopLevelOpcode, InnerOpcode)) + // Does the instruction have the form "(A op' B) op (C op' B)" or, in the + // commutative case, "(A op' B) op (B op' D)"? + if (B == D || (InnerCommutative && B == C)) { + if (B != D) + std::swap(C, D); + // Consider forming "(A op C) op' B". + // If "A op C" simplifies then it can be formed with no cost. + Value *V = SimplifyBinOp(TopLevelOpcode, A, C, TD); + // If "A op C" doesn't simplify then only go on if both of the existing + // operations "A op' B" and "C op' D" will be zapped as no longer used. + if (!V && Op0->hasOneUse() && Op1->hasOneUse()) + V = Builder->CreateBinOp(TopLevelOpcode, A, C, Op0->getName()); + if (V) { + ++NumFactor; + V = Builder->CreateBinOp(InnerOpcode, V, B); + V->takeName(&I); + return V; + } } - } + } - // Does "(X op Y) op' Z" always equal "(X op' Z) op (Y op' Z)"? - if (RightDistributesOverLeft(OuterOpcode, InnerOpcode)) - // Does the instruction have the form "(A op' B) op (C op' B)" or, in the - // commutative case, "(A op' B) op (B op' D)"? - if (B == D || (InnerCommutative && B == C)) { - if (B != D) - std::swap(C, D); - // Consider forming "(A op C) op' B". - // If "A op C" simplifies then it can be formed with no cost. - Value *LHS = SimplifyBinOp(OuterOpcode, A, C, TD); - // If "A op C" doesn't simplify then only proceed if both of the existing - // operations "A op' B" and "C op' D" will be zapped since no longer used. - if (!LHS && Op0->hasOneUse() && Op1->hasOneUse()) - LHS = Builder->CreateBinOp(OuterOpcode, A, C, Op0->getName()); - if (LHS) { - ++NumFactor; - return BinaryOperator::Create(InnerOpcode, LHS, B); + // Expansion. + if (Op0 && RightDistributesOverLeft(Op0->getOpcode(), TopLevelOpcode)) { + // The instruction has the form "(A op' B) op C". See if expanding it out + // to "(A op C) op' (B op C)" results in simplifications. + Value *A = Op0->getOperand(0), *B = Op0->getOperand(1), *C = RHS; + Instruction::BinaryOps InnerOpcode = Op0->getOpcode(); // op' + + // Do "A op C" and "B op C" both simplify? + if (Value *L = SimplifyBinOp(TopLevelOpcode, A, C, TD)) + if (Value *R = SimplifyBinOp(TopLevelOpcode, B, C, TD)) { + // They do! Return "L op' R". + ++NumExpand; + // If "L op' R" equals "A op' B" then "L op' R" is just the LHS. + if ((L == A && R == B) || + (Instruction::isCommutative(InnerOpcode) && L == B && R == A)) + return Op0; + // Otherwise return "L op' R" if it simplifies. + if (Value *V = SimplifyBinOp(InnerOpcode, L, R, TD)) + return V; + // Otherwise, create a new instruction. + C = Builder->CreateBinOp(InnerOpcode, L, R); + C->takeName(&I); + return C; } - } + } + + if (Op1 && LeftDistributesOverRight(TopLevelOpcode, Op1->getOpcode())) { + // The instruction has the form "A op (B op' C)". See if expanding it out + // to "(A op B) op' (A op C)" results in simplifications. + Value *A = LHS, *B = Op1->getOperand(0), *C = Op1->getOperand(1); + Instruction::BinaryOps InnerOpcode = Op1->getOpcode(); // op' + + // Do "A op B" and "A op C" both simplify? + if (Value *L = SimplifyBinOp(TopLevelOpcode, A, B, TD)) + if (Value *R = SimplifyBinOp(TopLevelOpcode, A, C, TD)) { + // They do! Return "L op' R". + ++NumExpand; + // If "L op' R" equals "B op' C" then "L op' R" is just the RHS. + if ((L == B && R == C) || + (Instruction::isCommutative(InnerOpcode) && L == C && R == B)) + return Op1; + // Otherwise return "L op' R" if it simplifies. + if (Value *V = SimplifyBinOp(InnerOpcode, L, R, TD)) + return V; + // Otherwise, create a new instruction. + A = Builder->CreateBinOp(InnerOpcode, L, R); + A->takeName(&I); + return A; + } + } return 0; } Modified: llvm/trunk/test/Transforms/InstCombine/2010-11-23-Distributed.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2010-11-23-Distributed.ll?rev=122399&r1=122398&r2=122399&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2010-11-23-Distributed.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/2010-11-23-Distributed.ll Wed Dec 22 07:36:08 2010 @@ -5,7 +5,19 @@ %mul = mul nsw i32 %add, %y %square = mul nsw i32 %y, %y %res = sub i32 %mul, %square -; CHECK: %res = mul i32 %x, %y ret i32 %res -; CHECK: ret i32 %res +; CHECK-NEXT: mul i32 %x, %y +; CHECK-NEXT: ret i32 +} + +define i1 @bar(i64 %x, i64 %y) { +; CHECK: @bar + %a = and i64 %y, %x +; CHECK: and +; CHECK-NOT: and + %not = xor i64 %a, -1 + %b = and i64 %y, %not + %r = icmp eq i64 %b, 0 + ret i1 %r +; CHECK: ret i1 } From daniel at zuster.org Wed Dec 22 07:49:43 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 13:49:43 -0000 Subject: [llvm-commits] [llvm] r122400 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222134943.8C3482A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 07:49:43 2010 New Revision: 122400 URL: http://llvm.org/viewvc/llvm-project?rev=122400&view=rev Log: MC/Mach-O: Split out RecordARMRelocation for now, it is weird enough it isn't clear how to keep in the generic path (yet). - Will revisit when it actually works. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122400&r1=122399&r2=122400&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 07:49:43 2010 @@ -235,6 +235,10 @@ /// @{ bool is64Bit() const { return TargetObjectWriter->is64Bit(); } + bool isARM() const { + uint32_t CPUType = TargetObjectWriter->getCPUType() & mach::CTFM_ArchMask; + return CPUType == mach::CTM_ARM; + } /// @} @@ -839,9 +843,20 @@ Relocations[Fragment->getParent()].push_back(MRE); } + void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue) { + // FIXME! + } + void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { + // FIXME: These needs to be factored into the target Mach-O writer. + if (isARM()) { + RecordARMRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); + return; + } if (is64Bit()) { RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); return; From daniel at zuster.org Wed Dec 22 07:49:56 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 13:49:56 -0000 Subject: [llvm-commits] [llvm] r122401 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222134956.C5B262A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 07:49:56 2010 New Revision: 122401 URL: http://llvm.org/viewvc/llvm-project?rev=122401&view=rev Log: Simplify. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122401&r1=122400&r2=122401&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 07:49:56 2010 @@ -906,16 +906,15 @@ // find a case where they are actually emitted. Type = macho::RIT_Vanilla; } else if (SD->getSymbol().isVariable()) { - const MCExpr *Value = SD->getSymbol().getVariableValue(); int64_t Res; - bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress); - if (isAbs) { + if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( + Res, Layout, SectionAddress)) { FixedValue = Res; return; - } else { - report_fatal_error("unsupported relocation of variable '" + - SD->getSymbol().getName() + "'"); } + + report_fatal_error("unsupported relocation of variable '" + + SD->getSymbol().getName() + "'"); } else { // Check whether we need an external or internal relocation. if (doesSymbolRequireExternRelocation(SD)) { From daniel at zuster.org Wed Dec 22 07:50:05 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 13:50:05 -0000 Subject: [llvm-commits] [llvm] r122402 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222135005.816B32A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 07:50:05 2010 New Revision: 122402 URL: http://llvm.org/viewvc/llvm-project?rev=122402&view=rev Log: MC/Mach-O/ARM: Stub out RecordARMRelocation, which is mostly a copy of RecordRelocation with lots of FIXMEs. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122402&r1=122401&r2=122402&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 07:50:05 2010 @@ -846,7 +846,84 @@ void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { - // FIXME! + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + // FIXME: Eliminate this! + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + + // If this is a difference or a defined symbol plus an offset, then we need + // a scattered relocation entry. Differences always require scattered + // relocations. + if (Target.getSymB()) + return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, FixedValue); + + // Get the symbol data, if any. + MCSymbolData *SD = 0; + if (Target.getSymA()) + SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); + + // FIXME: For other platforms, we need to use scattered relocations for + // internal relocations with offsets. If this is an internal relocation + // with an offset, it also needs a scattered relocation entry. + // + // Is this right for ARM? + uint32_t Offset = Target.getConstant(); + if (IsPCRel) + Offset += 1 << Log2Size; + if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) + return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, FixedValue); + + // See . + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned Index = 0; + unsigned IsExtern = 0; + unsigned Type = 0; + + if (Target.isAbsolute()) { // constant + // FIXME! + report_fatal_error("FIXME: relocations to absolute targets " + "not yet implemented"); + } else if (SD->getSymbol().isVariable()) { + int64_t Res; + if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( + Res, Layout, SectionAddress)) { + FixedValue = Res; + return; + } + + report_fatal_error("unsupported relocation of variable '" + + SD->getSymbol().getName() + "'"); + } else { + // Check whether we need an external or internal relocation. + if (doesSymbolRequireExternRelocation(SD)) { + IsExtern = 1; + Index = SD->getIndex(); + // For external relocations, make sure to offset the fixup value to + // compensate for the addend of the symbol address, if it was + // undefined. This occurs with weak definitions, for example. + if (!SD->Symbol->isUndefined()) + FixedValue -= Layout.getSymbolOffset(SD); + } else { + // The index is the section ordinal (1-based). + Index = SD->getFragment()->getParent()->getOrdinal() + 1; + FixedValue += getSectionAddress(SD->getFragment()->getParent()); + } + if (IsPCRel) + FixedValue -= getSectionAddress(Fragment->getParent()); + + Type = macho::RIT_Vanilla; + } + + // struct relocation_info (8 bytes) + macho::RelocationEntry MRE; + MRE.Word0 = FixupOffset; + MRE.Word1 = ((Index << 0) | + (IsPCRel << 24) | + (Log2Size << 25) | + (IsExtern << 27) | + (Type << 28)); + Relocations[Fragment->getParent()].push_back(MRE); } void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, From rafael.espindola at gmail.com Wed Dec 22 10:03:00 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 16:03:00 -0000 Subject: [llvm-commits] [llvm] r122404 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/MC/ELF/size.s Message-ID: <20101222160300.78C7E2A6C12D@llvm.org> Author: rafael Date: Wed Dec 22 10:03:00 2010 New Revision: 122404 URL: http://llvm.org/viewvc/llvm-project?rev=122404&view=rev Log: Simplify the handling of .size expressions. Removed: llvm/trunk/test/MC/ELF/size.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=122404&r1=122403&r2=122404&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed Dec 22 10:03:00 2010 @@ -594,26 +594,15 @@ uint64_t Value = SymbolValue(Data, Layout); uint64_t Size = 0; - const MCExpr *ESize; assert(!(Data.isCommon() && !Data.isExternal())); - ESize = Data.getSize(); - if (Data.getSize()) { - MCValue Res; - if (ESize->getKind() == MCExpr::Binary) { - const MCBinaryExpr *BE = static_cast(ESize); - - if (BE->EvaluateAsRelocatable(Res, &Layout)) { - assert(!Res.getSymA() || !Res.getSymA()->getSymbol().isDefined()); - assert(!Res.getSymB() || !Res.getSymB()->getSymbol().isDefined()); - Size = Res.getConstant(); - } - } else if (ESize->getKind() == MCExpr::Constant) { - Size = static_cast(ESize)->getValue(); - } else { - assert(0 && "Unsupported size expression"); - } + const MCExpr *ESize = Data.getSize(); + if (ESize) { + int64_t Res; + if (!ESize->EvaluateAsAbsolute(Res, Layout)) + report_fatal_error("Size expression must be absolute."); + Size = Res; } // Write out the symbol table entry Removed: llvm/trunk/test/MC/ELF/size.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/size.s?rev=122403&view=auto ============================================================================== --- llvm/trunk/test/MC/ELF/size.s (original) +++ llvm/trunk/test/MC/ELF/size.s (removed) @@ -1,10 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s - -// Mostly a test that this doesn't crash anymore. - -// CHECK: # Symbol 0x00000004 -// CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000001) - - .size foo, .Lbar-foo - .long foo From rafael.espindola at gmail.com Wed Dec 22 10:11:57 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 16:11:57 -0000 Subject: [llvm-commits] [llvm] r122405 - in /llvm/trunk: include/llvm/MC/MCExpr.h lib/MC/MCAssembler.cpp lib/MC/MCExpr.cpp Message-ID: <20101222161157.3989F2A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 10:11:57 2010 New Revision: 122405 URL: http://llvm.org/viewvc/llvm-project?rev=122405&view=rev Log: Use references and simplify. Modified: llvm/trunk/include/llvm/MC/MCExpr.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCExpr.cpp Modified: llvm/trunk/include/llvm/MC/MCExpr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=122405&r1=122404&r2=122405&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCExpr.h (original) +++ llvm/trunk/include/llvm/MC/MCExpr.h Wed Dec 22 10:11:57 2010 @@ -90,7 +90,7 @@ /// @param Res - The relocatable value, if evaluation succeeds. /// @param Layout - The assembler layout object to use for evaluating values. /// @result - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const; + bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const; /// @} Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122405&r1=122404&r2=122405&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed Dec 22 10:11:57 2010 @@ -215,7 +215,7 @@ MCValue &Target, uint64_t &Value) const { ++stats::EvaluateFixup; - if (!Fixup.getValue()->EvaluateAsRelocatable(Target, &Layout)) + if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout)) report_fatal_error("expected relocatable expression"); // FIXME: How do non-scattered symbols work in ELF? I presume the linker Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=122405&r1=122404&r2=122405&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Wed Dec 22 10:11:57 2010 @@ -409,12 +409,9 @@ } bool MCExpr::EvaluateAsRelocatable(MCValue &Res, - const MCAsmLayout *Layout) const { - if (Layout) - return EvaluateAsRelocatableImpl(Res, &Layout->getAssembler(), Layout, - 0, false); - else - return EvaluateAsRelocatableImpl(Res, 0, 0, 0, false); + const MCAsmLayout &Layout) const { + return EvaluateAsRelocatableImpl(Res, &Layout.getAssembler(), &Layout, + 0, false); } bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, From daniel at zuster.org Wed Dec 22 10:19:20 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:19:20 -0000 Subject: [llvm-commits] [llvm] r122406 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222161920.49F1B2A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 10:19:20 2010 New Revision: 122406 URL: http://llvm.org/viewvc/llvm-project?rev=122406&view=rev Log: MC/Mach-O/ARM: Fix thinko. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122406&r1=122405&r2=122406&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:19:20 2010 @@ -236,7 +236,7 @@ bool is64Bit() const { return TargetObjectWriter->is64Bit(); } bool isARM() const { - uint32_t CPUType = TargetObjectWriter->getCPUType() & mach::CTFM_ArchMask; + uint32_t CPUType = TargetObjectWriter->getCPUType() & ~mach::CTFM_ArchMask; return CPUType == mach::CTM_ARM; } From daniel at zuster.org Wed Dec 22 10:19:24 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:19:24 -0000 Subject: [llvm-commits] [llvm] r122407 - in /llvm/trunk: lib/MC/MachObjectWriter.cpp test/MC/MachO/darwin-ARM-reloc.s Message-ID: <20101222161925.089982A6C12D@llvm.org> Author: ddunbar Date: Wed Dec 22 10:19:24 2010 New Revision: 122407 URL: http://llvm.org/viewvc/llvm-project?rev=122407&view=rev Log: MC/Mach-O/ARM: Add enough relocation logic to get BR24 relocations. Added: llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122407&r1=122406&r2=122407&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:19:24 2010 @@ -24,6 +24,7 @@ #include "llvm/Target/TargetAsmBackend.h" // FIXME: Gross. +#include "../Target/ARM/ARMFixupKinds.h" #include "../Target/X86/X86FixupKinds.h" #include @@ -843,12 +844,33 @@ Relocations[Fragment->getParent()].push_back(MRE); } + static bool getARMFixupKindMachOInfo(unsigned Kind, bool &Is24BitBranch, + unsigned &Log2Size) { + switch (Kind) { + default: + return false; + + // Handle 24-bit branch kinds. + case ARM::fixup_arm_ldst_pcrel_12: + case ARM::fixup_arm_pcrel_10: + case ARM::fixup_arm_adr_pcrel_12: + case ARM::fixup_arm_branch: + Is24BitBranch = true; + // Report as 'long', even though that is not quite accurate. + Log2Size = llvm::Log2_32(4); + return true; + } + } void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - // FIXME: Eliminate this! - unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + unsigned Log2Size; + bool Is24BitBranch; + if (!getARMFixupKindMachOInfo(Fixup.getKind(), Is24BitBranch, Log2Size)) { + report_fatal_error("unknown ARM fixup kind!"); + return; + } // If this is a difference or a defined symbol plus an offset, then we need // a scattered relocation entry. Differences always require scattered @@ -912,7 +934,8 @@ if (IsPCRel) FixedValue -= getSectionAddress(Fragment->getParent()); - Type = macho::RIT_Vanilla; + // Determine the appropriate type based on the fixup kind. + Type = Is24BitBranch ? macho::RIT_ARM_Branch24Bit : macho::RIT_Vanilla; } // struct relocation_info (8 bytes) Added: llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s?rev=122407&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s (added) +++ llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Wed Dec 22 10:19:24 2010 @@ -0,0 +1,102 @@ +@ RUN: llvm-mc -n -triple armv7-apple-darwin10 %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck < %t.dump %s + + .syntax unified + .text +_f0: + bl _printf + +@ CHECK: ('cputype', 12) +@ CHECK: ('cpusubtype', 9) +@ CHECK: ('filetype', 1) +@ CHECK: ('num_load_commands', 3) +@ CHECK: ('load_commands_size', 228) +@ CHECK: ('flag', 0) +@ CHECK: ('load_commands', [ +@ CHECK: # Load Command 0 +@ CHECK: (('command', 1) +@ CHECK: ('size', 124) +@ CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('vm_addr', 0) +@ CHECK: ('vm_size', 4) +@ CHECK: ('file_offset', 256) +@ CHECK: ('file_size', 4) +@ CHECK: ('maxprot', 7) +@ CHECK: ('initprot', 7) +@ CHECK: ('num_sections', 1) +@ CHECK: ('flags', 0) +@ CHECK: ('sections', [ +@ CHECK: # Section 0 +@ CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('address', 0) +@ CHECK: ('size', 4) +@ CHECK: ('offset', 256) +@ CHECK: ('alignment', 0) +@ CHECK: ('reloc_offset', 260) +@ CHECK: ('num_reloc', 1) +@ CHECK: ('flags', 0x80000400) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: # Relocation 0 +@ CHECK: (('word-0', 0x0), +@ CHECK: ('word-1', 0x5d000001)), +@ CHECK: ]) +@ CHECK: ('_section_data', 'feffffeb') +@ CHECK: ]) +@ CHECK: ), +@ CHECK: # Load Command 1 +@ CHECK: (('command', 2) +@ CHECK: ('size', 24) +@ CHECK: ('symoff', 268) +@ CHECK: ('nsyms', 2) +@ CHECK: ('stroff', 292) +@ CHECK: ('strsize', 16) +@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00\x00\x00\x00') +@ CHECK: ('_symbols', [ +@ CHECK: # Symbol 0 +@ CHECK: (('n_strx', 9) +@ CHECK: ('n_type', 0xe) +@ CHECK: ('n_sect', 1) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 0) +@ CHECK: ('_string', '_f0') +@ CHECK: ), +@ CHECK: # Symbol 1 +@ CHECK: (('n_strx', 1) +@ CHECK: ('n_type', 0x1) +@ CHECK: ('n_sect', 0) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 0) +@ CHECK: ('_string', '_printf') +@ CHECK: ), +@ CHECK: ]) +@ CHECK: ), +@ CHECK: # Load Command 2 +@ CHECK: (('command', 11) +@ CHECK: ('size', 80) +@ CHECK: ('ilocalsym', 0) +@ CHECK: ('nlocalsym', 1) +@ CHECK: ('iextdefsym', 1) +@ CHECK: ('nextdefsym', 0) +@ CHECK: ('iundefsym', 1) +@ CHECK: ('nundefsym', 1) +@ CHECK: ('tocoff', 0) +@ CHECK: ('ntoc', 0) +@ CHECK: ('modtaboff', 0) +@ CHECK: ('nmodtab', 0) +@ CHECK: ('extrefsymoff', 0) +@ CHECK: ('nextrefsyms', 0) +@ CHECK: ('indirectsymoff', 0) +@ CHECK: ('nindirectsyms', 0) +@ CHECK: ('extreloff', 0) +@ CHECK: ('nextrel', 0) +@ CHECK: ('locreloff', 0) +@ CHECK: ('nlocrel', 0) +@ CHECK: ('_indirect_symbols', [ +@ CHECK: ]) +@ CHECK: ), +@ CHECK: ]) From daniel at zuster.org Wed Dec 22 10:32:37 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:32:37 -0000 Subject: [llvm-commits] [llvm] r122408 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222163237.F2E7C2A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 10:32:37 2010 New Revision: 122408 URL: http://llvm.org/viewvc/llvm-project?rev=122408&view=rev Log: MC/Mach-O/ARM: Recognize generic _Data_N fixup kinds. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122408&r1=122407&r2=122408&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:32:37 2010 @@ -846,10 +846,26 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, bool &Is24BitBranch, unsigned &Log2Size) { + Is24BitBranch = false; + Log2Size = ~0U; + switch (Kind) { default: return false; + case FK_Data_1: + Log2Size = llvm::Log2_32(1); + return true; + case FK_Data_2: + Log2Size = llvm::Log2_32(2); + return true; + case FK_Data_4: + Log2Size = llvm::Log2_32(4); + return true; + case FK_Data_8: + Log2Size = llvm::Log2_32(8); + return true; + // Handle 24-bit branch kinds. case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: From daniel at zuster.org Wed Dec 22 10:32:41 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:32:41 -0000 Subject: [llvm-commits] [llvm] r122409 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222163241.645BE2A6C12D@llvm.org> Author: ddunbar Date: Wed Dec 22 10:32:41 2010 New Revision: 122409 URL: http://llvm.org/viewvc/llvm-project?rev=122409&view=rev Log: MC/Mach-O: Return to reporting errors if we see unexpected fixup kinds. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122409&r1=122408&r2=122409&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:32:41 2010 @@ -34,17 +34,14 @@ // FIXME: this has been copied from (or to) X86AsmBackend.cpp static unsigned getFixupKindLog2Size(unsigned Kind) { switch (Kind) { - // FIXME: Until ARM has it's own relocation stuff spun off, it comes - // through here and we don't want it to puke all over. Any reasonable - // values will only come when ARM relocation support gets added, at which - // point this will be X86 only again and the llvm_unreachable can be - // re-enabled. - default: return 0;// llvm_unreachable("invalid fixup kind!"); + default: + llvm_unreachable("invalid fixup kind!"); case FK_PCRel_1: case FK_Data_1: return 0; case FK_PCRel_2: case FK_Data_2: return 1; case FK_PCRel_4: + // FIXME: Remove these!!! case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_movq_load: case X86::reloc_signed_4byte: From clattner at apple.com Wed Dec 22 10:40:23 2010 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Dec 2010 08:40:23 -0800 Subject: [llvm-commits] [llvm] r122326 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/ test/Transforms/InstSimplify/2010-12-20-Reassociate.ll test/Transforms/InstSimplify/dg.exp In-Reply-To: <4D11C5E4.6020601@free.fr> References: <20101221084900.DFBF42A6C12D@llvm.org> <8378C911-1AA6-4372-995A-0CB82FCEF42C@apple.com> <4D11C5E4.6020601@free.fr> Message-ID: On Dec 22, 2010, at 1:33 AM, Duncan Sands wrote: > Hi Chris, > >>> Add generic simplification of associative operations, generalizing >>> a couple of existing transforms. This fires surprisingly often, for >>> example when compiling gcc "(X+(-1))+1->X" fires quite a lot as well >>> as various "and" simplifications (usually with a phi node operand). >>> Most of the time this doesn't make a real difference since the same >>> thing would have been done elsewhere anyway, eg: by instcombine, but >>> there are a few places where this results in simplifications that we >>> were not doing before. >> >> Nice. Should the related logic get ripped out of instcombine? It is probably a little more general, but if it doesn't matter in practice, we should remove it. > > when running std-compile-opts on gcc-as-one-big-file, this logic in > InstructionSimplify succeeds 171 times, while the corresponding logic in > InstCombine succeeds 4095 times. As a point of comparison, InstCombine does > 3536 constant folds on this testcase. It is not surprising that instcombine > succeeds so much more often, as instsimplify is hugely constrained by the > requirement that it is only allowed to simplify to existing instructions, it is > not allowed to create any new instructions. That said, if instsimplify was > allowed to modify instructions in place then I think for reassociation it would > catch everything. Ok, makes sense. Thanks, -Chris From baldrick at free.fr Wed Dec 22 11:08:04 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Dec 2010 17:08:04 -0000 Subject: [llvm-commits] [llvm] r122413 - /llvm/trunk/test/Transforms/InstCombine/select.ll Message-ID: <20101222170804.6C2142A6C12C@llvm.org> Author: baldrick Date: Wed Dec 22 11:08:04 2010 New Revision: 122413 URL: http://llvm.org/viewvc/llvm-project?rev=122413&view=rev Log: Make this test not depend on how the variable is named. Modified: llvm/trunk/test/Transforms/InstCombine/select.ll Modified: llvm/trunk/test/Transforms/InstCombine/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=122413&r1=122412&r2=122413&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/select.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/select.ll Wed Dec 22 11:08:04 2010 @@ -581,6 +581,6 @@ %r = and i32 %x, %s ret i32 %r ; CHECK: @test41 -; CHECK: %r = and i32 %x, %y -; CHECK: ret i32 %r +; CHECK-NEXT: and i32 %x, %y +; CHECK-NEXT: ret i32 } From criswell at uiuc.edu Wed Dec 22 10:51:53 2010 From: criswell at uiuc.edu (John Criswell) Date: Wed, 22 Dec 2010 16:51:53 -0000 Subject: [llvm-commits] [poolalloc] r122411 - /poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <20101222165153.19AD32A6C12C@llvm.org> Author: criswell Date: Wed Dec 22 10:51:52 2010 New Revision: 122411 URL: http://llvm.org/viewvc/llvm-project?rev=122411&view=rev Log: Do not add DSNodes to the local DSGraphs for newly added pools. This somehow causes memory exhaustion. Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=122411&r1=122410&r2=122411&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Wed Dec 22 10:51:52 2010 @@ -1155,9 +1155,18 @@ if (!IsMain) { PoolDesc = new AllocaInst(PoolDescType, 0, "PD", InsertPoint); +#if 0 + // // Create a node in DSG to represent the new alloca. + // + // Note: + // Disable this for now. Other passes don't look up DSNodes for pool + // handles, and doing this seems to blow up memory consumption. So, + // for now, don't do this. + // DSNode *NewNode = DSG->addObjectToGraph(PoolDesc); NewNode->setModifiedMarker()->setReadMarker(); // This is M/R +#endif } else { PoolDesc = CreateGlobalPool(Pool.PoolSize, Pool.PoolAlignment, "PoolForMain", InsertPoint); From clattner at apple.com Wed Dec 22 10:43:46 2010 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Dec 2010 08:43:46 -0800 Subject: [llvm-commits] [llvm] r122364 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/conditional-indecrement.ll In-Reply-To: <48D6FE29-F6B4-4166-819F-C0B32D087FCC@gmail.com> References: <20101221214144.536632A6C12C@llvm.org> <7D5EA39D-3D57-46E5-91C1-F0876BC61E85@apple.com> <48D6FE29-F6B4-4166-819F-C0B32D087FCC@gmail.com> Message-ID: <3F431891-AA8E-47AD-9BC4-63FF4A0C4AD2@apple.com> On Dec 22, 2010, at 4:42 AM, Benjamin Kramer wrote: > > On 22.12.2010, at 03:13, Chris Lattner wrote: > >> >> On Dec 21, 2010, at 1:41 PM, Benjamin Kramer wrote: >> >>> Author: d0k >>> Date: Tue Dec 21 15:41:44 2010 >>> New Revision: 122364 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122364&view=rev >>> Log: >>> Add some x86 specific dagcombines for conditional increments. >>> >>> (add Y, (sete X, 0)) -> cmp X, 1; adc 0, Y >>> (add Y, (setne X, 0)) -> cmp X, 1; sbb -1, Y >>> (sub (sete X, 0), Y) -> cmp X, 1; sbb 0, Y >>> (sub (setne X, 0), Y) -> cmp X, 1; adc -1, Y >> >> Very nice. Do we handle the cases when X and Y are the same value? "X == 0 ? X+1 : X" simplifies to "X == 0 ? 1 : X". > > $ cat t.c > unsigned foo(unsigned x) { > if (x == 0) x++; > return x; > } > > $ clang -O3 t.c > _foo: > cmpl $1, %edi > movl %edi, %eax > adcl $0, %eax > ret That's very nice. I guess I was assuming that we'd canonicalize that into: define i32 @bar(i32 %x) nounwind readnone ssp { entry: %cmp = icmp eq i32 %x, 0 %inc.x = select i1 %cmp, i32 1, i32 %x ret i32 %inc.x } which we don't. This isels to: _bar: ## @bar ## BB#0: ## %entry testl %edi, %edi movl $1, %eax cmovnel %edi, %eax ret Which isn't too bad, but isn't as nice as the adc sequence because it uses an extra register :) -Chris From daniel at zuster.org Wed Dec 22 10:45:29 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:45:29 -0000 Subject: [llvm-commits] [llvm] r122410 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222164529.675902A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 10:45:29 2010 New Revision: 122410 URL: http://llvm.org/viewvc/llvm-project?rev=122410&view=rev Log: MC/Mach-O/ARM: Clone off an ARM version of RecordScatteredRelocation until I figure out how it is supposed to work. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122410&r1=122409&r2=122410&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:45:29 2010 @@ -796,6 +796,70 @@ Relocations[Fragment->getParent()].push_back(MRE); } + void RecordARMScatteredRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + uint64_t &FixedValue) { + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + unsigned Type = macho::RIT_Vanilla; + + // See . + const MCSymbol *A = &Target.getSymA()->getSymbol(); + MCSymbolData *A_SD = &Asm.getSymbolData(*A); + + if (!A_SD->getFragment()) + report_fatal_error("symbol '" + A->getName() + + "' can not be undefined in a subtraction expression"); + + uint32_t Value = getSymbolAddress(A_SD, Layout); + uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent()); + FixedValue += SecAddr; + uint32_t Value2 = 0; + + if (const MCSymbolRefExpr *B = Target.getSymB()) { + MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); + + if (!B_SD->getFragment()) + report_fatal_error("symbol '" + B->getSymbol().getName() + + "' can not be undefined in a subtraction expression"); + + // Select the appropriate difference relocation type. + // + // Note that there is no longer any semantic difference between these two + // relocation types from the linkers point of view, this is done solely + // for pedantic compatibility with 'as'. + Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference : + (unsigned)macho::RIT_Generic_LocalDifference; + Value2 = getSymbolAddress(B_SD, Layout); + FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); + } + + // Relocations are written out in reverse order, so the PAIR comes first. + if (Type == macho::RIT_Difference || + Type == macho::RIT_Generic_LocalDifference) { + macho::RelocationEntry MRE; + MRE.Word0 = ((0 << 0) | + (macho::RIT_Pair << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value2; + Relocations[Fragment->getParent()].push_back(MRE); + } + + macho::RelocationEntry MRE; + MRE.Word0 = ((FixupOffset << 0) | + (Type << 24) | + (Log2Size << 28) | + (IsPCRel << 30) | + macho::RF_Scattered); + MRE.Word1 = Value; + Relocations[Fragment->getParent()].push_back(MRE); + } + void RecordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -889,8 +953,8 @@ // a scattered relocation entry. Differences always require scattered // relocations. if (Target.getSymB()) - return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, - Target, FixedValue); + return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, FixedValue); // Get the symbol data, if any. MCSymbolData *SD = 0; @@ -906,8 +970,8 @@ if (IsPCRel) Offset += 1 << Log2Size; if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) - return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup, - Target, FixedValue); + return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, + Target, FixedValue); // See . uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); From daniel at zuster.org Wed Dec 22 10:52:19 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 16:52:19 -0000 Subject: [llvm-commits] [llvm] r122412 - in /llvm/trunk: lib/MC/MachObjectWriter.cpp test/MC/MachO/darwin-ARM-reloc.s Message-ID: <20101222165219.D07582A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 10:52:19 2010 New Revision: 122412 URL: http://llvm.org/viewvc/llvm-project?rev=122412&view=rev Log: MC/Mach-O/ARM: We always use the SECTDIFF reloc type on ARM, which is esp. important given that the LOCAL_SECTDIFF enumeration got redefined. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122412&r1=122411&r2=122412&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 10:52:19 2010 @@ -827,12 +827,7 @@ "' can not be undefined in a subtraction expression"); // Select the appropriate difference relocation type. - // - // Note that there is no longer any semantic difference between these two - // relocation types from the linkers point of view, this is done solely - // for pedantic compatibility with 'as'. - Type = A_SD->isExternal() ? (unsigned)macho::RIT_Difference : - (unsigned)macho::RIT_Generic_LocalDifference; + Type = macho::RIT_Difference; Value2 = getSymbolAddress(B_SD, Layout); FixedValue -= getSectionAddress(B_SD->getFragment()->getParent()); } Modified: llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s?rev=122412&r1=122411&r2=122412&view=diff ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s (original) +++ llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Wed Dec 22 10:52:19 2010 @@ -7,24 +7,33 @@ _f0: bl _printf + .data +_d0: +Ld0_0: + .long Lsc0_0 - Ld0_0 + + .section __TEXT,__cstring,cstring_literals +Lsc0_0: + .long 0 + @ CHECK: ('cputype', 12) @ CHECK: ('cpusubtype', 9) @ CHECK: ('filetype', 1) @ CHECK: ('num_load_commands', 3) -@ CHECK: ('load_commands_size', 228) +@ CHECK: ('load_commands_size', 364) @ CHECK: ('flag', 0) @ CHECK: ('load_commands', [ @ CHECK: # Load Command 0 @ CHECK: (('command', 1) -@ CHECK: ('size', 124) +@ CHECK: ('size', 260) @ CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('vm_addr', 0) -@ CHECK: ('vm_size', 4) -@ CHECK: ('file_offset', 256) -@ CHECK: ('file_size', 4) +@ CHECK: ('vm_size', 12) +@ CHECK: ('file_offset', 392) +@ CHECK: ('file_size', 12) @ CHECK: ('maxprot', 7) @ CHECK: ('initprot', 7) -@ CHECK: ('num_sections', 1) +@ CHECK: ('num_sections', 3) @ CHECK: ('flags', 0) @ CHECK: ('sections', [ @ CHECK: # Section 0 @@ -32,9 +41,9 @@ @ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('address', 0) @ CHECK: ('size', 4) -@ CHECK: ('offset', 256) +@ CHECK: ('offset', 392) @ CHECK: ('alignment', 0) -@ CHECK: ('reloc_offset', 260) +@ CHECK: ('reloc_offset', 404) @ CHECK: ('num_reloc', 1) @ CHECK: ('flags', 0x80000400) @ CHECK: ('reserved1', 0) @@ -43,19 +52,57 @@ @ CHECK: ('_relocations', [ @ CHECK: # Relocation 0 @ CHECK: (('word-0', 0x0), -@ CHECK: ('word-1', 0x5d000001)), +@ CHECK: ('word-1', 0x5d000002)), @ CHECK: ]) @ CHECK: ('_section_data', 'feffffeb') +@ CHECK: # Section 1 +@ CHECK: (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('address', 4) +@ CHECK: ('size', 4) +@ CHECK: ('offset', 396) +@ CHECK: ('alignment', 0) +@ CHECK: ('reloc_offset', 412) +@ CHECK: ('num_reloc', 2) +@ CHECK: ('flags', 0x0) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: # Relocation 0 +@ CHECK: (('word-0', 0xa2000000), +@ CHECK: ('word-1', 0x8)), +@ CHECK: # Relocation 1 +@ CHECK: (('word-0', 0xa1000000), +@ CHECK: ('word-1', 0x4)), +@ CHECK: ]) +@ CHECK: ('_section_data', '04000000') +@ CHECK: # Section 2 +@ CHECK: (('section_name', '__cstring\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('address', 8) +@ CHECK: ('size', 4) +@ CHECK: ('offset', 400) +@ CHECK: ('alignment', 0) +@ CHECK: ('reloc_offset', 0) +@ CHECK: ('num_reloc', 0) +@ CHECK: ('flags', 0x2) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: ]) +@ CHECK: ('_section_data', '00000000') @ CHECK: ]) @ CHECK: ), @ CHECK: # Load Command 1 @ CHECK: (('command', 2) @ CHECK: ('size', 24) -@ CHECK: ('symoff', 268) -@ CHECK: ('nsyms', 2) -@ CHECK: ('stroff', 292) -@ CHECK: ('strsize', 16) -@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00\x00\x00\x00') +@ CHECK: ('symoff', 428) +@ CHECK: ('nsyms', 3) +@ CHECK: ('stroff', 464) +@ CHECK: ('strsize', 20) +@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00_d0\x00\x00\x00\x00') @ CHECK: ('_symbols', [ @ CHECK: # Symbol 0 @ CHECK: (('n_strx', 9) @@ -66,6 +113,14 @@ @ CHECK: ('_string', '_f0') @ CHECK: ), @ CHECK: # Symbol 1 +@ CHECK: (('n_strx', 13) +@ CHECK: ('n_type', 0xe) +@ CHECK: ('n_sect', 2) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 4) +@ CHECK: ('_string', '_d0') +@ CHECK: ), +@ CHECK: # Symbol 2 @ CHECK: (('n_strx', 1) @ CHECK: ('n_type', 0x1) @ CHECK: ('n_sect', 0) @@ -79,10 +134,10 @@ @ CHECK: (('command', 11) @ CHECK: ('size', 80) @ CHECK: ('ilocalsym', 0) -@ CHECK: ('nlocalsym', 1) -@ CHECK: ('iextdefsym', 1) +@ CHECK: ('nlocalsym', 2) +@ CHECK: ('iextdefsym', 2) @ CHECK: ('nextdefsym', 0) -@ CHECK: ('iundefsym', 1) +@ CHECK: ('iundefsym', 2) @ CHECK: ('nundefsym', 1) @ CHECK: ('tocoff', 0) @ CHECK: ('ntoc', 0) From baldrick at free.fr Wed Dec 22 11:15:26 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Dec 2010 17:15:26 -0000 Subject: [llvm-commits] [llvm] r122414 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2010-12-20-Distribute.ll Message-ID: <20101222171526.28E612A6C12C@llvm.org> Author: baldrick Date: Wed Dec 22 11:15:25 2010 New Revision: 122414 URL: http://llvm.org/viewvc/llvm-project?rev=122414&view=rev Log: When determining whether the new instruction was already present in the original instruction, half the cases were missed (making it not wrong but suboptimal). Also correct a typo (A <-> B) in the second chunk. Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=122414&r1=122413&r2=122414&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed Dec 22 11:15:25 2010 @@ -159,10 +159,11 @@ // Does "B op DD" simplify? if (Value *V = SimplifyBinOp(Opcode, B, DD, TD, DT, MaxRecurse)) { // It does! Return "A op' V" if it simplifies or is already available. - // If V equals B then "A op' V" is just the LHS. - if (V == B) { + // If V equals B then "A op' V" is just the LHS. If V equals DD then + // "A op' V" is just the RHS. + if (V == B || V == DD) { ++NumFactor; - return LHS; + return V == B ? LHS : RHS; } // Otherwise return "A op' V" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, A, V, TD, DT, MaxRecurse)) { @@ -181,10 +182,11 @@ // Does "A op CC" simplify? if (Value *V = SimplifyBinOp(Opcode, A, CC, TD, DT, MaxRecurse)) { // It does! Return "V op' B" if it simplifies or is already available. - // If V equals A then "V op' B" is just the LHS. - if (V == B) { + // If V equals A then "V op' B" is just the LHS. If V equals CC then + // "V op' B" is just the RHS. + if (V == A || V == CC) { ++NumFactor; - return LHS; + return V == A ? LHS : RHS; } // Otherwise return "V op' B" if it simplifies. if (Value *W = SimplifyBinOp(OpcodeToExtract, V, B, TD, DT, MaxRecurse)) { Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll?rev=122414&r1=122413&r2=122414&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll (original) +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-Distribute.ll Wed Dec 22 11:15:25 2010 @@ -20,6 +20,17 @@ ; CHECK: ret i32 %x } +define i32 @factorize3(i32 %x, i32 %a, i32 %b) { +; CHECK: @factorize3 +; (X | (A|B)) & (X | B) -> X | ((A|B) & B) -> X | B + %aORb = or i32 %a, %b + %l = or i32 %x, %aORb + %r = or i32 %x, %b + %z = and i32 %l, %r + ret i32 %z +; CHECK: ret i32 %r +} + define i32 @expand(i32 %x) { ; CHECK: @expand ; ((X & 1) | 2) & 1 -> ((X & 1) & 1) | (2 & 1) -> (X & 1) | 0 -> X & 1 From aggarwa4 at illinois.edu Wed Dec 22 12:09:30 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Dec 2010 18:09:30 -0000 Subject: [llvm-commits] [poolalloc] r122417 - /poolalloc/trunk/include/dsa/DSSupport.h Message-ID: <20101222180930.0AF302A6C12C@llvm.org> Author: aggarwa4 Date: Wed Dec 22 12:09:29 2010 New Revision: 122417 URL: http://llvm.org/viewvc/llvm-project?rev=122417&view=rev Log: Add an == operator. Modified: poolalloc/trunk/include/dsa/DSSupport.h Modified: poolalloc/trunk/include/dsa/DSSupport.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSSupport.h?rev=122417&r1=122416&r2=122417&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DSSupport.h (original) +++ poolalloc/trunk/include/dsa/DSSupport.h Wed Dec 22 12:09:29 2010 @@ -351,6 +351,12 @@ RetVal == CS.RetVal && CallArgs == CS.CallArgs && VarArgVal == CS.VarArgVal; } + + bool operator==(DSCallSite &CS) { + return CalleeF == CS.CalleeF && CalleeN == CS.CalleeN && + RetVal == CS.RetVal && CallArgs == CS.CallArgs && + VarArgVal == CS.VarArgVal; + } /// FunctionTypeOfCallSite - Helper method to extract the signature of a function /// that is called a given CallSite From dalej at apple.com Wed Dec 22 12:14:58 2010 From: dalej at apple.com (dalej) Date: Wed, 22 Dec 2010 10:14:58 -0800 Subject: [llvm-commits] [llvm] r122353 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp In-Reply-To: <38476CE2-6095-4AB5-A50A-B0259B1BEBFB@apple.com> References: <20101221200006.D16D32A6C12C@llvm.org> <38476CE2-6095-4AB5-A50A-B0259B1BEBFB@apple.com> Message-ID: <0DDC2D28-934E-45FD-ABFC-F55863B93941@apple.com> On Dec 21, 2010, at 6:04 PM, Chris Lattner wrote: > > On Dec 21, 2010, at 12:00 PM, Dale Johannesen wrote: > >> Author: johannes >> Date: Tue Dec 21 14:00:06 2010 >> New Revision: 122353 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=122353&view=rev >> Log: >> Shift by the word size is invalid IR; don't create it. > > I agree, but testcase? I don't have one; spotted by inspection. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101222/e0d02834/attachment.html From matthewbg at google.com Wed Dec 22 12:25:55 2010 From: matthewbg at google.com (Matt Beaumont-Gay) Date: Wed, 22 Dec 2010 18:25:55 -0000 Subject: [llvm-commits] [llvm] r122419 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20101222182555.C719B2A6C12C@llvm.org> Author: matthewbg Date: Wed Dec 22 12:25:55 2010 New Revision: 122419 URL: http://llvm.org/viewvc/llvm-project?rev=122419&view=rev Log: Fix another conditional expression mismatched enum type warning. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122419&r1=122418&r2=122419&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 12:25:55 2010 @@ -1007,7 +1007,8 @@ FixedValue -= getSectionAddress(Fragment->getParent()); // Determine the appropriate type based on the fixup kind. - Type = Is24BitBranch ? macho::RIT_ARM_Branch24Bit : macho::RIT_Vanilla; + Type = Is24BitBranch ? (unsigned)macho::RIT_ARM_Branch24Bit : + (unsigned)macho::RIT_Vanilla; } // struct relocation_info (8 bytes) From rafael.espindola at gmail.com Wed Dec 22 13:05:49 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 19:05:49 -0000 Subject: [llvm-commits] [llvm] r122427 - /llvm/trunk/lib/MC/MCExpr.cpp Message-ID: <20101222190549.5DCFA2A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 13:05:49 2010 New Revision: 122427 URL: http://llvm.org/viewvc/llvm-project?rev=122427&view=rev Log: Revert r122359 while I debug PR8845. Modified: llvm/trunk/lib/MC/MCExpr.cpp Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=122427&r1=122426&r2=122427&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Wed Dec 22 13:05:49 2010 @@ -269,13 +269,27 @@ // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us // absolutize differences across sections and that is what the MachO writer // uses Addrs for. - bool IsRelocatable = - EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs); + if (!EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs) || + !Value.isAbsolute()) { + // EvaluateAsAbsolute is defined to return the "current value" of + // the expression if we are given a Layout object, even in cases + // when the value is not fixed. + if (Layout) { + Res = Value.getConstant(); + if (Value.getSymA()) { + Res += Layout->getSymbolOffset( + &Layout->getAssembler().getSymbolData(Value.getSymA()->getSymbol())); + } + if (Value.getSymB()) { + Res -= Layout->getSymbolOffset( + &Layout->getAssembler().getSymbolData(Value.getSymB()->getSymbol())); + } + } + return false; + } - // Record the current value. Res = Value.getConstant(); - - return IsRelocatable && Value.isAbsolute(); + return true; } /// \brief Helper method for \see EvaluateSymbolAdd(). From clattner at apple.com Wed Dec 22 13:17:42 2010 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Dec 2010 11:17:42 -0800 Subject: [llvm-commits] [llvm] r122353 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp In-Reply-To: <0DDC2D28-934E-45FD-ABFC-F55863B93941@apple.com> References: <20101221200006.D16D32A6C12C@llvm.org> <38476CE2-6095-4AB5-A50A-B0259B1BEBFB@apple.com> <0DDC2D28-934E-45FD-ABFC-F55863B93941@apple.com> Message-ID: On Dec 22, 2010, at 10:14 AM, dalej wrote: > > On Dec 21, 2010, at 6:04 PM, Chris Lattner wrote: > >> >> On Dec 21, 2010, at 12:00 PM, Dale Johannesen wrote: >> >>> Author: johannes >>> Date: Tue Dec 21 14:00:06 2010 >>> New Revision: 122353 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=122353&view=rev >>> Log: >>> Shift by the word size is invalid IR; don't create it. >> >> I agree, but testcase? > > I don't have one; spotted by inspection. Ok. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101222/45ffb7f3/attachment.html From aggarwa4 at illinois.edu Wed Dec 22 14:42:07 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Dec 2010 20:42:07 -0000 Subject: [llvm-commits] [poolalloc] r122435 - /poolalloc/trunk/runtime/PreRT/strdup.c Message-ID: <20101222204207.921422A6C12C@llvm.org> Author: aggarwa4 Date: Wed Dec 22 14:42:07 2010 New Revision: 122435 URL: http://llvm.org/viewvc/llvm-project?rev=122435&view=rev Log: Also handle __strdup, as that seems to be generated in some cases. Modified: poolalloc/trunk/runtime/PreRT/strdup.c Modified: poolalloc/trunk/runtime/PreRT/strdup.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/runtime/PreRT/strdup.c?rev=122435&r1=122434&r2=122435&view=diff ============================================================================== --- poolalloc/trunk/runtime/PreRT/strdup.c (original) +++ poolalloc/trunk/runtime/PreRT/strdup.c Wed Dec 22 14:42:07 2010 @@ -2,6 +2,7 @@ #include #undef strdup +#undef __strdup char* strdup(const char *s) { @@ -14,3 +15,13 @@ return (char *) memcpy (new, s, len); } +char* __strdup(const char *s) +{ + size_t len = strlen (s) + 1; + void *new = malloc (len); + + if (new == NULL) + return NULL; + + return (char *) memcpy (new, s, len); +} From criswell at uiuc.edu Wed Dec 22 15:11:40 2010 From: criswell at uiuc.edu (John Criswell) Date: Wed, 22 Dec 2010 21:11:40 -0000 Subject: [llvm-commits] [poolalloc] r122437 - /poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Message-ID: <20101222211140.C39962A6C12C@llvm.org> Author: criswell Date: Wed Dec 22 15:11:40 2010 New Revision: 122437 URL: http://llvm.org/viewvc/llvm-project?rev=122437&view=rev Log: Strip pointer casts when determining if a pool handle is a local alloca instruction. This gets APA to correctly recognize pools used by run-time checks. Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=122437&r1=122436&r2=122437&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Wed Dec 22 15:11:40 2010 @@ -58,8 +58,7 @@ template void AddPoolUse(InstType &I, Value *PoolHandle, SetType &Set) { - // FIXME: Strip away pointer casts - if (AllocaInst *AI = dyn_cast(PoolHandle)) + if (AllocaInst *AI=dyn_cast(PoolHandle->stripPointerCasts())) Set.insert(std::make_pair(AI, &I)); } From rafael.espindola at gmail.com Wed Dec 22 15:15:13 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 21:15:13 -0000 Subject: [llvm-commits] [llvm] r122438 - /llvm/trunk/test/MC/MachO/loc.s Message-ID: <20101222211513.C51162A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 15:15:13 2010 New Revision: 122438 URL: http://llvm.org/viewvc/llvm-project?rev=122438&view=rev Log: Add reduced test from 8845. Added: llvm/trunk/test/MC/MachO/loc.s Added: llvm/trunk/test/MC/MachO/loc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/loc.s?rev=122438&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/loc.s (added) +++ llvm/trunk/test/MC/MachO/loc.s Wed Dec 22 15:15:13 2010 @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + + .file 1 "foo" + .loc 1 64 0 + nop + +// CHECK: # Section 1 +// CHECK-NEXT: (('section_name', '__debug_line\x00\x00\x00\x00') +// CHECK-NEXT: ('segment_name', '__DWARF\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK-NEXT: ('address', 1) +// CHECK-NEXT: ('size', 51) +// CHECK-NEXT: ('offset', 221) +// CHECK-NEXT: ('alignment', 0) +// CHECK-NEXT: ('reloc_offset', 272) +// CHECK-NEXT: ('num_reloc', 1) +// CHECK-NEXT: ('flags', 0x2000000) +// CHECK-NEXT: ('reserved1', 0) +// CHECK-NEXT: ('reserved2', 0) +// CHECK-NEXT: ), +// CHECK-NEXT: ('_relocations', [ +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('word-0', 0x27), +// CHECK-NEXT: ('word-1', 0x4000001)), +// CHECK-NEXT: ]) +// CHECK-NEXT: ('_section_data', '2f000000 02001a00 00000101 fb0e0d00 01010101 00000001 00000100 666f6f00 00000000 00050200 00000003 3f010201 000101') From aggarwa4 at illinois.edu Wed Dec 22 15:21:04 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Wed, 22 Dec 2010 21:21:04 -0000 Subject: [llvm-commits] [poolalloc] r122440 - in /poolalloc/trunk: include/dsa/AddressTakenAnalysis.h include/dsa/DataStructure.h lib/DSA/AddressTakenAnalysis.cpp lib/DSA/Local.cpp Message-ID: <20101222212104.2D9642A6C12C@llvm.org> Author: aggarwa4 Date: Wed Dec 22 15:21:03 2010 New Revision: 122440 URL: http://llvm.org/viewvc/llvm-project?rev=122440&view=rev Log: Add an analysis pass to figure out which functions are address taken. Query this pass in Local DSA. Added: poolalloc/trunk/include/dsa/AddressTakenAnalysis.h poolalloc/trunk/lib/DSA/AddressTakenAnalysis.cpp Modified: poolalloc/trunk/include/dsa/DataStructure.h poolalloc/trunk/lib/DSA/Local.cpp Added: poolalloc/trunk/include/dsa/AddressTakenAnalysis.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/AddressTakenAnalysis.h?rev=122440&view=auto ============================================================================== --- poolalloc/trunk/include/dsa/AddressTakenAnalysis.h (added) +++ poolalloc/trunk/include/dsa/AddressTakenAnalysis.h Wed Dec 22 15:21:03 2010 @@ -0,0 +1,48 @@ +//===-- AddressTakenAnalysis.h - Entry point Finding Pass -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass helps find which functions are address taken in a module. +// Functions are considered to be address taken if they are either stored, +// or passed as arguments to functions. +// +//===----------------------------------------------------------------------===// + +#ifndef _ADDRESSTAKENANALYSIS_H +#define _ADDRESSTAKENANALYSIS_H + +namespace llvm { +class Function; +class Module; +class Instruction; + + +#include +#include "llvm/Pass.h" + +class AddressTakenAnalysis : public llvm::ModulePass { + std::set addressTakenFunctions; +public: + static char ID; + AddressTakenAnalysis(); + virtual ~AddressTakenAnalysis(); + + bool runOnModule(llvm::Module&); + + virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; + + bool hasAddressTaken(llvm::Function *); + +}; + +} + + + +#endif /* _ADDRESSTAKENANALYSIS_H */ + Modified: poolalloc/trunk/include/dsa/DataStructure.h URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=122440&r1=122439&r2=122440&view=diff ============================================================================== --- poolalloc/trunk/include/dsa/DataStructure.h (original) +++ poolalloc/trunk/include/dsa/DataStructure.h Wed Dec 22 15:21:03 2010 @@ -22,6 +22,7 @@ #include "dsa/DSCallGraph.h" #include "dsa/svset.h" #include "dsa/super_set.h" +#include "dsa/AddressTakenAnalysis.h" #include @@ -174,6 +175,7 @@ // be automatically preserved. Until we can do that, this is a Pass. // class LocalDataStructures : public DataStructures { + AddressTakenAnalysis* addrAnalysis; public: static char ID; LocalDataStructures() : DataStructures((intptr_t)&ID, "local.") {} @@ -185,6 +187,7 @@ /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } }; Added: poolalloc/trunk/lib/DSA/AddressTakenAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/AddressTakenAnalysis.cpp?rev=122440&view=auto ============================================================================== --- poolalloc/trunk/lib/DSA/AddressTakenAnalysis.cpp (added) +++ poolalloc/trunk/lib/DSA/AddressTakenAnalysis.cpp Wed Dec 22 15:21:03 2010 @@ -0,0 +1,82 @@ +//===-- AddressTakenAnalysis.cpp - Address Taken Functions Finding Pass ---===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass helps find which functions are address taken in a module. +// Functions are considered to be address taken if they are either stored, +// or passed as arguments to functions. +// +// +//===----------------------------------------------------------------------===// + +#include "llvm/Pass.h" +#include "llvm/Module.h" +#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/CallSite.h" + +#include +#include + +#include "dsa/AddressTakenAnalysis.h" + +using namespace llvm; + + +AddressTakenAnalysis::AddressTakenAnalysis() :ModulePass(&ID) { +} + +AddressTakenAnalysis::~AddressTakenAnalysis() {} + +static bool isAddressTaken(Value* V) { + for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { + User *U = *I; + if (!isa(U) && !isa(U)) { + if(isa(U)) { + if(isAddressTaken(U)) + return true; + } else { + // FIXME handle bitcasts to see if the resultant value + // is ever used in an address taken fashion + return true; + } + + // FIXME: Can be more robust here for weak aliases that + // are never used + } else { + llvm::CallSite CS(cast(U)); + if (!CS.isCallee(I)) { + return true; + } + } + } + return false; +} + +bool AddressTakenAnalysis::runOnModule(llvm::Module& M) { + for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI){ + if(isAddressTaken(FI)) { + addressTakenFunctions.insert(FI); + } + } + + return false; +} +bool AddressTakenAnalysis::hasAddressTaken(llvm::Function *F){ + return addressTakenFunctions.find(F) != addressTakenFunctions.end(); +} + +void AddressTakenAnalysis::getAnalysisUsage(llvm::AnalysisUsage &AU) const { + AU.setPreservesAll(); +} + +char AddressTakenAnalysis::ID; +static RegisterPass A("ata", "Identify Address Taken Functions"); Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=122440&r1=122439&r2=122440&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Wed Dec 22 15:21:03 2010 @@ -1180,6 +1180,7 @@ bool LocalDataStructures::runOnModule(Module &M) { init(&getAnalysis()); + addrAnalysis = &getAnalysis(); // First step, build the globals graph. { @@ -1197,7 +1198,7 @@ // Add Functions to the globals graph. // FIXME: Write a separate pass to handle address taken property better. for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI){ - if(FI->hasAddressTaken()) { + if(addrAnalysis->hasAddressTaken(FI)) { GGB.mergeFunction(FI); } } From daniel at zuster.org Wed Dec 22 15:26:43 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 22 Dec 2010 21:26:43 -0000 Subject: [llvm-commits] [llvm] r122441 - in /llvm/trunk: lib/MC/MachObjectWriter.cpp test/MC/MachO/darwin-ARM-reloc.s Message-ID: <20101222212643.AA8C22A6C12C@llvm.org> Author: ddunbar Date: Wed Dec 22 15:26:43 2010 New Revision: 122441 URL: http://llvm.org/viewvc/llvm-project?rev=122441&view=rev Log: MC/Mach-O/ARM: Don't try to use scattered relocs for BR24 fixups. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=122441&r1=122440&r2=122441&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Dec 22 15:26:43 2010 @@ -962,7 +962,7 @@ // // Is this right for ARM? uint32_t Offset = Target.getConstant(); - if (IsPCRel) + if (IsPCRel && !Is24BitBranch) Offset += 1 << Log2Size; if (Offset && SD && !doesSymbolRequireExternRelocation(SD)) return RecordARMScatteredRelocation(Asm, Layout, Fragment, Fixup, Modified: llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s?rev=122441&r1=122440&r2=122441&view=diff ============================================================================== --- llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s (original) +++ llvm/trunk/test/MC/MachO/darwin-ARM-reloc.s Wed Dec 22 15:26:43 2010 @@ -7,6 +7,9 @@ _f0: bl _printf +_f1: + bl _f0 + .data _d0: Ld0_0: @@ -28,9 +31,9 @@ @ CHECK: ('size', 260) @ CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('vm_addr', 0) -@ CHECK: ('vm_size', 12) +@ CHECK: ('vm_size', 16) @ CHECK: ('file_offset', 392) -@ CHECK: ('file_size', 12) +@ CHECK: ('file_size', 16) @ CHECK: ('maxprot', 7) @ CHECK: ('initprot', 7) @ CHECK: ('num_sections', 3) @@ -40,29 +43,32 @@ @ CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('address', 0) -@ CHECK: ('size', 4) +@ CHECK: ('size', 8) @ CHECK: ('offset', 392) @ CHECK: ('alignment', 0) -@ CHECK: ('reloc_offset', 404) -@ CHECK: ('num_reloc', 1) +@ CHECK: ('reloc_offset', 408) +@ CHECK: ('num_reloc', 2) @ CHECK: ('flags', 0x80000400) @ CHECK: ('reserved1', 0) @ CHECK: ('reserved2', 0) @ CHECK: ), @ CHECK: ('_relocations', [ @ CHECK: # Relocation 0 +@ CHECK: (('word-0', 0x4), +@ CHECK: ('word-1', 0x55000001)), +@ CHECK: # Relocation 1 @ CHECK: (('word-0', 0x0), -@ CHECK: ('word-1', 0x5d000002)), +@ CHECK: ('word-1', 0x5d000003)), @ CHECK: ]) -@ CHECK: ('_section_data', 'feffffeb') +@ CHECK: ('_section_data', 'feffffeb fdffffeb') @ CHECK: # Section 1 @ CHECK: (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -@ CHECK: ('address', 4) +@ CHECK: ('address', 8) @ CHECK: ('size', 4) -@ CHECK: ('offset', 396) +@ CHECK: ('offset', 400) @ CHECK: ('alignment', 0) -@ CHECK: ('reloc_offset', 412) +@ CHECK: ('reloc_offset', 424) @ CHECK: ('num_reloc', 2) @ CHECK: ('flags', 0x0) @ CHECK: ('reserved1', 0) @@ -71,18 +77,18 @@ @ CHECK: ('_relocations', [ @ CHECK: # Relocation 0 @ CHECK: (('word-0', 0xa2000000), -@ CHECK: ('word-1', 0x8)), +@ CHECK: ('word-1', 0xc)), @ CHECK: # Relocation 1 @ CHECK: (('word-0', 0xa1000000), -@ CHECK: ('word-1', 0x4)), +@ CHECK: ('word-1', 0x8)), @ CHECK: ]) @ CHECK: ('_section_data', '04000000') @ CHECK: # Section 2 @ CHECK: (('section_name', '__cstring\x00\x00\x00\x00\x00\x00\x00') @ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -@ CHECK: ('address', 8) +@ CHECK: ('address', 12) @ CHECK: ('size', 4) -@ CHECK: ('offset', 400) +@ CHECK: ('offset', 404) @ CHECK: ('alignment', 0) @ CHECK: ('reloc_offset', 0) @ CHECK: ('num_reloc', 0) @@ -98,11 +104,11 @@ @ CHECK: # Load Command 1 @ CHECK: (('command', 2) @ CHECK: ('size', 24) -@ CHECK: ('symoff', 428) -@ CHECK: ('nsyms', 3) -@ CHECK: ('stroff', 464) -@ CHECK: ('strsize', 20) -@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00_d0\x00\x00\x00\x00') +@ CHECK: ('symoff', 440) +@ CHECK: ('nsyms', 4) +@ CHECK: ('stroff', 488) +@ CHECK: ('strsize', 24) +@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00_f1\x00_d0\x00\x00\x00\x00') @ CHECK: ('_symbols', [ @ CHECK: # Symbol 0 @ CHECK: (('n_strx', 9) @@ -115,12 +121,20 @@ @ CHECK: # Symbol 1 @ CHECK: (('n_strx', 13) @ CHECK: ('n_type', 0xe) -@ CHECK: ('n_sect', 2) +@ CHECK: ('n_sect', 1) @ CHECK: ('n_desc', 0) @ CHECK: ('n_value', 4) -@ CHECK: ('_string', '_d0') +@ CHECK: ('_string', '_f1') @ CHECK: ), @ CHECK: # Symbol 2 +@ CHECK: (('n_strx', 17) +@ CHECK: ('n_type', 0xe) +@ CHECK: ('n_sect', 2) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 8) +@ CHECK: ('_string', '_d0') +@ CHECK: ), +@ CHECK: # Symbol 3 @ CHECK: (('n_strx', 1) @ CHECK: ('n_type', 0x1) @ CHECK: ('n_sect', 0) @@ -134,10 +148,10 @@ @ CHECK: (('command', 11) @ CHECK: ('size', 80) @ CHECK: ('ilocalsym', 0) -@ CHECK: ('nlocalsym', 2) -@ CHECK: ('iextdefsym', 2) +@ CHECK: ('nlocalsym', 3) +@ CHECK: ('iextdefsym', 3) @ CHECK: ('nextdefsym', 0) -@ CHECK: ('iundefsym', 2) +@ CHECK: ('iundefsym', 3) @ CHECK: ('nundefsym', 1) @ CHECK: ('tocoff', 0) @ CHECK: ('ntoc', 0) From rafael.espindola at gmail.com Wed Dec 22 15:51:29 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 21:51:29 -0000 Subject: [llvm-commits] [llvm] r122443 - in /llvm/trunk: include/llvm/MC/MCAsmInfo.h lib/MC/MCAsmInfo.cpp lib/MC/MCAsmInfoDarwin.cpp lib/MC/MCStreamer.cpp Message-ID: <20101222215129.801CA2A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 15:51:29 2010 New Revision: 122443 URL: http://llvm.org/viewvc/llvm-project?rev=122443&view=rev Log: Rename NeedsSetToChangeDiffSize to HasAggressiveSymbolFolding which is a much better name and matches what is used in the MachO writer. Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h llvm/trunk/lib/MC/MCAsmInfo.cpp llvm/trunk/lib/MC/MCAsmInfoDarwin.cpp llvm/trunk/lib/MC/MCStreamer.cpp Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=122443&r1=122442&r2=122443&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original) +++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Wed Dec 22 15:51:29 2010 @@ -197,12 +197,12 @@ /// HasSetDirective - True if the assembler supports the .set directive. bool HasSetDirective; // Defaults to true. - /// NeedsSetToChangeDiffSize - True if the assembler requires that we do + /// HasAggressiveSymbolFolding - False if the assembler requires that we use /// Lc = a - b /// .long Lc - /// instead of doing + /// instead of /// .long a - b - bool NeedsSetToChangeDiffSize; // Defaults to false. + bool HasAggressiveSymbolFolding; // Defaults to true. /// HasLCOMMDirective - This is true if the target supports the .lcomm /// directive. @@ -407,7 +407,9 @@ return ExternDirective; } bool hasSetDirective() const { return HasSetDirective; } - bool needsSetToChangeDiffSize() const { return NeedsSetToChangeDiffSize; } + bool hasAggressiveSymbolFolding() const { + return HasAggressiveSymbolFolding; + } bool hasLCOMMDirective() const { return HasLCOMMDirective; } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { Modified: llvm/trunk/lib/MC/MCAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmInfo.cpp?rev=122443&r1=122442&r2=122443&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmInfo.cpp (original) +++ llvm/trunk/lib/MC/MCAsmInfo.cpp Wed Dec 22 15:51:29 2010 @@ -54,7 +54,7 @@ GPRel32Directive = 0; GlobalDirective = "\t.globl\t"; HasSetDirective = true; - NeedsSetToChangeDiffSize = false; + HasAggressiveSymbolFolding = true; HasLCOMMDirective = false; COMMDirectiveAlignmentIsInBytes = true; HasDotTypeDotSizeDirective = true; Modified: llvm/trunk/lib/MC/MCAsmInfoDarwin.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmInfoDarwin.cpp?rev=122443&r1=122442&r2=122443&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmInfoDarwin.cpp (original) +++ llvm/trunk/lib/MC/MCAsmInfoDarwin.cpp Wed Dec 22 15:51:29 2010 @@ -41,7 +41,9 @@ // FIXME: Darwin 10 and newer don't need this. LinkerRequiresNonEmptyDwarfLines = true; - NeedsSetToChangeDiffSize = true; + // FIXME: Change this once MC is the system assembler. + HasAggressiveSymbolFolding = false; + HiddenVisibilityAttr = MCSA_PrivateExtern; // Doesn't support protected visibility. ProtectedVisibilityAttr = MCSA_Global; Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122443&r1=122442&r2=122443&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Wed Dec 22 15:51:29 2010 @@ -77,7 +77,7 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { - if (!getContext().getAsmInfo().needsSetToChangeDiffSize()) { + if (getContext().getAsmInfo().hasAggressiveSymbolFolding()) { EmitValue(Value, Size, AddrSpace); return; } From stoklund at 2pi.dk Wed Dec 22 16:01:28 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 22 Dec 2010 22:01:28 -0000 Subject: [llvm-commits] [llvm] r122444 - /llvm/trunk/lib/CodeGen/SplitKit.cpp Message-ID: <20101222220128.A4FAB2A6C12C@llvm.org> Author: stoklund Date: Wed Dec 22 16:01:28 2010 New Revision: 122444 URL: http://llvm.org/viewvc/llvm-project?rev=122444&view=rev Log: Include a shadow of the original CFG edges in the edge bundle graph. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=122444&r1=122443&r2=122444&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Wed Dec 22 16:01:28 2010 @@ -75,6 +75,10 @@ O << "\t\"BB#" << BB << "\" [ shape=box ]\n" << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n" << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n'; + for (MachineBasicBlock::const_succ_iterator SI = I->succ_begin(), + SE = I->succ_end(); SI != SE; ++SI) + O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber() + << "\" [ color=lightgray ]\n"; } O << "}\n"; return O; From stoklund at 2pi.dk Wed Dec 22 16:01:31 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 22 Dec 2010 22:01:31 -0000 Subject: [llvm-commits] [llvm] r122445 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20101222220131.251362A6C12D@llvm.org> Author: stoklund Date: Wed Dec 22 16:01:30 2010 New Revision: 122445 URL: http://llvm.org/viewvc/llvm-project?rev=122445&view=rev Log: When RegAllocGreedy decides to spill the interferences of the current register, pick the victim with the lowest total spill weight. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=122445&r1=122444&r2=122445&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Wed Dec 22 16:01:30 2010 @@ -94,10 +94,13 @@ bool reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg); unsigned findInterferenceFreeReg(MachineLoopRange*, LiveInterval&, AllocationOrder&); + float calcInterferenceWeight(LiveInterval&, unsigned); unsigned tryReassign(LiveInterval&, AllocationOrder&); unsigned trySplit(LiveInterval&, AllocationOrder&, SmallVectorImpl&); + unsigned trySpillInterferences(LiveInterval&, AllocationOrder&, + SmallVectorImpl&); }; } // end anonymous namespace @@ -164,6 +167,11 @@ return Priority; } + +//===----------------------------------------------------------------------===// +// Register Reassignment +//===----------------------------------------------------------------------===// + // Check interference without using the cache. bool RAGreedy::checkUncachedInterference(LiveInterval &VirtReg, unsigned PhysReg) { @@ -263,6 +271,11 @@ return 0; } + +//===----------------------------------------------------------------------===// +// Loop Splitting +//===----------------------------------------------------------------------===// + /// findInterferenceFreeReg - Find a physical register in Order where Loop has /// no interferences with VirtReg. unsigned RAGreedy::findInterferenceFreeReg(MachineLoopRange *Loop, @@ -338,29 +351,81 @@ return 0; } -unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, - SmallVectorImpl &SplitVRegs) { - // Populate a list of physical register spill candidates. - SmallVector PhysRegSpillCands; - // Check for an available register in this class. +//===----------------------------------------------------------------------===// +// Spilling +//===----------------------------------------------------------------------===// + +/// calcInterferenceWeight - Calculate the combined spill weight of +/// interferences when assigning VirtReg to PhysReg. +float RAGreedy::calcInterferenceWeight(LiveInterval &VirtReg, unsigned PhysReg){ + float Sum = 0; + for (const unsigned *AI = TRI->getOverlaps(PhysReg); *AI; ++AI) { + LiveIntervalUnion::Query &Q = query(VirtReg, *AI); + Q.collectInterferingVRegs(); + if (Q.seenUnspillableVReg()) + return HUGE_VALF; + for (unsigned i = 0, e = Q.interferingVRegs().size(); i != e; ++i) + Sum += Q.interferingVRegs()[i]->weight; + } + return Sum; +} + +/// trySpillInterferences - Try to spill interfering registers instead of the +/// current one. Only do it if the accumulated spill weight is smaller than the +/// current spill weight. +unsigned RAGreedy::trySpillInterferences(LiveInterval &VirtReg, + AllocationOrder &Order, + SmallVectorImpl &NewVRegs) { + NamedRegionTimer T("Spill Interference", TimerGroupName, TimePassesIsEnabled); + unsigned BestPhys = 0; + float BestWeight; + + Order.rewind(); + while (unsigned PhysReg = Order.next()) { + float Weight = calcInterferenceWeight(VirtReg, PhysReg); + if (Weight == HUGE_VALF || Weight >= VirtReg.weight) + continue; + if (!BestPhys || Weight < BestWeight) + BestPhys = PhysReg, BestWeight = Weight; + } + + // No candidates found. + if (!BestPhys) + return 0; + + // Collect all interfering registers. + SmallVector Spills; + for (const unsigned *AI = TRI->getOverlaps(BestPhys); *AI; ++AI) { + LiveIntervalUnion::Query &Q = query(VirtReg, *AI); + Spills.append(Q.interferingVRegs().begin(), Q.interferingVRegs().end()); + for (unsigned i = 0, e = Q.interferingVRegs().size(); i != e; ++i) { + LiveInterval *VReg = Q.interferingVRegs()[i]; + PhysReg2LiveUnion[*AI].extract(*VReg); + VRM->clearVirt(VReg->reg); + } + } + + // Spill them all. + DEBUG(dbgs() << "spilling " << Spills.size() << " interferences with weight " + << BestWeight << '\n'); + for (unsigned i = 0, e = Spills.size(); i != e; ++i) + spiller().spill(Spills[i], NewVRegs, Spills); + return BestPhys; +} + + +//===----------------------------------------------------------------------===// +// Main Entry Point +//===----------------------------------------------------------------------===// + +unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, + SmallVectorImpl &SplitVRegs) { + // First try assigning a free register. AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs); while (unsigned PhysReg = Order.next()) { - // Check interference and as a side effect, intialize queries for this - // VirtReg and its aliases. - unsigned InterfReg = checkPhysRegInterference(VirtReg, PhysReg); - if (InterfReg == 0) { - // Found an available register. + if (!checkPhysRegInterference(VirtReg, PhysReg)) return PhysReg; - } - assert(!VirtReg.empty() && "Empty VirtReg has interference"); - LiveInterval *InterferingVirtReg = - Queries[InterfReg].firstInterference().liveUnionPos().value(); - - // The current VirtReg must either be spillable, or one of its interferences - // must have less spill weight. - if (InterferingVirtReg->weight < VirtReg.weight ) - PhysRegSpillCands.push_back(PhysReg); } // Try to reassign interferences. @@ -373,26 +438,13 @@ return PhysReg; // Try to spill another interfering reg with less spill weight. - NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); - // - // FIXME: do this in two steps: (1) check for unspillable interferences while - // accumulating spill weight; (2) spill the interferences with lowest - // aggregate spill weight. - for (SmallVectorImpl::iterator PhysRegI = PhysRegSpillCands.begin(), - PhysRegE = PhysRegSpillCands.end(); PhysRegI != PhysRegE; ++PhysRegI) { - - if (!spillInterferences(VirtReg, *PhysRegI, SplitVRegs)) continue; - - assert(checkPhysRegInterference(VirtReg, *PhysRegI) == 0 && - "Interference after spill."); - // Tell the caller to allocate to this newly freed physical register. - return *PhysRegI; - } + PhysReg = trySpillInterferences(VirtReg, Order, SplitVRegs); + if (PhysReg) + return PhysReg; - // No other spill candidates were found, so spill the current VirtReg. - DEBUG(dbgs() << "spilling: " << VirtReg << '\n'); + // Finally spill VirtReg itself. + NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); SmallVector pendingSpills; - spiller().spill(&VirtReg, SplitVRegs, pendingSpills); // The live virtual register requesting allocation was spilled, so tell From rafael.espindola at gmail.com Wed Dec 22 16:04:28 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 22:04:28 -0000 Subject: [llvm-commits] [llvm] r122446 - in /llvm/trunk/lib/MC: MCAssembler.cpp MCObjectStreamer.cpp Message-ID: <20101222220428.A2AA82A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 16:04:28 2010 New Revision: 122446 URL: http://llvm.org/viewvc/llvm-project?rev=122446&view=rev Log: Assert that the AddrDelta expression is really constant and wrap it in a set if we have a lame assembler. Modified: llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCObjectStreamer.cpp Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=122446&r1=122445&r2=122446&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed Dec 22 16:04:28 2010 @@ -687,7 +687,9 @@ MCDwarfLineAddrFragment &DF) { int64_t AddrDelta = 0; uint64_t OldSize = DF.getContents().size(); - DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); + bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); + (void)IsAbs; + assert(IsAbs); int64_t LineDelta; LineDelta = DF.getLineDelta(); SmallString<8> &Data = DF.getContents(); Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=122446&r1=122445&r2=122446&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Wed Dec 22 16:04:28 2010 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/Support/ErrorHandling.h" @@ -90,7 +91,7 @@ return; } DF->addFixup(MCFixup::Create(DF->getContents().size(), - AddValueSymbols(Value), + Value, MCFixup::getKindForSize(Size, isPCRel))); DF->getContents().resize(DF->getContents().size() + Size, 0); } @@ -210,6 +211,11 @@ MCDwarfLineAddr::Emit(this, LineDelta, Res); return; } + if (!getContext().getAsmInfo().hasAggressiveSymbolFolding()) { + MCSymbol *ABS = getContext().CreateTempSymbol(); + EmitAssignment(ABS, AddrDelta); + AddrDelta = MCSymbolRefExpr::Create(ABS, getContext()); + } new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); } From gohman at apple.com Wed Dec 22 16:10:08 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 22 Dec 2010 22:10:08 -0000 Subject: [llvm-commits] [llvm] r122447 - /llvm/trunk/include/llvm/Analysis/Dominators.h Message-ID: <20101222221008.7DE3A2A6C12C@llvm.org> Author: djg Date: Wed Dec 22 16:10:08 2010 New Revision: 122447 URL: http://llvm.org/viewvc/llvm-project?rev=122447&view=rev Log: Constify. Modified: llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=122447&r1=122446&r2=122447&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Wed Dec 22 16:10:08 2010 @@ -766,7 +766,7 @@ AU.setPreservesAll(); } - inline bool dominates(DomTreeNode* A, DomTreeNode* B) const { + inline bool dominates(const DomTreeNode* A, const DomTreeNode* B) const { return DT->dominates(A, B); } From rafael.espindola at gmail.com Wed Dec 22 16:16:24 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 22 Dec 2010 22:16:24 -0000 Subject: [llvm-commits] [llvm] r122448 - /llvm/trunk/lib/MC/MCExpr.cpp Message-ID: <20101222221624.9D5112A6C12C@llvm.org> Author: rafael Date: Wed Dec 22 16:16:24 2010 New Revision: 122448 URL: http://llvm.org/viewvc/llvm-project?rev=122448&view=rev Log: Add r122359 back now that the bug in MCDwarfLineAddrFragment fragment has been fixed. Modified: llvm/trunk/lib/MC/MCExpr.cpp Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=122448&r1=122447&r2=122448&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Wed Dec 22 16:16:24 2010 @@ -269,27 +269,13 @@ // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us // absolutize differences across sections and that is what the MachO writer // uses Addrs for. - if (!EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs) || - !Value.isAbsolute()) { - // EvaluateAsAbsolute is defined to return the "current value" of - // the expression if we are given a Layout object, even in cases - // when the value is not fixed. - if (Layout) { - Res = Value.getConstant(); - if (Value.getSymA()) { - Res += Layout->getSymbolOffset( - &Layout->getAssembler().getSymbolData(Value.getSymA()->getSymbol())); - } - if (Value.getSymB()) { - Res -= Layout->getSymbolOffset( - &Layout->getAssembler().getSymbolData(Value.getSymB()->getSymbol())); - } - } - return false; - } + bool IsRelocatable = + EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs); + // Record the current value. Res = Value.getConstant(); - return true; + + return IsRelocatable && Value.isAbsolute(); } /// \brief Helper method for \see EvaluateSymbolAdd(). From benny.kra at googlemail.com Wed Dec 22 17:09:28 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 22 Dec 2010 23:09:28 -0000 Subject: [llvm-commits] [llvm] r122451 - in /llvm/trunk: lib/Target/X86/README.txt lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/select.ll Message-ID: <20101222230928.C6D4B2A6C12C@llvm.org> Author: d0k Date: Wed Dec 22 17:09:28 2010 New Revision: 122451 URL: http://llvm.org/viewvc/llvm-project?rev=122451&view=rev Log: X86: Lower a select directly to a setcc_carry if possible. int test(unsigned long a, unsigned long b) { return -(a < b); } compiles to _test: ## @test cmpq %rsi, %rdi ## encoding: [0x48,0x39,0xf7] sbbl %eax, %eax ## encoding: [0x19,0xc0] ret ## encoding: [0xc3] instead of _test: ## @test xorl %ecx, %ecx ## encoding: [0x31,0xc9] cmpq %rsi, %rdi ## encoding: [0x48,0x39,0xf7] movl $-1, %eax ## encoding: [0xb8,0xff,0xff,0xff,0xff] cmovael %ecx, %eax ## encoding: [0x0f,0x43,0xc1] ret ## encoding: [0xc3] Modified: llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/select.ll Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=122451&r1=122450&r2=122451&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Wed Dec 22 17:09:28 2010 @@ -1165,58 +1165,6 @@ //===---------------------------------------------------------------------===// -Consider: -int test(unsigned long a, unsigned long b) { return -(a < b); } - -We currently compile this to: - -define i32 @test(i32 %a, i32 %b) nounwind { - %tmp3 = icmp ult i32 %a, %b ; [#uses=1] - %tmp34 = zext i1 %tmp3 to i32 ; [#uses=1] - %tmp5 = sub i32 0, %tmp34 ; [#uses=1] - ret i32 %tmp5 -} - -and - -_test: - movl 8(%esp), %eax - cmpl %eax, 4(%esp) - setb %al - movzbl %al, %eax - negl %eax - ret - -Several deficiencies here. First, we should instcombine zext+neg into sext: - -define i32 @test2(i32 %a, i32 %b) nounwind { - %tmp3 = icmp ult i32 %a, %b ; [#uses=1] - %tmp34 = sext i1 %tmp3 to i32 ; [#uses=1] - ret i32 %tmp34 -} - -However, before we can do that, we have to fix the bad codegen that we get for -sext from bool: - -_test2: - movl 8(%esp), %eax - cmpl %eax, 4(%esp) - setb %al - movzbl %al, %eax - shll $31, %eax - sarl $31, %eax - ret - -This code should be at least as good as the code above. Once this is fixed, we -can optimize this specific case even more to: - - movl 8(%esp), %eax - xorl %ecx, %ecx - cmpl %eax, 4(%esp) - sbbl %ecx, %ecx - -//===---------------------------------------------------------------------===// - Take the following code (from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16541): Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122451&r1=122450&r2=122451&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 22 17:09:28 2010 @@ -7313,6 +7313,23 @@ Cond = EmitTest(Cond, X86::COND_NE, DAG); } + // a < b ? -1 : 0 -> RES = ~setcc_carry + // a < b ? 0 : -1 -> RES = setcc_carry + // a >= b ? -1 : 0 -> RES = setcc_carry + // a >= b ? 0 : -1 -> RES = ~setcc_carry + if (Cond.getOpcode() == X86ISD::CMP) { + unsigned CondCode = cast(CC)->getZExtValue(); + + if ((CondCode == X86::COND_AE || CondCode == X86::COND_B) && + (isAllOnes(Op1) || isAllOnes(Op2)) && (isZero(Op1) || isZero(Op2))) { + SDValue Res = DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(), + DAG.getConstant(X86::COND_B, MVT::i8), Cond); + if (isAllOnes(Op1) != (CondCode == X86::COND_B)) + return DAG.getNOT(DL, Res, Res.getValueType()); + return Res; + } + } + // X86ISD::CMOV means set the result (which is operand 1) to the RHS if // condition is true. SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); Modified: llvm/trunk/test/CodeGen/X86/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/select.ll?rev=122451&r1=122450&r2=122451&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/select.ll (original) +++ llvm/trunk/test/CodeGen/X86/select.ll Wed Dec 22 17:09:28 2010 @@ -197,7 +197,24 @@ declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone - - - +define i32 @test13(i32 %a, i32 %b) nounwind { + %c = icmp ult i32 %a, %b + %d = sext i1 %c to i32 + ret i32 %d +; CHECK: test13: +; CHECK: cmpl +; CHECK-NEXT: sbbl +; CHECK-NEXT: ret +} + +define i32 @test14(i32 %a, i32 %b) nounwind { + %c = icmp uge i32 %a, %b + %d = sext i1 %c to i32 + ret i32 %d +; CHECK: test14: +; CHECK: cmpl +; CHECK-NEXT: sbbl +; CHECK-NEXT: notl +; CHECK-NEXT: ret +} From benny.kra at googlemail.com Wed Dec 22 17:12:15 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 22 Dec 2010 23:12:15 -0000 Subject: [llvm-commits] [llvm] r122453 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineSelect.cpp test/Transforms/InstCombine/select.ll Message-ID: <20101222231215.AE9BF2A6C12C@llvm.org> Author: d0k Date: Wed Dec 22 17:12:15 2010 New Revision: 122453 URL: http://llvm.org/viewvc/llvm-project?rev=122453&view=rev Log: InstCombine: creating selects from -1 and 0 is fine, they combine into a sext from i1. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/trunk/test/Transforms/InstCombine/select.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=122453&r1=122452&r2=122453&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Wed Dec 22 17:12:15 2010 @@ -195,7 +195,10 @@ ConstantInt *C2I = dyn_cast(C2); if (!C2I) return false; - return (C1I->isZero() || C1I->isOne()) && (C2I->isZero() || C2I->isOne()); + if (!C1I->isZero() && !C2I->isZero()) // One side must be zero. + return false; + return C1I->isOne() || C1I->isAllOnesValue() || + C2I->isOne() || C2I->isAllOnesValue(); } /// FoldSelectIntoOp - Try fold the select into one of the operands to @@ -219,7 +222,7 @@ Constant *C = GetSelectFoldableConstant(TVI); Value *OOp = TVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting - // between 0 and 1. + // between 0, 1 and -1. if (!isa(OOp) || isSelect01(C, cast(OOp))) { Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C); InsertNewInstBefore(NewSel, SI); @@ -248,7 +251,7 @@ Constant *C = GetSelectFoldableConstant(FVI); Value *OOp = FVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting - // between 0 and 1. + // between 0, 1 and -1. if (!isa(OOp) || isSelect01(C, cast(OOp))) { Instruction *NewSel = SelectInst::Create(SI.getCondition(), C, OOp); InsertNewInstBefore(NewSel, SI); Modified: llvm/trunk/test/Transforms/InstCombine/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=122453&r1=122452&r2=122453&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/select.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/select.ll Wed Dec 22 17:12:15 2010 @@ -584,3 +584,15 @@ ; CHECK-NEXT: and i32 %x, %y ; CHECK-NEXT: ret i32 } + +define i32 @test42(i32 %x, i32 %y) { + %b = add i32 %y, -1 + %cond = icmp eq i32 %x, 0 + %c = select i1 %cond, i32 %b, i32 %y + ret i32 %c +; CHECK: @test42 +; CHECK-NEXT: %cond = icmp eq i32 %x, 0 +; CHECK-NEXT: %b = sext i1 %cond to i32 +; CHECK-NEXT: %c = add i32 %b, %y +; CHECK-NEXT: ret i32 %c +} From benny.kra at googlemail.com Wed Dec 22 17:17:45 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 22 Dec 2010 23:17:45 -0000 Subject: [llvm-commits] [llvm] r122455 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/add.ll Message-ID: <20101222231745.DA7692A6C12C@llvm.org> Author: d0k Date: Wed Dec 22 17:17:45 2010 New Revision: 122455 URL: http://llvm.org/viewvc/llvm-project?rev=122455&view=rev Log: DAGCombine add (sext i1), X into sub X, (zext i1) if sext from i1 is illegal. The latter usually compiles into smaller code. example code: unsigned foo(unsigned x, unsigned y) { if (x != 0) y--; return y; } before: _foo: ## @foo cmpl $1, 4(%esp) ## encoding: [0x83,0x7c,0x24,0x04,0x01] sbbl %eax, %eax ## encoding: [0x19,0xc0] notl %eax ## encoding: [0xf7,0xd0] addl 8(%esp), %eax ## encoding: [0x03,0x44,0x24,0x08] ret ## encoding: [0xc3] after: _foo: ## @foo cmpl $1, 4(%esp) ## encoding: [0x83,0x7c,0x24,0x04,0x01] movl 8(%esp), %eax ## encoding: [0x8b,0x44,0x24,0x08] adcl $-1, %eax ## encoding: [0x83,0xd0,0xff] ret ## encoding: [0xc3] Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/add.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=122455&r1=122454&r2=122455&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Dec 22 17:17:45 2010 @@ -1443,6 +1443,15 @@ } } + // add (sext i1), X -> sub X, (zext i1) + if (N0.getOpcode() == ISD::SIGN_EXTEND && + N0.getOperand(0).getValueType() == MVT::i1 && + !TLI.isOperationLegal(ISD::SIGN_EXTEND, MVT::i1)) { + DebugLoc DL = N->getDebugLoc(); + SDValue ZExt = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)); + return DAG.getNode(ISD::SUB, DL, VT, N1, ZExt); + } + return SDValue(); } Modified: llvm/trunk/test/CodeGen/X86/add.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add.ll?rev=122455&r1=122454&r2=122455&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/add.ll (original) +++ llvm/trunk/test/CodeGen/X86/add.ll Wed Dec 22 17:17:45 2010 @@ -120,3 +120,15 @@ ; X64: addq ; X64-NEXT: sbbq ; X64-NEXT: testb + +define i32 @test9(i32 %x, i32 %y) nounwind readnone { + %cmp = icmp eq i32 %x, 10 + %sub = sext i1 %cmp to i32 + %cond = add i32 %sub, %y + ret i32 %cond +; X64: test9: +; X64: cmpl $10 +; X64: sete +; X64: subl +; X64: ret +} From grosbach at apple.com Wed Dec 22 17:26:02 2010 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 22 Dec 2010 23:26:02 -0000 Subject: [llvm-commits] [llvm] r122456 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Message-ID: <20101222232602.31D932A6C12C@llvm.org> Author: grosbach Date: Wed Dec 22 17:26:02 2010 New Revision: 122456 URL: http://llvm.org/viewvc/llvm-project?rev=122456&view=rev Log: Trailing whitespace. Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp?rev=122456&r1=122455&r2=122456&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp Wed Dec 22 17:26:02 2010 @@ -28,20 +28,20 @@ using namespace llvm; namespace { - + class ARMBaseAsmLexer : public TargetAsmLexer { const MCAsmInfo &AsmInfo; - + const AsmToken &lexDefinite() { return getLexer()->Lex(); } - + AsmToken LexTokenUAL(); protected: typedef std::map rmap_ty; - + rmap_ty RegisterMap; - + void InitRegisterMap(const TargetRegisterInfo *info) { unsigned numRegs = info->getNumRegs(); @@ -51,7 +51,7 @@ RegisterMap[regName] = i; } } - + unsigned MatchRegisterName(StringRef Name) { rmap_ty::iterator iter = RegisterMap.find(Name.str()); if (iter != RegisterMap.end()) @@ -59,13 +59,13 @@ else return 0; } - + AsmToken LexToken() { if (!Lexer) { SetError(SMLoc(), "No MCAsmLexer installed"); return AsmToken(AsmToken::Error, "", 0); } - + switch (AsmInfo.getAssemblerDialect()) { default: SetError(SMLoc(), "Unhandled dialect"); @@ -79,26 +79,26 @@ : TargetAsmLexer(T), AsmInfo(MAI) { } }; - + class ARMAsmLexer : public ARMBaseAsmLexer { public: ARMAsmLexer(const Target &T, const MCAsmInfo &MAI) : ARMBaseAsmLexer(T, MAI) { std::string tripleString("arm-unknown-unknown"); std::string featureString; - OwningPtr + OwningPtr targetMachine(T.createTargetMachine(tripleString, featureString)); InitRegisterMap(targetMachine->getRegisterInfo()); } }; - + class ThumbAsmLexer : public ARMBaseAsmLexer { public: ThumbAsmLexer(const Target &T, const MCAsmInfo &MAI) : ARMBaseAsmLexer(T, MAI) { std::string tripleString("thumb-unknown-unknown"); std::string featureString; - OwningPtr + OwningPtr targetMachine(T.createTargetMachine(tripleString, featureString)); InitRegisterMap(targetMachine->getRegisterInfo()); } @@ -107,7 +107,7 @@ AsmToken ARMBaseAsmLexer::LexTokenUAL() { const AsmToken &lexedToken = lexDefinite(); - + switch (lexedToken.getKind()) { default: return AsmToken(lexedToken); @@ -119,9 +119,9 @@ std::string upperCase = lexedToken.getString().str(); std::string lowerCase = LowercaseString(upperCase); StringRef lowerRef(lowerCase); - + unsigned regID = MatchRegisterName(lowerRef); - + if (regID) { return AsmToken(AsmToken::Register, lexedToken.getString(), From isanbard at gmail.com Wed Dec 22 18:49:18 2010 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Dec 2010 00:49:18 -0000 Subject: [llvm-commits] [llvm] r122457 - /llvm/trunk/utils/buildit/build_llvm Message-ID: <20101223004918.DD2C22A6C12C@llvm.org> Author: void Date: Wed Dec 22 18:49:18 2010 New Revision: 122457 URL: http://llvm.org/viewvc/llvm-project?rev=122457&view=rev Log: Default to armv7 instead of armv6. Modified: llvm/trunk/utils/buildit/build_llvm Modified: llvm/trunk/utils/buildit/build_llvm URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/buildit/build_llvm?rev=122457&r1=122456&r2=122457&view=diff ============================================================================== --- llvm/trunk/utils/buildit/build_llvm (original) +++ llvm/trunk/utils/buildit/build_llvm Wed Dec 22 18:49:18 2010 @@ -105,7 +105,7 @@ T=`xcrun -sdk $SDKROOT -find ${prog}` fi echo '#!/bin/sh' > $P || exit 1 - echo 'exec '$T' -arch armv6 -isysroot '${SDKROOT}' "$@"' >> $P || exit 1 + echo 'exec '$T' -arch armv7 -isysroot '${SDKROOT}' "$@"' >> $P || exit 1 chmod a+x $P || exit 1 done From jyasskin at google.com Wed Dec 22 18:58:25 2010 From: jyasskin at google.com (Jeffrey Yasskin) Date: Thu, 23 Dec 2010 00:58:25 -0000 Subject: [llvm-commits] [llvm] r122458 - in /llvm/trunk: include/llvm/Transforms/Utils/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Support/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ unittests/Support/ utils/TableGen/ Message-ID: <20101223005825.544EB2A6C12C@llvm.org> Author: jyasskin Date: Wed Dec 22 18:58:24 2010 New Revision: 122458 URL: http://llvm.org/viewvc/llvm-project?rev=122458&view=rev Log: Change all self assignments X=X to (void)X, so that we can turn on a new gcc warning that complains on self-assignments and self-initializations. Modified: llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp llvm/trunk/lib/Support/PrettyStackTrace.cpp llvm/trunk/lib/Support/StringMap.cpp llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp llvm/trunk/lib/Transforms/Utils/DemoteRegToStack.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Type.cpp llvm/trunk/lib/VMCore/TypesContext.h llvm/trunk/lib/VMCore/Value.cpp llvm/trunk/unittests/Support/ValueHandleTest.cpp llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/AddrModeMatcher.h Wed Dec 22 18:58:24 2010 @@ -90,7 +90,7 @@ bool Success = AddressingModeMatcher(AddrModeInsts, TLI, AccessTy, MemoryInst, Result).MatchAddr(V, 0); - Success = Success; assert(Success && "Couldn't select *anything*?"); + (void)Success; assert(Success && "Couldn't select *anything*?"); return Result; } private: Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Dec 22 18:58:24 2010 @@ -1216,7 +1216,7 @@ Val.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &lost); // Conversion is always precise. - status = status; + (void)status; assert(status == APFloat::opOK && !lost && "Precision lost during fp16 constfolding"); @@ -1313,4 +1313,3 @@ } return 0; } - Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Dec 22 18:58:24 2010 @@ -100,7 +100,7 @@ InstIt = ReverseMap.find(Inst); assert(InstIt != ReverseMap.end() && "Reverse map out of sync?"); bool Found = InstIt->second.erase(Val); - assert(Found && "Invalid reverse map!"); Found=Found; + assert(Found && "Invalid reverse map!"); (void)Found; if (InstIt->second.empty()) ReverseMap.erase(InstIt); } Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Wed Dec 22 18:58:24 2010 @@ -934,7 +934,7 @@ void RALinScan::DowngradeRegister(LiveInterval *li, unsigned Reg) { bool isNew = DowngradedRegs.insert(Reg); - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Multiple reloads holding the same register?"); DowngradeMap.insert(std::make_pair(li->reg, Reg)); for (const unsigned *AS = tri_->getAliasSet(Reg); *AS; ++AS) { Modified: llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp Wed Dec 22 18:58:24 2010 @@ -57,7 +57,7 @@ assert(I->getReg() && "Unknown physical register!"); unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC); bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); BuildMI(*BB, InsertPos, DebugLoc(), TII->get(TargetOpcode::COPY), VRBase) .addReg(I->getReg()); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Wed Dec 22 18:58:24 2010 @@ -67,7 +67,7 @@ if (IsClone) VRBaseMap.erase(Op); bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); return; } @@ -150,7 +150,7 @@ if (IsClone) VRBaseMap.erase(Op); bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); } @@ -224,7 +224,7 @@ if (IsClone) VRBaseMap.erase(Op); bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); } } @@ -496,7 +496,7 @@ SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); } @@ -518,7 +518,7 @@ SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); } @@ -555,7 +555,7 @@ MBB->insert(InsertPos, MI); SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; - isNew = isNew; // Silence compiler warning. + (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); } Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed Dec 22 18:58:24 2010 @@ -646,7 +646,7 @@ } else { SmallVector NewMIs; bool Success = TII->unfoldMemoryOperand(MF, MI, Reg, false, false, NewMIs); - Success = Success; // Silence compiler warning. + (void)Success; // Silence compiler warning. assert(Success && "Failed to unfold!"); MachineInstr *NewMI = NewMIs[0]; MBB->insert(MI, NewMI); Modified: llvm/trunk/lib/Support/PrettyStackTrace.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PrettyStackTrace.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Support/PrettyStackTrace.cpp (original) +++ llvm/trunk/lib/Support/PrettyStackTrace.cpp Wed Dec 22 18:58:24 2010 @@ -107,7 +107,7 @@ PrettyStackTraceEntry::PrettyStackTraceEntry() { // The first time this is called, we register the crash printer. static bool HandlerRegistered = RegisterCrashPrinter(); - HandlerRegistered = HandlerRegistered; + (void)HandlerRegistered; // Link ourselves. NextEntry = PrettyStackTraceHead.get(); @@ -131,4 +131,3 @@ OS << ArgV[i] << ' '; OS << '\n'; } - Modified: llvm/trunk/lib/Support/StringMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringMap.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringMap.cpp (original) +++ llvm/trunk/lib/Support/StringMap.cpp Wed Dec 22 18:58:24 2010 @@ -155,7 +155,7 @@ void StringMapImpl::RemoveKey(StringMapEntryBase *V) { const char *VStr = (char*)V + ItemSize; StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength())); - V2 = V2; + (void)V2; assert(V == V2 && "Didn't find key?"); } Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Wed Dec 22 18:58:24 2010 @@ -325,7 +325,7 @@ case ISD::SUBE: case ISD::ADDE: { SDValue InFlag = Node->getOperand(2), CmpLHS; - unsigned Opc = InFlag.getOpcode(); Opc=Opc; + unsigned Opc = InFlag.getOpcode(); (void)Opc; assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || (Opc == ISD::SUBC || Opc == ISD::SUBE)) && "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Dec 22 18:58:24 2010 @@ -1058,7 +1058,6 @@ VT = LD->getMemoryVT(); } else if (StoreSDNode *ST = dyn_cast(N)) { - ST = ST; Ptr = ST->getBasePtr(); VT = ST->getMemoryVT(); } else Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Wed Dec 22 18:58:24 2010 @@ -504,7 +504,7 @@ DEBUG(dbgs() << "Replace stores:\n"; for (unsigned i = 0, e = Range.TheStores.size(); i != e; ++i) dbgs() << *Range.TheStores[i] << '\n'; - dbgs() << "With: " << *C << '\n'); C=C; + dbgs() << "With: " << *C << '\n'); (void)C; // Don't invalidate the iterator BBI = BI; @@ -932,6 +932,3 @@ MD = 0; return MadeChange; } - - - Modified: llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/AddrModeMatcher.cpp Wed Dec 22 18:58:24 2010 @@ -568,7 +568,7 @@ MemoryInst, Result); Matcher.IgnoreProfitability = true; bool Success = Matcher.MatchAddr(Address, 0); - Success = Success; assert(Success && "Couldn't select *anything*?"); + (void)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(), Modified: llvm/trunk/lib/Transforms/Utils/DemoteRegToStack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/DemoteRegToStack.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/DemoteRegToStack.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/DemoteRegToStack.cpp Wed Dec 22 18:58:24 2010 @@ -129,7 +129,7 @@ for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) { if (InvokeInst *II = dyn_cast(P->getIncomingValue(i))) { assert(II->getParent() != P->getIncomingBlock(i) && - "Invoke edge not supported yet"); II=II; + "Invoke edge not supported yet"); (void)II; } new StoreInst(P->getIncomingValue(i), Slot, P->getIncomingBlock(i)->getTerminator()); Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Wed Dec 22 18:58:24 2010 @@ -186,7 +186,7 @@ const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((NumParams == FTy->getNumParams() || (FTy->isVarArg() && NumParams > FTy->getNumParams())) && @@ -207,7 +207,7 @@ const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((FTy->getNumParams() == 2 || (FTy->isVarArg() && FTy->getNumParams() < 2)) && @@ -227,7 +227,7 @@ const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert((FTy->getNumParams() == 1 || (FTy->isVarArg() && FTy->getNumParams() == 0)) && @@ -243,7 +243,7 @@ const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); } @@ -500,7 +500,7 @@ Op<-1>() = IfException; const FunctionType *FTy = cast(cast(Fn->getType())->getElementType()); - FTy = FTy; // silence warning. + (void)FTy; // silence warning. assert(((NumArgs == FTy->getNumParams()) || (FTy->isVarArg() && NumArgs > FTy->getNumParams())) && @@ -1579,7 +1579,7 @@ void BinaryOperator::init(BinaryOps iType) { Value *LHS = getOperand(0), *RHS = getOperand(1); - LHS = LHS; RHS = RHS; // Silence warnings. + (void)LHS; (void)RHS; // Silence warnings. assert(LHS->getType() == RHS->getType() && "Binary operator operand types must match!"); #ifndef NDEBUG Modified: llvm/trunk/lib/VMCore/Type.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Type.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Type.cpp (original) +++ llvm/trunk/lib/VMCore/Type.cpp Wed Dec 22 18:58:24 2010 @@ -1103,7 +1103,7 @@ while (!AbstractTypeUsers.empty() && NewTy != this) { AbstractTypeUser *User = AbstractTypeUsers.back(); - unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; + unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; #ifdef DEBUG_MERGE_TYPES DEBUG(dbgs() << " REFINING user " << OldSize-1 << "[" << (void*)User << "] of abstract type [" << (void*)this << " " @@ -1130,7 +1130,7 @@ DEBUG(dbgs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n"); #endif - unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; + unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; while (!AbstractTypeUsers.empty()) { AbstractTypeUser *ATU = AbstractTypeUsers.back(); ATU->typeBecameConcrete(this); Modified: llvm/trunk/lib/VMCore/TypesContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/TypesContext.h?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/TypesContext.h (original) +++ llvm/trunk/lib/VMCore/TypesContext.h Wed Dec 22 18:58:24 2010 @@ -317,7 +317,7 @@ // The old record is now out-of-date, because one of the children has been // updated. Remove the obsolete entry from the map. unsigned NumErased = Map.erase(ValType::get(Ty)); - assert(NumErased && "Element not found!"); NumErased = NumErased; + assert(NumErased && "Element not found!"); (void)NumErased; // Remember the structural hash for the type before we start hacking on it, // in case we need it later. Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Wed Dec 22 18:58:24 2010 @@ -255,7 +255,7 @@ // Get V's ST, this should always succed, because V has a name. ValueSymbolTable *VST; bool Failure = getSymTab(V, VST); - assert(!Failure && "V has a name, so it should have a ST!"); Failure=Failure; + assert(!Failure && "V has a name, so it should have a ST!"); (void)Failure; // If these values are both in the same symtab, we can do this very fast. // This works even if both values have no symtab yet. Modified: llvm/trunk/unittests/Support/ValueHandleTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ValueHandleTest.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/unittests/Support/ValueHandleTest.cpp (original) +++ llvm/trunk/unittests/Support/ValueHandleTest.cpp Wed Dec 22 18:58:24 2010 @@ -108,7 +108,7 @@ TEST_F(ValueHandle, AssertingVH_BasicOperation) { AssertingVH AVH(BitcastV.get()); CastInst *implicit_to_exact_type = AVH; - implicit_to_exact_type = implicit_to_exact_type; // Avoid warning. + (void)implicit_to_exact_type; // Avoid warning. AssertingVH GenericAVH(BitcastV.get()); EXPECT_EQ(BitcastV.get(), GenericAVH); @@ -125,7 +125,7 @@ const CastInst *ConstBitcast = BitcastV.get(); AssertingVH AVH(ConstBitcast); const CastInst *implicit_to_exact_type = AVH; - implicit_to_exact_type = implicit_to_exact_type; // Avoid warning. + (void)implicit_to_exact_type; // Avoid warning. } TEST_F(ValueHandle, AssertingVH_Comparisons) { Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.cpp?rev=122458&r1=122457&r2=122458&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeEmitterGen.cpp (original) +++ llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Wed Dec 22 18:58:24 2010 @@ -264,7 +264,7 @@ o << " const unsigned opcode = MI.getOpcode();\n" << " unsigned Value = InstBits[opcode];\n" << " unsigned op = 0;\n" - << " op = op; // suppress warning\n" + << " (void)op; // suppress warning\n" << " switch (opcode) {\n"; // Emit each case statement From wangmp at apple.com Wed Dec 22 19:41:32 2010 From: wangmp at apple.com (Mon P Wang) Date: Thu, 23 Dec 2010 01:41:32 -0000 Subject: [llvm-commits] [llvm] r122462 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <20101223014132.D19712A6C12C@llvm.org> Author: wangmp Date: Wed Dec 22 19:41:32 2010 New Revision: 122462 URL: http://llvm.org/viewvc/llvm-project?rev=122462&view=rev Log: Preserve the address space when generating bitcasts for MemTransferInst in ConvertToScalarInfo Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=122462&r1=122461&r2=122462&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Dec 22 19:41:32 2010 @@ -498,8 +498,14 @@ // pointer (bitcasted), then a store to our new alloca. assert(MTI->getRawDest() == Ptr && "Neither use is of pointer?"); Value *SrcPtr = MTI->getSource(); - SrcPtr = Builder.CreateBitCast(SrcPtr, NewAI->getType()); - + const PointerType* SPTy = cast(SrcPtr->getType()); + const PointerType* AIPTy = cast(NewAI->getType()); + if (SPTy->getAddressSpace() != AIPTy->getAddressSpace()) { + AIPTy = PointerType::get(AIPTy->getElementType(), + SPTy->getAddressSpace()); + } + SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy); + LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval"); SrcVal->setAlignment(MTI->getAlignment()); Builder.CreateStore(SrcVal, NewAI); @@ -509,7 +515,14 @@ assert(MTI->getRawSource() == Ptr && "Neither use is of pointer?"); LoadInst *SrcVal = Builder.CreateLoad(NewAI, "srcval"); - Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), NewAI->getType()); + const PointerType* DPTy = cast(MTI->getDest()->getType()); + const PointerType* AIPTy = cast(NewAI->getType()); + if (DPTy->getAddressSpace() != AIPTy->getAddressSpace()) { + AIPTy = PointerType::get(AIPTy->getElementType(), + DPTy->getAddressSpace()); + } + Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy); + StoreInst *NewStore = Builder.CreateStore(SrcVal, DstPtr); NewStore->setAlignment(MTI->getAlignment()); } else { From atrick at apple.com Wed Dec 22 21:15:51 2010 From: atrick at apple.com (Andrew Trick) Date: Thu, 23 Dec 2010 03:15:51 -0000 Subject: [llvm-commits] [llvm] r122472 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp test/CodeGen/Generic/add-with-overflow-128.ll Message-ID: <20101223031551.363292A6C12C@llvm.org> Author: atrick Date: Wed Dec 22 21:15:51 2010 New Revision: 122472 URL: http://llvm.org/viewvc/llvm-project?rev=122472&view=rev Log: Fixes PR8823: add-with-overflow-128.ll In the bottom-up selection DAG scheduling, handle two-address instructions that read/write unspillable registers. Treat the entire chain of two-address nodes as a single live range. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122472&r1=122471&r2=122472&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 22 21:15:51 2010 @@ -247,6 +247,23 @@ } } +/// Call ReleasePred for each predecessor, then update register live def/gen. +/// Always update LiveRegDefs for a register dependence even if the current SU +/// also defines the register. This effectively create one large live range +/// across a sequence of two-address node. This is important because the +/// entire chain must be scheduled together. Example: +/// +/// flags = (3) add +/// flags = (2) addc flags +/// flags = (1) addc flags +/// +/// results in +/// +/// LiveRegDefs[flags] = 3 +/// LiveRegCycles[flags] = 1 +/// +/// If (2) addc is unscheduled, then (1) addc must also be unscheduled to avoid +/// interference on flags. void ScheduleDAGRRList::ReleasePredecessors(SUnit *SU, unsigned CurCycle) { // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); @@ -257,9 +274,12 @@ // expensive to copy the register. Make sure nothing that can // clobber the register is scheduled between the predecessor and // this node. - if (!LiveRegDefs[I->getReg()]) { + SUnit *&RegDef = LiveRegDefs[I->getReg()]; + assert((!RegDef || RegDef == SU || RegDef == I->getSUnit()) && + "interference on register dependence"); + RegDef = I->getSUnit(); + if (!LiveRegCycles[I->getReg()]) { ++NumLiveRegs; - LiveRegDefs[I->getReg()] = I->getSUnit(); LiveRegCycles[I->getReg()] = CurCycle; } } @@ -284,20 +304,19 @@ AvailableQueue->ScheduledNode(SU); + // Update liveness of predecessors before successors to avoid treating a + // two-address node as a live range def. ReleasePredecessors(SU, CurCycle); // Release all the implicit physical register defs that are live. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { - if (I->isAssignedRegDep()) { - if (LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) { - assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); - assert(LiveRegDefs[I->getReg()] == SU && - "Physical register dependency violated?"); - --NumLiveRegs; - LiveRegDefs[I->getReg()] = NULL; - LiveRegCycles[I->getReg()] = 0; - } + // LiveRegDegs[I->getReg()] != SU when SU is a two-address node. + if (I->isAssignedRegDep() && LiveRegDefs[I->getReg()] == SU) { + assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); + --NumLiveRegs; + LiveRegDefs[I->getReg()] = NULL; + LiveRegCycles[I->getReg()] = 0; } } @@ -341,8 +360,10 @@ for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { if (I->isAssignedRegDep()) { + // This becomes the nearest def. Note that an earlier def may still be + // pending if this is a two-address node. + LiveRegDefs[I->getReg()] = SU; if (!LiveRegDefs[I->getReg()]) { - LiveRegDefs[I->getReg()] = SU; ++NumLiveRegs; } if (I->getSUnit()->getHeight() < LiveRegCycles[I->getReg()]) Modified: llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll?rev=122472&r1=122471&r2=122472&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll (original) +++ llvm/trunk/test/CodeGen/Generic/add-with-overflow-128.ll Wed Dec 22 21:15:51 2010 @@ -1,6 +1,4 @@ -; RUN: true -; FIXME: TEmporarily disabled: PR8823 -; llc < %s +; RUN: llc < %s @ok = internal constant [4 x i8] c"%d\0A\00" @no = internal constant [4 x i8] c"no\0A\00" From atrick at apple.com Wed Dec 22 21:43:21 2010 From: atrick at apple.com (Andrew Trick) Date: Thu, 23 Dec 2010 03:43:21 -0000 Subject: [llvm-commits] [llvm] r122473 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101223034321.91EA82A6C12C@llvm.org> Author: atrick Date: Wed Dec 22 21:43:21 2010 New Revision: 122473 URL: http://llvm.org/viewvc/llvm-project?rev=122473&view=rev Log: In CheckForLiveRegDef use TRI->getOverlaps. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122473&r1=122472&r2=122473&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 22 21:43:21 2010 @@ -659,15 +659,18 @@ SmallSet &RegAdded, SmallVector &LRegs, const TargetRegisterInfo *TRI) { - if (LiveRegDefs[Reg] && LiveRegDefs[Reg] != SU) { + for (const unsigned *AliasI = TRI->getOverlaps(Reg); *AliasI; ++AliasI) { + + // Check if Ref is live. + if (!LiveRegDefs[Reg]) continue; + + // Allow multiple uses of the same def. + if (LiveRegDefs[Reg] == SU) continue; + + // Add Reg to the set of interfering live regs. if (RegAdded.insert(Reg)) LRegs.push_back(Reg); } - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) - if (LiveRegDefs[*Alias] && LiveRegDefs[*Alias] != SU) { - if (RegAdded.insert(*Alias)) - LRegs.push_back(*Alias); - } } /// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay From atrick at apple.com Wed Dec 22 22:16:14 2010 From: atrick at apple.com (Andrew Trick) Date: Thu, 23 Dec 2010 04:16:14 -0000 Subject: [llvm-commits] [llvm] r122474 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101223041614.C91F02A6C12C@llvm.org> Author: atrick Date: Wed Dec 22 22:16:14 2010 New Revision: 122474 URL: http://llvm.org/viewvc/llvm-project?rev=122474&view=rev Log: Converted LiveRegCycles to LiveRegGens. It's easier to work with and allows multiple nodes per cycle. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122474&r1=122473&r2=122474&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 22 22:16:14 2010 @@ -88,7 +88,7 @@ /// modifies the registers can be scheduled. unsigned NumLiveRegs; std::vector LiveRegDefs; - std::vector LiveRegCycles; + std::vector LiveRegGens; /// Topo - A topological ordering for SUnits which permits fast IsReachable /// and similar queries. @@ -137,7 +137,7 @@ private: void ReleasePred(SUnit *SU, const SDep *PredEdge); - void ReleasePredecessors(SUnit *SU, unsigned CurCycle); + void ReleasePredecessors(SUnit *SU); void ReleaseSucc(SUnit *SU, const SDep *SuccEdge); void ReleaseSuccessors(SUnit *SU); void CapturePred(SDep *PredEdge); @@ -194,7 +194,7 @@ NumLiveRegs = 0; LiveRegDefs.resize(TRI->getNumRegs(), NULL); - LiveRegCycles.resize(TRI->getNumRegs(), 0); + LiveRegGens.resize(TRI->getNumRegs(), NULL); // Build the scheduling graph. BuildSchedGraph(NULL); @@ -260,11 +260,11 @@ /// results in /// /// LiveRegDefs[flags] = 3 -/// LiveRegCycles[flags] = 1 +/// LiveRegGens[flags] = 1 /// /// If (2) addc is unscheduled, then (1) addc must also be unscheduled to avoid /// interference on flags. -void ScheduleDAGRRList::ReleasePredecessors(SUnit *SU, unsigned CurCycle) { +void ScheduleDAGRRList::ReleasePredecessors(SUnit *SU) { // Bottom up: release predecessors for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { @@ -274,13 +274,13 @@ // expensive to copy the register. Make sure nothing that can // clobber the register is scheduled between the predecessor and // this node. - SUnit *&RegDef = LiveRegDefs[I->getReg()]; + SUnit *RegDef = LiveRegDefs[I->getReg()]; (void)RegDef; assert((!RegDef || RegDef == SU || RegDef == I->getSUnit()) && "interference on register dependence"); - RegDef = I->getSUnit(); - if (!LiveRegCycles[I->getReg()]) { + LiveRegDefs[I->getReg()] = I->getSUnit(); + if (!LiveRegGens[I->getReg()]) { ++NumLiveRegs; - LiveRegCycles[I->getReg()] = CurCycle; + LiveRegGens[I->getReg()] = SU; } } } @@ -306,7 +306,7 @@ // Update liveness of predecessors before successors to avoid treating a // two-address node as a live range def. - ReleasePredecessors(SU, CurCycle); + ReleasePredecessors(SU); // Release all the implicit physical register defs that are live. for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); @@ -316,7 +316,7 @@ assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); --NumLiveRegs; LiveRegDefs[I->getReg()] = NULL; - LiveRegCycles[I->getReg()] = 0; + LiveRegGens[I->getReg()] = NULL; } } @@ -347,13 +347,13 @@ for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { CapturePred(&*I); - if (I->isAssignedRegDep() && SU->getHeight() == LiveRegCycles[I->getReg()]){ + if (I->isAssignedRegDep() && SU == LiveRegGens[I->getReg()]){ assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); assert(LiveRegDefs[I->getReg()] == I->getSUnit() && "Physical register dependency violated?"); --NumLiveRegs; LiveRegDefs[I->getReg()] = NULL; - LiveRegCycles[I->getReg()] = 0; + LiveRegGens[I->getReg()] = NULL; } } @@ -366,8 +366,9 @@ if (!LiveRegDefs[I->getReg()]) { ++NumLiveRegs; } - if (I->getSUnit()->getHeight() < LiveRegCycles[I->getReg()]) - LiveRegCycles[I->getReg()] = I->getSUnit()->getHeight(); + if (LiveRegGens[I->getReg()] == NULL || + I->getSUnit()->getHeight() < LiveRegGens[I->getReg()]->getHeight()) + LiveRegGens[I->getReg()] = I->getSUnit(); } } @@ -740,7 +741,7 @@ unsigned CurCycle = 0; // Release any predecessors of the special Exit node. - ReleasePredecessors(&ExitSU, CurCycle); + ReleasePredecessors(&ExitSU); // Add root to Available queue. if (!SUnits.empty()) { @@ -784,7 +785,7 @@ unsigned LiveCycle = CurCycle; for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { unsigned Reg = LRegs[j]; - unsigned LCycle = LiveRegCycles[Reg]; + unsigned LCycle = LiveRegGens[Reg]->getHeight(); LiveCycle = std::min(LiveCycle, LCycle); } SUnit *OldSU = Sequence[LiveCycle]; From atrick at apple.com Wed Dec 22 23:42:20 2010 From: atrick at apple.com (Andrew Trick) Date: Thu, 23 Dec 2010 05:42:20 -0000 Subject: [llvm-commits] [llvm] r122491 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20101223054220.8A7CD2A6C12C@llvm.org> Author: atrick Date: Wed Dec 22 23:42:20 2010 New Revision: 122491 URL: http://llvm.org/viewvc/llvm-project?rev=122491&view=rev Log: Reorganize ListScheduleBottomUp in preparation for modeling machine cycles and instruction issue. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=122491&r1=122490&r2=122491&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 22 23:42:20 2010 @@ -83,6 +83,9 @@ /// AvailableQueue - The priority queue to use for the available SUnits. SchedulingPriorityQueue *AvailableQueue; + /// CurCycle - The current scheduler state corresponds to this cycle. + unsigned CurCycle; + /// LiveRegDefs - A set of physical registers and their definition /// that are "live". These nodes must be scheduled before any other nodes that /// modifies the registers can be scheduled. @@ -99,7 +102,7 @@ bool isbottomup, bool needlatency, SchedulingPriorityQueue *availqueue) : ScheduleDAGSDNodes(mf), isBottomUp(isbottomup), NeedLatency(needlatency), - AvailableQueue(availqueue), Topo(SUnits) { + AvailableQueue(availqueue), CurCycle(0), Topo(SUnits) { } ~ScheduleDAGRRList() { @@ -141,19 +144,21 @@ void ReleaseSucc(SUnit *SU, const SDep *SuccEdge); void ReleaseSuccessors(SUnit *SU); void CapturePred(SDep *PredEdge); - void ScheduleNodeBottomUp(SUnit*, unsigned); - void ScheduleNodeTopDown(SUnit*, unsigned); + void ScheduleNodeBottomUp(SUnit*); void UnscheduleNodeBottomUp(SUnit*); - void BacktrackBottomUp(SUnit*, unsigned, unsigned&); + void BacktrackBottomUp(SUnit*, unsigned); SUnit *CopyAndMoveSuccessors(SUnit*); void InsertCopiesAndMoveSuccs(SUnit*, unsigned, const TargetRegisterClass*, const TargetRegisterClass*, SmallVector&); bool DelayForLiveRegsBottomUp(SUnit*, SmallVector&); - void ListScheduleTopDown(); + SUnit *PickNodeToScheduleBottomUp(); void ListScheduleBottomUp(); + void ScheduleNodeTopDown(SUnit*); + void ListScheduleTopDown(); + /// CreateNewSUnit - Creates a new SUnit and returns a pointer to it. /// Updates the topological ordering if required. @@ -192,6 +197,7 @@ << "********** List Scheduling BB#" << BB->getNumber() << " '" << BB->getName() << "' **********\n"); + CurCycle = 0; NumLiveRegs = 0; LiveRegDefs.resize(TRI->getNumRegs(), NULL); LiveRegGens.resize(TRI->getNumRegs(), NULL); @@ -289,7 +295,7 @@ /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending /// count of its predecessors. If a predecessor pending count is zero, add it to /// the Available queue. -void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { +void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU) { DEBUG(dbgs() << "\n*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(this)); @@ -381,8 +387,7 @@ /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in /// BTCycle in order to schedule a specific node. -void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle, - unsigned &CurCycle) { +void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle) { SUnit *OldSU = NULL; while (CurCycle > BtCycle) { OldSU = Sequence.back(); @@ -734,12 +739,143 @@ return !LRegs.empty(); } +/// Return a node that can be scheduled in this cycle. Requirements: +/// (1) Ready: latency has been satisfied +/// (2) No Hazards: resources are available (TBD) +/// (3) No Interferences: may unschedule to break register interferences. +SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() { + SmallVector Interferences; + DenseMap > LRegsMap; + + SUnit *CurSU = AvailableQueue->pop(); + while (CurSU) { + SmallVector LRegs; + if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) + break; + LRegsMap.insert(std::make_pair(CurSU, LRegs)); + + CurSU->isPending = true; // This SU is not in AvailableQueue right now. + Interferences.push_back(CurSU); + CurSU = AvailableQueue->pop(); + } + if (CurSU) { + // Add the nodes that aren't ready back onto the available list. + for (unsigned i = 0, e = Interferences.size(); i != e; ++i) { + Interferences[i]->isPending = false; + assert(Interferences[i]->isAvailable && "must still be available"); + AvailableQueue->push(Interferences[i]); + } + return CurSU; + } + + // All candidates are delayed due to live physical reg dependencies. + // Try backtracking, code duplication, or inserting cross class copies + // to resolve it. + for (unsigned i = 0, e = Interferences.size(); i != e; ++i) { + SUnit *TrySU = Interferences[i]; + SmallVector &LRegs = LRegsMap[TrySU]; + + // Try unscheduling up to the point where it's safe to schedule + // this node. + unsigned LiveCycle = CurCycle; + for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { + unsigned Reg = LRegs[j]; + unsigned LCycle = LiveRegGens[Reg]->getHeight(); + LiveCycle = std::min(LiveCycle, LCycle); + } + SUnit *OldSU = Sequence[LiveCycle]; + if (!WillCreateCycle(TrySU, OldSU)) { + BacktrackBottomUp(TrySU, LiveCycle); + + // Force the current node to be scheduled before the node that + // requires the physical reg dep. + if (OldSU->isAvailable) { + OldSU->isAvailable = false; + if (!OldSU->isPending) + AvailableQueue->remove(OldSU); + } + AddPred(TrySU, SDep(OldSU, SDep::Order, /*Latency=*/1, + /*Reg=*/0, /*isNormalMemory=*/false, + /*isMustAlias=*/false, /*isArtificial=*/true)); + + // If one or more successors has been unscheduled, then the current + // node is no longer avaialable. Schedule a successor that's now + // available instead. + if (!TrySU->isAvailable) { + CurSU = AvailableQueue->pop(); + } + else { + CurSU = TrySU; + TrySU->isPending = false; + Interferences.erase(Interferences.begin()+i); + } + break; + } + } + + if (!CurSU) { + // Can't backtrack. If it's too expensive to copy the value, then try + // duplicate the nodes that produces these "too expensive to copy" + // values to break the dependency. In case even that doesn't work, + // insert cross class copies. + // If it's not too expensive, i.e. cost != -1, issue copies. + SUnit *TrySU = Interferences[0]; + SmallVector &LRegs = LRegsMap[TrySU]; + assert(LRegs.size() == 1 && "Can't handle this yet!"); + unsigned Reg = LRegs[0]; + SUnit *LRDef = LiveRegDefs[Reg]; + EVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); + const TargetRegisterClass *RC = + TRI->getMinimalPhysRegClass(Reg, VT); + const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); + + // If cross copy register class is null, then it must be possible copy + // the value directly. Do not try duplicate the def. + SUnit *NewDef = 0; + if (DestRC) + NewDef = CopyAndMoveSuccessors(LRDef); + else + DestRC = RC; + if (!NewDef) { + // Issue copies, these can be expensive cross register class copies. + SmallVector Copies; + InsertCopiesAndMoveSuccs(LRDef, Reg, DestRC, RC, Copies); + DEBUG(dbgs() << " Adding an edge from SU #" << TrySU->NodeNum + << " to SU #" << Copies.front()->NodeNum << "\n"); + AddPred(TrySU, SDep(Copies.front(), SDep::Order, /*Latency=*/1, + /*Reg=*/0, /*isNormalMemory=*/false, + /*isMustAlias=*/false, + /*isArtificial=*/true)); + NewDef = Copies.back(); + } + + DEBUG(dbgs() << " Adding an edge from SU #" << NewDef->NodeNum + << " to SU #" << TrySU->NodeNum << "\n"); + LiveRegDefs[Reg] = NewDef; + AddPred(NewDef, SDep(TrySU, SDep::Order, /*Latency=*/1, + /*Reg=*/0, /*isNormalMemory=*/false, + /*isMustAlias=*/false, + /*isArtificial=*/true)); + TrySU->isAvailable = false; + CurSU = NewDef; + } + + assert(CurSU && "Unable to resolve live physical register dependencies!"); + + // Add the nodes that aren't ready back onto the available list. + for (unsigned i = 0, e = Interferences.size(); i != e; ++i) { + Interferences[i]->isPending = false; + // May no longer be available due to backtracking. + if (Interferences[i]->isAvailable) { + AvailableQueue->push(Interferences[i]); + } + } + return CurSU; +} /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up /// schedulers. void ScheduleDAGRRList::ListScheduleBottomUp() { - unsigned CurCycle = 0; - // Release any predecessors of the special Exit node. ReleasePredecessors(&ExitSU); @@ -753,128 +889,15 @@ // While Available queue is not empty, grab the node with the highest // priority. If it is not ready put it back. Schedule the node. - SmallVector NotReady; - DenseMap > LRegsMap; Sequence.reserve(SUnits.size()); while (!AvailableQueue->empty()) { - bool Delayed = false; - LRegsMap.clear(); - SUnit *CurSU = AvailableQueue->pop(); - while (CurSU) { - SmallVector LRegs; - if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) - break; - Delayed = true; - LRegsMap.insert(std::make_pair(CurSU, LRegs)); + // Pick the best node to schedule taking all constraints into + // consideration. + SUnit *SU = PickNodeToScheduleBottomUp(); - CurSU->isPending = true; // This SU is not in AvailableQueue right now. - NotReady.push_back(CurSU); - CurSU = AvailableQueue->pop(); - } - - // All candidates are delayed due to live physical reg dependencies. - // Try backtracking, code duplication, or inserting cross class copies - // to resolve it. - if (Delayed && !CurSU) { - for (unsigned i = 0, e = NotReady.size(); i != e; ++i) { - SUnit *TrySU = NotReady[i]; - SmallVector &LRegs = LRegsMap[TrySU]; - - // Try unscheduling up to the point where it's safe to schedule - // this node. - unsigned LiveCycle = CurCycle; - for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { - unsigned Reg = LRegs[j]; - unsigned LCycle = LiveRegGens[Reg]->getHeight(); - LiveCycle = std::min(LiveCycle, LCycle); - } - SUnit *OldSU = Sequence[LiveCycle]; - if (!WillCreateCycle(TrySU, OldSU)) { - BacktrackBottomUp(TrySU, LiveCycle, CurCycle); - // Force the current node to be scheduled before the node that - // requires the physical reg dep. - if (OldSU->isAvailable) { - OldSU->isAvailable = false; - AvailableQueue->remove(OldSU); - } - AddPred(TrySU, SDep(OldSU, SDep::Order, /*Latency=*/1, - /*Reg=*/0, /*isNormalMemory=*/false, - /*isMustAlias=*/false, /*isArtificial=*/true)); - // If one or more successors has been unscheduled, then the current - // node is no longer avaialable. Schedule a successor that's now - // available instead. - if (!TrySU->isAvailable) - CurSU = AvailableQueue->pop(); - else { - CurSU = TrySU; - TrySU->isPending = false; - NotReady.erase(NotReady.begin()+i); - } - break; - } - } + if (SU) + ScheduleNodeBottomUp(SU); - if (!CurSU) { - // Can't backtrack. If it's too expensive to copy the value, then try - // duplicate the nodes that produces these "too expensive to copy" - // values to break the dependency. In case even that doesn't work, - // insert cross class copies. - // If it's not too expensive, i.e. cost != -1, issue copies. - SUnit *TrySU = NotReady[0]; - SmallVector &LRegs = LRegsMap[TrySU]; - assert(LRegs.size() == 1 && "Can't handle this yet!"); - unsigned Reg = LRegs[0]; - SUnit *LRDef = LiveRegDefs[Reg]; - EVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); - const TargetRegisterClass *RC = - TRI->getMinimalPhysRegClass(Reg, VT); - const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); - - // If cross copy register class is null, then it must be possible copy - // the value directly. Do not try duplicate the def. - SUnit *NewDef = 0; - if (DestRC) - NewDef = CopyAndMoveSuccessors(LRDef); - else - DestRC = RC; - if (!NewDef) { - // Issue copies, these can be expensive cross register class copies. - SmallVector Copies; - InsertCopiesAndMoveSuccs(LRDef, Reg, DestRC, RC, Copies); - DEBUG(dbgs() << " Adding an edge from SU #" << TrySU->NodeNum - << " to SU #" << Copies.front()->NodeNum << "\n"); - AddPred(TrySU, SDep(Copies.front(), SDep::Order, /*Latency=*/1, - /*Reg=*/0, /*isNormalMemory=*/false, - /*isMustAlias=*/false, - /*isArtificial=*/true)); - NewDef = Copies.back(); - } - - DEBUG(dbgs() << " Adding an edge from SU #" << NewDef->NodeNum - << " to SU #" << TrySU->NodeNum << "\n"); - LiveRegDefs[Reg] = NewDef; - AddPred(NewDef, SDep(TrySU, SDep::Order, /*Latency=*/1, - /*Reg=*/0, /*isNormalMemory=*/false, - /*isMustAlias=*/false, - /*isArtificial=*/true)); - TrySU->isAvailable = false; - CurSU = NewDef; - } - - assert(CurSU && "Unable to resolve live physical register dependencies!"); - } - - // Add the nodes that aren't ready back onto the available list. - for (unsigned i = 0, e = NotReady.size(); i != e; ++i) { - NotReady[i]->isPending = false; - // May no longer be available due to backtracking. - if (NotReady[i]->isAvailable) - AvailableQueue->push(NotReady[i]); - } - NotReady.clear(); - - if (CurSU) - ScheduleNodeBottomUp(CurSU, CurCycle); ++CurCycle; AvailableQueue->setCurCycle(CurCycle); } @@ -928,7 +951,7 @@ /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending /// count of its successors. If a successor pending count is zero, add it to /// the Available queue. -void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { +void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU) { DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: "); DEBUG(SU->dump(this)); @@ -966,7 +989,7 @@ SUnit *CurSU = AvailableQueue->pop(); if (CurSU) - ScheduleNodeTopDown(CurSU, CurCycle); + ScheduleNodeTopDown(CurSU); ++CurCycle; AvailableQueue->setCurCycle(CurCycle); } From benny.kra at googlemail.com Thu Dec 23 09:07:02 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 23 Dec 2010 15:07:02 -0000 Subject: [llvm-commits] [llvm] r122495 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <20101223150702.E50FB2A6C12C@llvm.org> Author: d0k Date: Thu Dec 23 09:07:02 2010 New Revision: 122495 URL: http://llvm.org/viewvc/llvm-project?rev=122495&view=rev Log: Remove some obsolete README items, add a new one off the top of my head. 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=122495&r1=122494&r2=122495&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Thu Dec 23 09:07:02 2010 @@ -67,19 +67,6 @@ //===---------------------------------------------------------------------===// -Compile this: -_Bool f(_Bool a) { return a!=1; } - -into: - movzbl %dil, %eax - xorl $1, %eax - ret - -(Although note that this isn't a legal way to express the code that llvm-gcc -currently generates for that function.) - -//===---------------------------------------------------------------------===// - Some isel ideas: 1. Dynamic programming based approach when compile time if not an @@ -394,72 +381,8 @@ //===---------------------------------------------------------------------===// -Codegen: - -int f(int a, int b) { - if (a == 4 || a == 6) - b++; - return b; -} - - -as: - -or eax, 2 -cmp eax, 6 -jz label - -//===---------------------------------------------------------------------===// - GCC's ix86_expand_int_movcc function (in i386.c) has a ton of interesting -simplifications for integer "x cmp y ? a : b". For example, instead of: - -int G; -void f(int X, int Y) { - G = X < 0 ? 14 : 13; -} - -compiling to: - -_f: - movl $14, %eax - movl $13, %ecx - movl 4(%esp), %edx - testl %edx, %edx - cmovl %eax, %ecx - movl %ecx, _G - ret - -it could be: -_f: - movl 4(%esp), %eax - sarl $31, %eax - notl %eax - addl $14, %eax - movl %eax, _G - ret - -etc. - -Another is: -int usesbb(unsigned int a, unsigned int b) { - return (a < b ? -1 : 0); -} -to: -_usesbb: - movl 8(%esp), %eax - cmpl %eax, 4(%esp) - sbbl %eax, %eax - ret - -instead of: -_usesbb: - xorl %eax, %eax - movl 8(%esp), %ecx - cmpl %ecx, 4(%esp) - movl $4294967295, %ecx - cmovb %ecx, %eax - ret +simplifications for integer "x cmp y ? a : b". //===---------------------------------------------------------------------===// @@ -1868,3 +1791,28 @@ the load and the store which would prohibit narrowing. //===---------------------------------------------------------------------===// + +This code: +void foo(unsigned x) { + if (x == 0) bar(); + else if (x == 1) qux(); +} + +currently compiles into: +_foo: + movl 4(%esp), %eax + cmpl $1, %eax + je LBB0_3 + testl %eax, %eax + jne LBB0_4 + +the testl could be removed: +_foo: + movl 4(%esp), %eax + cmpl $1, %eax + je LBB0_3 + jb LBB0_4 + +0 is the only unsigned number < 1. + +//===---------------------------------------------------------------------===// From benny.kra at googlemail.com Thu Dec 23 09:32:07 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 23 Dec 2010 15:32:07 -0000 Subject: [llvm-commits] [llvm] r122496 - /llvm/trunk/lib/Target/README.txt Message-ID: <20101223153207.325E32A6C12C@llvm.org> Author: d0k Date: Thu Dec 23 09:32:07 2010 New Revision: 122496 URL: http://llvm.org/viewvc/llvm-project?rev=122496&view=rev Log: Remove/fix invalid README entries. The well thought out strcpy function doesn't return a pointer to the end of the string. 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=122496&r1=122495&r2=122496&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Thu Dec 23 09:32:07 2010 @@ -697,7 +697,7 @@ Consider: int test() { - long long input[8] = {1,1,1,1,1,1,1,1}; + long long input[8] = {1,0,1,0,1,0,1,0}; foo(input); } @@ -1432,14 +1432,7 @@ This is interesting for a couple reasons. First, in this: - %3073 = call i8* @strcpy(i8* %3072, i8* %3071) nounwind - %strlen = call i32 @strlen(i8* %3072) - -The strlen could be replaced with: %strlen = sub %3072, %3073, because the -strcpy call returns a pointer to the end of the string. Based on that, the -endptr GEP just becomes equal to 3073, which eliminates a strlen call and GEP. - -Second, the memcpy+strlen strlen can be replaced with: +The memcpy+strlen strlen can be replaced with: %3074 = call i32 @strlen([5 x i8]* @"\01LC42") nounwind readonly @@ -1515,18 +1508,6 @@ //===---------------------------------------------------------------------===// -186.crafty also contains this code: - -%1906 = call i32 @strlen(i8* getelementptr ([32 x i8]* @pgn_event, i32 0,i32 0)) -%1907 = getelementptr [32 x i8]* @pgn_event, i32 0, i32 %1906 -%1908 = call i8* @strcpy(i8* %1907, i8* %1905) nounwind align 1 -%1909 = call i32 @strlen(i8* getelementptr ([32 x i8]* @pgn_event, i32 0,i32 0)) -%1910 = getelementptr [32 x i8]* @pgn_event, i32 0, i32 %1909 - -The last strlen is computable as 1908- at pgn_event, which means 1910=1908. - -//===---------------------------------------------------------------------===// - 186.crafty has this interesting pattern with the "out.4543" variable: call void @llvm.memcpy.i32( From edwintorok at gmail.com Thu Dec 23 09:49:26 2010 From: edwintorok at gmail.com (Torok Edwin) Date: Thu, 23 Dec 2010 15:49:26 -0000 Subject: [llvm-commits] [llvm] r122497 - in /llvm/trunk: bindings/ocaml/bitreader/llvm_bitreader.mli bindings/ocaml/executionengine/llvm_executionengine.mli bindings/ocaml/llvm/llvm.mli test/Bindings/Ocaml/ext_exc.ml Message-ID: <20101223154927.180F42A6C12C@llvm.org> Author: edwin Date: Thu Dec 23 09:49:26 2010 New Revision: 122497 URL: http://llvm.org/viewvc/llvm-project?rev=122497&view=rev Log: Fix OCaml bindings crash, PR8847. See http://caml.inria.fr/mantis/view.php?id=4166 If we call only external functions from a module, then its 'let _' bindings don't get executed, which means that the exceptions don't get registered for use in the C code. This in turn causes llvm_raise to call raise_with_arg() with a NULL pointer and cause a segmentation fault. The workaround is to declare all 'external' functions as 'val' in these .mli files. Also added a separate testcase (the testcase must call only external functions for the bug to occur). Added: llvm/trunk/test/Bindings/Ocaml/ext_exc.ml Modified: llvm/trunk/bindings/ocaml/bitreader/llvm_bitreader.mli llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli llvm/trunk/bindings/ocaml/llvm/llvm.mli Modified: llvm/trunk/bindings/ocaml/bitreader/llvm_bitreader.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/bitreader/llvm_bitreader.mli?rev=122497&r1=122496&r2=122497&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/bitreader/llvm_bitreader.mli (original) +++ llvm/trunk/bindings/ocaml/bitreader/llvm_bitreader.mli Thu Dec 23 09:49:26 2010 @@ -18,12 +18,12 @@ memory buffer [mb] in the context [context]. Returns [m] if successful, or raises [Error msg] otherwise, where [msg] is a description of the error encountered. See the function [llvm::getBitcodeModule]. *) -external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule - = "llvm_get_module" +val get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule + (** [parse_bitcode context mb] parses the bitcode for a new module [m] from the memory buffer [mb] in the context [context]. Returns [m] if successful, or raises [Error msg] otherwise, where [msg] is a description of the error encountered. See the function [llvm::ParseBitcodeFile]. *) -external parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule - = "llvm_parse_bitcode" +val parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule + Modified: llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli?rev=122497&r1=122496&r2=122497&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli (original) +++ llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli Thu Dec 23 09:49:26 2010 @@ -25,58 +25,58 @@ (** [of_float fpty n] boxes the float [n] in a float-valued generic value according to the floating point type [fpty]. See the fields [llvm::GenericValue::DoubleVal] and [llvm::GenericValue::FloatVal]. *) - external of_float : Llvm.lltype -> float -> t = "llvm_genericvalue_of_float" + val of_float : Llvm.lltype -> float -> t (** [of_pointer v] boxes the pointer value [v] in a generic value. See the field [llvm::GenericValue::PointerVal]. *) - external of_pointer : 'a -> t = "llvm_genericvalue_of_pointer" + val of_pointer : 'a -> t (** [of_int32 n w] boxes the int32 [i] in a generic value with the bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *) - external of_int32 : Llvm.lltype -> int32 -> t = "llvm_genericvalue_of_int32" + val of_int32 : Llvm.lltype -> int32 -> t (** [of_int n w] boxes the int [i] in a generic value with the bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *) - external of_int : Llvm.lltype -> int -> t = "llvm_genericvalue_of_int" + val of_int : Llvm.lltype -> int -> t (** [of_natint n w] boxes the native int [i] in a generic value with the bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *) - external of_nativeint : Llvm.lltype -> nativeint -> t - = "llvm_genericvalue_of_nativeint" + val of_nativeint : Llvm.lltype -> nativeint -> t + (** [of_int64 n w] boxes the int64 [i] in a generic value with the bitwidth [w]. See the field [llvm::GenericValue::IntVal]. *) - external of_int64 : Llvm.lltype -> int64 -> t = "llvm_genericvalue_of_int64" + val of_int64 : Llvm.lltype -> int64 -> t (** [as_float fpty gv] unboxes the floating point-valued generic value [gv] of floating point type [fpty]. See the fields [llvm::GenericValue::DoubleVal] and [llvm::GenericValue::FloatVal]. *) - external as_float : Llvm.lltype -> t -> float = "llvm_genericvalue_as_float" + val as_float : Llvm.lltype -> t -> float (** [as_pointer gv] unboxes the pointer-valued generic value [gv]. See the field [llvm::GenericValue::PointerVal]. *) - external as_pointer : t -> 'a = "llvm_genericvalue_as_pointer" + val as_pointer : t -> 'a (** [as_int32 gv] unboxes the integer-valued generic value [gv] as an [int32]. Is invalid if [gv] has a bitwidth greater than 32 bits. See the field [llvm::GenericValue::IntVal]. *) - external as_int32 : t -> int32 = "llvm_genericvalue_as_int32" + val as_int32 : t -> int32 (** [as_int gv] unboxes the integer-valued generic value [gv] as an [int]. Is invalid if [gv] has a bitwidth greater than the host bit width (but the most significant bit may be lost). See the field [llvm::GenericValue::IntVal]. *) - external as_int : t -> int = "llvm_genericvalue_as_int" + val as_int : t -> int (** [as_natint gv] unboxes the integer-valued generic value [gv] as a [nativeint]. Is invalid if [gv] has a bitwidth greater than [nativeint]. See the field [llvm::GenericValue::IntVal]. *) - external as_nativeint : t -> nativeint = "llvm_genericvalue_as_nativeint" + val as_nativeint : t -> nativeint (** [as_int64 gv] returns the integer-valued generic value [gv] as an [int64]. Is invalid if [gv] has a bitwidth greater than [int64]. See the field [llvm::GenericValue::IntVal]. *) - external as_int64 : t -> int64 = "llvm_genericvalue_as_int64" + val as_int64 : t -> int64 end @@ -91,73 +91,73 @@ interpreter. Raises [Error msg] if an error occurrs. The execution engine is not garbage collected and must be destroyed with [dispose ee]. See the function [llvm::EngineBuilder::create]. *) - external create : Llvm.llmodule -> t = "llvm_ee_create" + val create : Llvm.llmodule -> t (** [create_interpreter m] creates a new interpreter, taking ownership of the module [m] if successful. Raises [Error msg] if an error occurrs. The execution engine is not garbage collected and must be destroyed with [dispose ee]. See the function [llvm::EngineBuilder::create]. *) - external create_interpreter : Llvm.llmodule -> t = "llvm_ee_create_interpreter" + val create_interpreter : Llvm.llmodule -> t (** [create_jit m optlevel] creates a new JIT (just-in-time compiler), taking ownership of the module [m] if successful with the desired optimization level [optlevel]. Raises [Error msg] if an error occurrs. The execution engine is not garbage collected and must be destroyed with [dispose ee]. See the function [llvm::EngineBuilder::create]. *) - external create_jit : Llvm.llmodule -> int -> t = "llvm_ee_create_jit" + val create_jit : Llvm.llmodule -> int -> t (** [dispose ee] releases the memory used by the execution engine and must be invoked to avoid memory leaks. *) - external dispose : t -> unit = "llvm_ee_dispose" + val dispose : t -> unit (** [add_module m ee] adds the module [m] to the execution engine [ee]. *) - external add_module : Llvm.llmodule -> t -> unit = "llvm_ee_add_module" + val add_module : Llvm.llmodule -> t -> unit (** [remove_module m ee] removes the module [m] from the execution engine [ee], disposing of [m] and the module referenced by [mp]. Raises [Error msg] if an error occurs. *) - external remove_module : Llvm.llmodule -> t -> Llvm.llmodule - = "llvm_ee_remove_module" + val remove_module : Llvm.llmodule -> t -> Llvm.llmodule + (** [find_function n ee] finds the function named [n] defined in any of the modules owned by the execution engine [ee]. Returns [None] if the function is not found and [Some f] otherwise. *) - external find_function : string -> t -> Llvm.llvalue option - = "llvm_ee_find_function" + val find_function : string -> t -> Llvm.llvalue option + (** [run_function f args ee] synchronously executes the function [f] with the arguments [args], which must be compatible with the parameter types. *) - external run_function : Llvm.llvalue -> GenericValue.t array -> t -> + val run_function : Llvm.llvalue -> GenericValue.t array -> t -> GenericValue.t - = "llvm_ee_run_function" + (** [run_static_ctors ee] executes the static constructors of each module in the execution engine [ee]. *) - external run_static_ctors : t -> unit = "llvm_ee_run_static_ctors" + val run_static_ctors : t -> unit (** [run_static_dtors ee] executes the static destructors of each module in the execution engine [ee]. *) - external run_static_dtors : t -> unit = "llvm_ee_run_static_dtors" + val run_static_dtors : t -> unit (** [run_function_as_main f args env ee] executes the function [f] as a main function, passing it [argv] and [argc] according to the string array [args], and [envp] as specified by the array [env]. Returns the integer return value of the function. *) - external run_function_as_main : Llvm.llvalue -> string array -> + val run_function_as_main : Llvm.llvalue -> string array -> (string * string) array -> t -> int - = "llvm_ee_run_function_as_main" + (** [free_machine_code f ee] releases the memory in the execution engine [ee] used to store the machine code for the function [f]. *) - external free_machine_code : Llvm.llvalue -> t -> unit - = "llvm_ee_free_machine_code" + val free_machine_code : Llvm.llvalue -> t -> unit + (** [target_data ee] is the target data owned by the execution engine [ee]. *) - external target_data : t -> Llvm_target.TargetData.t - = "LLVMGetExecutionEngineTargetData" + val target_data : t -> Llvm_target.TargetData.t + end -external initialize_native_target : unit -> bool - = "llvm_initialize_native_target" +val initialize_native_target : unit -> bool + Modified: llvm/trunk/bindings/ocaml/llvm/llvm.mli URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm.mli?rev=122497&r1=122496&r2=122497&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm.mli (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm.mli Thu Dec 23 09:49:26 2010 @@ -212,19 +212,19 @@ (** [create_context ()] creates a context for storing the "global" state in LLVM. See the constructor [llvm::LLVMContext]. *) -external create_context : unit -> llcontext = "llvm_create_context" +val create_context : unit -> llcontext (** [destroy_context ()] destroys a context. See the destructor [llvm::LLVMContext::~LLVMContext]. *) -external dispose_context : llcontext -> unit = "llvm_dispose_context" +val dispose_context : llcontext -> unit (** See the function [llvm::getGlobalContext]. *) -external global_context : unit -> llcontext = "llvm_global_context" +val global_context : unit -> llcontext (** [mdkind_id context name] returns the MDKind ID that corresponds to the name [name] in the context [context]. See the function [llvm::LLVMContext::getMDKindID]. *) -external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id" +val mdkind_id : llcontext -> string -> int (** {6 Modules} *) @@ -233,71 +233,71 @@ the context [context]. Modules are not garbage collected; it is mandatory to call {!dispose_module} to free memory. See the constructor [llvm::Module::Module]. *) -external create_module : llcontext -> string -> llmodule = "llvm_create_module" +val create_module : llcontext -> string -> llmodule (** [dispose_module m] destroys a module [m] and all of the IR objects it contained. All references to subordinate objects are invalidated; referencing them will invoke undefined behavior. See the destructor [llvm::Module::~Module]. *) -external dispose_module : llmodule -> unit = "llvm_dispose_module" +val dispose_module : llmodule -> unit (** [target_triple m] is the target specifier for the module [m], something like [i686-apple-darwin8]. See the method [llvm::Module::getTargetTriple]. *) -external target_triple: llmodule -> string - = "llvm_target_triple" +val target_triple: llmodule -> string + (** [target_triple triple m] changes the target specifier for the module [m] to the string [triple]. See the method [llvm::Module::setTargetTriple]. *) -external set_target_triple: string -> llmodule -> unit - = "llvm_set_target_triple" +val set_target_triple: string -> llmodule -> unit + (** [data_layout m] is the data layout specifier for the module [m], something like [e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-...-a0:0:64-f80:128:128]. See the method [llvm::Module::getDataLayout]. *) -external data_layout: llmodule -> string - = "llvm_data_layout" +val data_layout: llmodule -> string + (** [set_data_layout s m] changes the data layout specifier for the module [m] to the string [s]. See the method [llvm::Module::setDataLayout]. *) -external set_data_layout: string -> llmodule -> unit - = "llvm_set_data_layout" +val set_data_layout: string -> llmodule -> unit + (** [define_type_name name ty m] adds a named type to the module's symbol table. Returns [true] if successful. If such a name already exists, then no entry is added and [false] is returned. See the [llvm::Module::addTypeName] method. *) -external define_type_name : string -> lltype -> llmodule -> bool - = "llvm_add_type_name" +val define_type_name : string -> lltype -> llmodule -> bool + (** [delete_type_name name] removes a type name from the module's symbol table. *) -external delete_type_name : string -> llmodule -> unit - = "llvm_delete_type_name" +val delete_type_name : string -> llmodule -> unit + (** [type_by_name m n] returns the type in the module [m] named [n], or [None] if it does not exist. See the method [llvm::Module::getTypeByName]. *) -external type_by_name : llmodule -> string -> lltype option - = "llvm_type_by_name" +val type_by_name : llmodule -> string -> lltype option + (** [dump_module m] prints the .ll representation of the module [m] to standard error. See the method [llvm::Module::dump]. *) -external dump_module : llmodule -> unit = "llvm_dump_module" +val dump_module : llmodule -> unit (** [set_module_inline_asm m asm] sets the inline assembler for the module. See the method [llvm::Module::setModuleInlineAsm]. *) -external set_module_inline_asm : llmodule -> string -> unit - = "llvm_set_module_inline_asm" +val set_module_inline_asm : llmodule -> string -> unit + (** {6 Types} *) (** [classify_type ty] returns the {!TypeKind.t} corresponding to the type [ty]. See the method [llvm::Type::getTypeID]. *) -external classify_type : lltype -> TypeKind.t = "llvm_classify_type" +val classify_type : lltype -> TypeKind.t (** [type_context ty] returns the {!llcontext} corresponding to the type [ty]. See the method [llvm::Type::getContext]. *) -external type_context : lltype -> llcontext = "llvm_type_context" +val type_context : lltype -> llcontext (** [string_of_lltype ty] returns a string describing the type [ty]. *) val string_of_lltype : lltype -> string @@ -306,54 +306,54 @@ (** [i1_type c] returns an integer type of bitwidth 1 in the context [c]. See [llvm::Type::Int1Ty]. *) -external i1_type : llcontext -> lltype = "llvm_i1_type" +val i1_type : llcontext -> lltype (** [i8_type c] returns an integer type of bitwidth 8 in the context [c]. See [llvm::Type::Int8Ty]. *) -external i8_type : llcontext -> lltype = "llvm_i8_type" +val i8_type : llcontext -> lltype (** [i16_type c] returns an integer type of bitwidth 16 in the context [c]. See [llvm::Type::Int16Ty]. *) -external i16_type : llcontext -> lltype = "llvm_i16_type" +val i16_type : llcontext -> lltype (** [i32_type c] returns an integer type of bitwidth 32 in the context [c]. See [llvm::Type::Int32Ty]. *) -external i32_type : llcontext -> lltype = "llvm_i32_type" +val i32_type : llcontext -> lltype (** [i64_type c] returns an integer type of bitwidth 64 in the context [c]. See [llvm::Type::Int64Ty]. *) -external i64_type : llcontext -> lltype = "llvm_i64_type" +val i64_type : llcontext -> lltype (** [integer_type c n] returns an integer type of bitwidth [n] in the context [c]. See the method [llvm::IntegerType::get]. *) -external integer_type : llcontext -> int -> lltype = "llvm_integer_type" +val integer_type : llcontext -> int -> lltype (** [integer_bitwidth c ty] returns the number of bits in the integer type [ty] in the context [c]. See the method [llvm::IntegerType::getBitWidth]. *) -external integer_bitwidth : lltype -> int = "llvm_integer_bitwidth" +val integer_bitwidth : lltype -> int (** {7 Operations on real types} *) (** [float_type c] returns the IEEE 32-bit floating point type in the context [c]. See [llvm::Type::FloatTy]. *) -external float_type : llcontext -> lltype = "llvm_float_type" +val float_type : llcontext -> lltype (** [double_type c] returns the IEEE 64-bit floating point type in the context [c]. See [llvm::Type::DoubleTy]. *) -external double_type : llcontext -> lltype = "llvm_double_type" +val double_type : llcontext -> lltype (** [x86fp80_type c] returns the x87 80-bit floating point type in the context [c]. See [llvm::Type::X86_FP80Ty]. *) -external x86fp80_type : llcontext -> lltype = "llvm_x86fp80_type" +val x86fp80_type : llcontext -> lltype (** [fp128_type c] returns the IEEE 128-bit floating point type in the context [c]. See [llvm::Type::FP128Ty]. *) -external fp128_type : llcontext -> lltype = "llvm_fp128_type" +val fp128_type : llcontext -> lltype (** [ppc_fp128_type c] returns the PowerPC 128-bit floating point type in the context [c]. See [llvm::Type::PPC_FP128Ty]. *) -external ppc_fp128_type : llcontext -> lltype = "llvm_ppc_fp128_type" +val ppc_fp128_type : llcontext -> lltype (** {7 Operations on function types} *) @@ -361,26 +361,26 @@ (** [function_type ret_ty param_tys] returns the function type returning [ret_ty] and taking [param_tys] as parameters. See the method [llvm::FunctionType::get]. *) -external function_type : lltype -> lltype array -> lltype = "llvm_function_type" +val function_type : lltype -> lltype array -> lltype (** [va_arg_function_type ret_ty param_tys] is just like [function_type ret_ty param_tys] except that it returns the function type which also takes a variable number of arguments. See the method [llvm::FunctionType::get]. *) -external var_arg_function_type : lltype -> lltype array -> lltype - = "llvm_var_arg_function_type" +val var_arg_function_type : lltype -> lltype array -> lltype + (** [is_var_arg fty] returns [true] if [fty] is a varargs function type, [false] otherwise. See the method [llvm::FunctionType::isVarArg]. *) -external is_var_arg : lltype -> bool = "llvm_is_var_arg" +val is_var_arg : lltype -> bool (** [return_type fty] gets the return type of the function type [fty]. See the method [llvm::FunctionType::getReturnType]. *) -external return_type : lltype -> lltype = "LLVMGetReturnType" +val return_type : lltype -> lltype (** [param_types fty] gets the parameter types of the function type [fty]. See the method [llvm::FunctionType::getParamType]. *) -external param_types : lltype -> lltype array = "llvm_param_types" +val param_types : lltype -> lltype array (** {7 Operations on struct types} *) @@ -388,61 +388,61 @@ (** [struct_type context tys] returns the structure type in the context [context] containing in the types in the array [tys]. See the method [llvm::StructType::get]. *) -external struct_type : llcontext -> lltype array -> lltype - = "llvm_struct_type" +val struct_type : llcontext -> lltype array -> lltype + (** [packed_struct_type context ys] returns the packed structure type in the context [context] containing in the types in the array [tys]. See the method [llvm::StructType::get]. *) -external packed_struct_type : llcontext -> lltype array -> lltype - = "llvm_packed_struct_type" +val packed_struct_type : llcontext -> lltype array -> lltype + (** [struct_element_types sty] returns the constituent types of the struct type [sty]. See the method [llvm::StructType::getElementType]. *) -external struct_element_types : lltype -> lltype array - = "llvm_struct_element_types" +val struct_element_types : lltype -> lltype array + (** [is_packed sty] returns [true] if the structure type [sty] is packed, [false] otherwise. See the method [llvm::StructType::isPacked]. *) -external is_packed : lltype -> bool = "llvm_is_packed" +val is_packed : lltype -> bool (** {7 Operations on pointer, vector, and array types} *) (** [array_type ty n] returns the array type containing [n] elements of type [ty]. See the method [llvm::ArrayType::get]. *) -external array_type : lltype -> int -> lltype = "llvm_array_type" +val array_type : lltype -> int -> lltype (** [pointer_type ty] returns the pointer type referencing objects of type [ty] in the default address space (0). See the method [llvm::PointerType::getUnqual]. *) -external pointer_type : lltype -> lltype = "llvm_pointer_type" +val pointer_type : lltype -> lltype (** [qualified_pointer_type ty as] returns the pointer type referencing objects of type [ty] in address space [as]. See the method [llvm::PointerType::get]. *) -external qualified_pointer_type : lltype -> int -> lltype - = "llvm_qualified_pointer_type" +val qualified_pointer_type : lltype -> int -> lltype + (** [vector_type ty n] returns the array type containing [n] elements of the primitive type [ty]. See the method [llvm::ArrayType::get]. *) -external vector_type : lltype -> int -> lltype = "llvm_vector_type" +val vector_type : lltype -> int -> lltype (** [element_type ty] returns the element type of the pointer, vector, or array type [ty]. See the method [llvm::SequentialType::get]. *) -external element_type : lltype -> lltype = "LLVMGetElementType" +val element_type : lltype -> lltype (** [element_type aty] returns the element count of the array type [aty]. See the method [llvm::ArrayType::getNumElements]. *) -external array_length : lltype -> int = "llvm_array_length" +val array_length : lltype -> int (** [address_space pty] returns the address space qualifier of the pointer type [pty]. See the method [llvm::PointerType::getAddressSpace]. *) -external address_space : lltype -> int = "llvm_address_space" +val address_space : lltype -> int (** [element_type ty] returns the element count of the vector type [ty]. See the method [llvm::VectorType::getNumElements]. *) -external vector_size : lltype -> int = "llvm_vector_size" +val vector_size : lltype -> int (** {7 Operations on other types} *) @@ -450,15 +450,15 @@ (** [opaque_type c] creates a new opaque type distinct from any other in the context [c]. Opaque types are useful for building recursive types in combination with {!refine_type}. See [llvm::OpaqueType::get]. *) -external opaque_type : llcontext -> lltype = "llvm_opaque_type" +val opaque_type : llcontext -> lltype (** [void_type c] creates a type of a function which does not return any value in the context [c]. See [llvm::Type::VoidTy]. *) -external void_type : llcontext -> lltype = "llvm_void_type" +val void_type : llcontext -> lltype (** [label_type c] creates a type of a basic block in the context [c]. See [llvm::Type::LabelTy]. *) -external label_type : llcontext -> lltype = "llvm_label_type" +val label_type : llcontext -> lltype (** {7 Operations on type handles} *) @@ -466,43 +466,43 @@ refined as a result of a call to {!refine_type}, the handle will be updated; any bare [lltype] references will become invalid. See the class [llvm::PATypeHolder]. *) -external handle_to_type : lltype -> lltypehandle = "llvm_handle_to_type" +val handle_to_type : lltype -> lltypehandle (** [type_of_handle tyh] resolves the type handle [tyh]. See the method [llvm::PATypeHolder::get()]. *) -external type_of_handle : lltypehandle -> lltype = "llvm_type_of_handle" +val type_of_handle : lltypehandle -> lltype (** [refine_type opaque_ty ty] replaces the abstract type [opaque_ty] with the concrete type [ty] in all users. Warning: This may invalidate {!lltype} values! Use {!lltypehandle} to manipulate potentially abstract types. See the method [llvm::Type::refineAbstractType]. *) -external refine_type : lltype -> lltype -> unit = "llvm_refine_type" +val refine_type : lltype -> lltype -> unit (* {6 Values} *) (** [type_of v] returns the type of the value [v]. See the method [llvm::Value::getType]. *) -external type_of : llvalue -> lltype = "llvm_type_of" +val type_of : llvalue -> lltype (** [value_name v] returns the name of the value [v]. For global values, this is the symbol name. For instructions and basic blocks, it is the SSA register name. It is meaningless for constants. See the method [llvm::Value::getName]. *) -external value_name : llvalue -> string = "llvm_value_name" +val value_name : llvalue -> string (** [set_value_name n v] sets the name of the value [v] to [n]. See the method [llvm::Value::setName]. *) -external set_value_name : string -> llvalue -> unit = "llvm_set_value_name" +val set_value_name : string -> llvalue -> unit (** [dump_value v] prints the .ll representation of the value [v] to standard error. See the method [llvm::Value::dump]. *) -external dump_value : llvalue -> unit = "llvm_dump_value" +val dump_value : llvalue -> unit (** [replace_all_uses_with old new] replaces all uses of the value [old] * with the value [new]. See the method [llvm::Value::replaceAllUsesWith]. *) -external replace_all_uses_with : llvalue -> llvalue -> unit - = "LLVMReplaceAllUsesWith" +val replace_all_uses_with : llvalue -> llvalue -> unit + (* {6 Uses} *) @@ -510,19 +510,19 @@ (** [use_begin v] returns the first position in the use list for the value [v]. [use_begin] and [use_succ] can e used to iterate over the use list in order. See the method [llvm::Value::use_begin]. *) -external use_begin : llvalue -> lluse option = "llvm_use_begin" +val use_begin : llvalue -> lluse option (** [use_succ u] returns the use list position succeeding [u]. See the method [llvm::use_value_iterator::operator++]. *) -external use_succ : lluse -> lluse option = "llvm_use_succ" +val use_succ : lluse -> lluse option (** [user u] returns the user of the use [u]. See the method [llvm::Use::getUser]. *) -external user : lluse -> llvalue = "llvm_user" +val user : lluse -> llvalue (** [used_value u] returns the usee of the use [u]. See the method [llvm::Use::getUsedValue]. *) -external used_value : lluse -> llvalue = "llvm_used_value" +val used_value : lluse -> llvalue (** [iter_uses f v] applies function [f] to each of the users of the value [v] in order. Tail recursive. *) @@ -541,46 +541,46 @@ (** [operand v i] returns the operand at index [i] for the value [v]. See the method [llvm::User::getOperand]. *) -external operand : llvalue -> int -> llvalue = "llvm_operand" +val operand : llvalue -> int -> llvalue (** [set_operand v i o] sets the operand of the value [v] at the index [i] to the value [o]. See the method [llvm::User::setOperand]. *) -external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand" +val set_operand : llvalue -> int -> llvalue -> unit (** [num_operands v] returns the number of operands for the value [v]. See the method [llvm::User::getNumOperands]. *) -external num_operands : llvalue -> int = "llvm_num_operands" +val num_operands : llvalue -> int (** {7 Operations on constants of (mostly) any type} *) (** [is_constant v] returns [true] if the value [v] is a constant, [false] otherwise. Similar to [llvm::isa]. *) -external is_constant : llvalue -> bool = "llvm_is_constant" +val is_constant : llvalue -> bool (** [const_null ty] returns the constant null (zero) of the type [ty]. See the method [llvm::Constant::getNullValue]. *) -external const_null : lltype -> llvalue = "LLVMConstNull" +val const_null : lltype -> llvalue (** [const_all_ones ty] returns the constant '-1' of the integer or vector type [ty]. See the method [llvm::Constant::getAllOnesValue]. *) -external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes" +val const_all_ones : (*int|vec*)lltype -> llvalue (** [const_pointer_null ty] returns the constant null (zero) pointer of the type [ty]. See the method [llvm::ConstantPointerNull::get]. *) -external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull" +val const_pointer_null : lltype -> llvalue (** [undef ty] returns the undefined value of the type [ty]. See the method [llvm::UndefValue::get]. *) -external undef : lltype -> llvalue = "LLVMGetUndef" +val undef : lltype -> llvalue (** [is_null v] returns [true] if the value [v] is the null (zero) value. See the method [llvm::Constant::isNullValue]. *) -external is_null : llvalue -> bool = "llvm_is_null" +val is_null : llvalue -> bool (** [is_undef v] returns [true] if the value [v] is an undefined value, [false] otherwise. Similar to [llvm::isa]. *) -external is_undef : llvalue -> bool = "llvm_is_undef" +val is_undef : llvalue -> bool (** {7 Operations on instructions} *) @@ -588,58 +588,58 @@ (** [has_metadata i] returns whether or not the instruction [i] has any metadata attached to it. See the function [llvm::Instruction::hasMetadata]. *) -external has_metadata : llvalue -> bool = "llvm_has_metadata" +val has_metadata : llvalue -> bool (** [metadata i kind] optionally returns the metadata associated with the kind [kind] in the instruction [i] See the function [llvm::Instruction::getMetadata]. *) -external metadata : llvalue -> int -> llvalue option = "llvm_metadata" +val metadata : llvalue -> int -> llvalue option (** [set_metadata i kind md] sets the metadata [md] of kind [kind] in the instruction [i]. See the function [llvm::Instruction::setMetadata]. *) -external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata" +val set_metadata : llvalue -> int -> llvalue -> unit (** [clear_metadata i kind] clears the metadata of kind [kind] in the instruction [i]. See the function [llvm::Instruction::setMetadata]. *) -external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata" +val clear_metadata : llvalue -> int -> unit (** {7 Operations on metadata} *) (** [mdstring c s] returns the MDString of the string [s] in the context [c]. See the method [llvm::MDNode::get]. *) -external mdstring : llcontext -> string -> llvalue = "llvm_mdstring" +val mdstring : llcontext -> string -> llvalue (** [mdnode c elts] returns the MDNode containing the values [elts] in the context [c]. See the method [llvm::MDNode::get]. *) -external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode" +val mdnode : llcontext -> llvalue array -> llvalue (** {7 Operations on scalar constants} *) (** [const_int ty i] returns the integer constant of type [ty] and value [i]. See the method [llvm::ConstantInt::get]. *) -external const_int : lltype -> int -> llvalue = "llvm_const_int" +val const_int : lltype -> int -> llvalue (** [const_of_int64 ty i] returns the integer constant of type [ty] and value [i]. See the method [llvm::ConstantInt::get]. *) -external const_of_int64 : lltype -> Int64.t -> bool -> llvalue - = "llvm_const_of_int64" +val const_of_int64 : lltype -> Int64.t -> bool -> llvalue + (** [const_int_of_string ty s r] returns the integer constant of type [ty] and * value [s], with the radix [r]. See the method [llvm::ConstantInt::get]. *) -external const_int_of_string : lltype -> string -> int -> llvalue - = "llvm_const_int_of_string" +val const_int_of_string : lltype -> string -> int -> llvalue + (** [const_float ty n] returns the floating point constant of type [ty] and value [n]. See the method [llvm::ConstantFP::get]. *) -external const_float : lltype -> float -> llvalue = "llvm_const_float" +val const_float : lltype -> float -> llvalue (** [const_float_of_string ty s] returns the floating point constant of type [ty] and value [n]. See the method [llvm::ConstantFP::get]. *) -external const_float_of_string : lltype -> string -> llvalue - = "llvm_const_float_of_string" +val const_float_of_string : lltype -> string -> llvalue + (** {7 Operations on composite constants} *) @@ -649,39 +649,39 @@ null-terminated (but see {!const_stringz}). This value can in turn be used as the initializer for a global variable. See the method [llvm::ConstantArray::get]. *) -external const_string : llcontext -> string -> llvalue = "llvm_const_string" +val const_string : llcontext -> string -> llvalue (** [const_stringz c s] returns the constant [i8] array with the values of the characters in the string [s] and a null terminator in the context [c]. This value can in turn be used as the initializer for a global variable. See the method [llvm::ConstantArray::get]. *) -external const_stringz : llcontext -> string -> llvalue = "llvm_const_stringz" +val const_stringz : llcontext -> string -> llvalue (** [const_array ty elts] returns the constant array of type [array_type ty (Array.length elts)] and containing the values [elts]. This value can in turn be used as the initializer for a global variable. See the method [llvm::ConstantArray::get]. *) -external const_array : lltype -> llvalue array -> llvalue = "llvm_const_array" +val const_array : lltype -> llvalue array -> llvalue (** [const_struct context elts] returns the structured constant of type [struct_type (Array.map type_of elts)] and containing the values [elts] in the context [context]. This value can in turn be used as the initializer for a global variable. See the method [llvm::ConstantStruct::get]. *) -external const_struct : llcontext -> llvalue array -> llvalue - = "llvm_const_struct" +val const_struct : llcontext -> llvalue array -> llvalue + (** [const_packed_struct context elts] returns the structured constant of type {!packed_struct_type} [(Array.map type_of elts)] and containing the values [elts] in the context [context]. This value can in turn be used as the initializer for a global variable. See the method [llvm::ConstantStruct::get]. *) -external const_packed_struct : llcontext -> llvalue array -> llvalue - = "llvm_const_packed_struct" +val const_packed_struct : llcontext -> llvalue array -> llvalue + (** [const_vector elts] returns the vector constant of type [vector_type (type_of elts.(0)) (Array.length elts)] and containing the values [elts]. See the method [llvm::ConstantVector::get]. *) -external const_vector : llvalue array -> llvalue = "llvm_const_vector" +val const_vector : llvalue array -> llvalue (** {7 Constant expressions} *) @@ -690,286 +690,286 @@ equivalent to [const_ptrtoint (const_gep (const_null (pointer_type {i8,ty})) (const_int i32_type 0) (const_int i32_type 1)) i32_type], but considerably more readable. See the method [llvm::ConstantExpr::getAlignOf]. *) -external align_of : lltype -> llvalue = "LLVMAlignOf" +val align_of : lltype -> llvalue (** [size_of ty] returns the sizeof constant for the type [ty]. This is equivalent to [const_ptrtoint (const_gep (const_null (pointer_type ty)) (const_int i32_type 1)) i64_type], but considerably more readable. See the method [llvm::ConstantExpr::getSizeOf]. *) -external size_of : lltype -> llvalue = "LLVMSizeOf" +val size_of : lltype -> llvalue (** [const_neg c] returns the arithmetic negation of the constant [c]. See the method [llvm::ConstantExpr::getNeg]. *) -external const_neg : llvalue -> llvalue = "LLVMConstNeg" +val const_neg : llvalue -> llvalue (** [const_nsw_neg c] returns the arithmetic negation of the constant [c] with no signed wrapping. The result is undefined if the negation overflows. See the method [llvm::ConstantExpr::getNSWNeg]. *) -external const_nsw_neg : llvalue -> llvalue = "LLVMConstNSWNeg" +val const_nsw_neg : llvalue -> llvalue (** [const_nuw_neg c] returns the arithmetic negation of the constant [c] with no unsigned wrapping. The result is undefined if the negation overflows. See the method [llvm::ConstantExpr::getNUWNeg]. *) -external const_nuw_neg : llvalue -> llvalue = "LLVMConstNUWNeg" +val const_nuw_neg : llvalue -> llvalue (** [const_fneg c] returns the arithmetic negation of the constant float [c]. See the method [llvm::ConstantExpr::getFNeg]. *) -external const_fneg : llvalue -> llvalue = "LLVMConstFNeg" +val const_fneg : llvalue -> llvalue (** [const_not c] returns the bitwise inverse of the constant [c]. See the method [llvm::ConstantExpr::getNot]. *) -external const_not : llvalue -> llvalue = "LLVMConstNot" +val const_not : llvalue -> llvalue (** [const_add c1 c2] returns the constant sum of two constants. See the method [llvm::ConstantExpr::getAdd]. *) -external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd" +val const_add : llvalue -> llvalue -> llvalue (** [const_nsw_add c1 c2] returns the constant sum of two constants with no signed wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWAdd]. *) -external const_nsw_add : llvalue -> llvalue -> llvalue = "LLVMConstNSWAdd" +val const_nsw_add : llvalue -> llvalue -> llvalue (** [const_nuw_add c1 c2] returns the constant sum of two constants with no unsigned wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWAdd]. *) -external const_nuw_add : llvalue -> llvalue -> llvalue = "LLVMConstNUWAdd" +val const_nuw_add : llvalue -> llvalue -> llvalue (** [const_fadd c1 c2] returns the constant sum of two constant floats. See the method [llvm::ConstantExpr::getFAdd]. *) -external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd" +val const_fadd : llvalue -> llvalue -> llvalue (** [const_sub c1 c2] returns the constant difference, [c1 - c2], of two constants. See the method [llvm::ConstantExpr::getSub]. *) -external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub" +val const_sub : llvalue -> llvalue -> llvalue (** [const_nsw_sub c1 c2] returns the constant difference of two constants with no signed wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWSub]. *) -external const_nsw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNSWSub" +val const_nsw_sub : llvalue -> llvalue -> llvalue (** [const_nuw_sub c1 c2] returns the constant difference of two constants with no unsigned wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWSub]. *) -external const_nuw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNUWSub" +val const_nuw_sub : llvalue -> llvalue -> llvalue (** [const_fsub c1 c2] returns the constant difference, [c1 - c2], of two constant floats. See the method [llvm::ConstantExpr::getFSub]. *) -external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub" +val const_fsub : llvalue -> llvalue -> llvalue (** [const_mul c1 c2] returns the constant product of two constants. See the method [llvm::ConstantExpr::getMul]. *) -external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul" +val const_mul : llvalue -> llvalue -> llvalue (** [const_nsw_mul c1 c2] returns the constant product of two constants with no signed wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWMul]. *) -external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul" +val const_nsw_mul : llvalue -> llvalue -> llvalue (** [const_nuw_mul c1 c2] returns the constant product of two constants with no unsigned wrapping. The result is undefined if the sum overflows. See the method [llvm::ConstantExpr::getNSWMul]. *) -external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul" +val const_nuw_mul : llvalue -> llvalue -> llvalue (** [const_fmul c1 c2] returns the constant product of two constants floats. See the method [llvm::ConstantExpr::getFMul]. *) -external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul" +val const_fmul : llvalue -> llvalue -> llvalue (** [const_udiv c1 c2] returns the constant quotient [c1 / c2] of two unsigned integer constants. See the method [llvm::ConstantExpr::getUDiv]. *) -external const_udiv : llvalue -> llvalue -> llvalue = "LLVMConstUDiv" +val const_udiv : llvalue -> llvalue -> llvalue (** [const_sdiv c1 c2] returns the constant quotient [c1 / c2] of two signed integer constants. See the method [llvm::ConstantExpr::getSDiv]. *) -external const_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstSDiv" +val const_sdiv : llvalue -> llvalue -> llvalue (** [const_exact_sdiv c1 c2] returns the constant quotient [c1 / c2] of two signed integer constants. The result is undefined if the result is rounded or overflows. See the method [llvm::ConstantExpr::getExactSDiv]. *) -external const_exact_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstExactSDiv" +val const_exact_sdiv : llvalue -> llvalue -> llvalue (** [const_fdiv c1 c2] returns the constant quotient [c1 / c2] of two floating point constants. See the method [llvm::ConstantExpr::getFDiv]. *) -external const_fdiv : llvalue -> llvalue -> llvalue = "LLVMConstFDiv" +val const_fdiv : llvalue -> llvalue -> llvalue (** [const_urem c1 c2] returns the constant remainder [c1 MOD c2] of two unsigned integer constants. See the method [llvm::ConstantExpr::getURem]. *) -external const_urem : llvalue -> llvalue -> llvalue = "LLVMConstURem" +val const_urem : llvalue -> llvalue -> llvalue (** [const_srem c1 c2] returns the constant remainder [c1 MOD c2] of two signed integer constants. See the method [llvm::ConstantExpr::getSRem]. *) -external const_srem : llvalue -> llvalue -> llvalue = "LLVMConstSRem" +val const_srem : llvalue -> llvalue -> llvalue (** [const_frem c1 c2] returns the constant remainder [c1 MOD c2] of two signed floating point constants. See the method [llvm::ConstantExpr::getFRem]. *) -external const_frem : llvalue -> llvalue -> llvalue = "LLVMConstFRem" +val const_frem : llvalue -> llvalue -> llvalue (** [const_and c1 c2] returns the constant bitwise [AND] of two integer constants. See the method [llvm::ConstantExpr::getAnd]. *) -external const_and : llvalue -> llvalue -> llvalue = "LLVMConstAnd" +val const_and : llvalue -> llvalue -> llvalue (** [const_or c1 c2] returns the constant bitwise [OR] of two integer constants. See the method [llvm::ConstantExpr::getOr]. *) -external const_or : llvalue -> llvalue -> llvalue = "LLVMConstOr" +val const_or : llvalue -> llvalue -> llvalue (** [const_xor c1 c2] returns the constant bitwise [XOR] of two integer constants. See the method [llvm::ConstantExpr::getXor]. *) -external const_xor : llvalue -> llvalue -> llvalue = "LLVMConstXor" +val const_xor : llvalue -> llvalue -> llvalue (** [const_icmp pred c1 c2] returns the constant comparison of two integer constants, [c1 pred c2]. See the method [llvm::ConstantExpr::getICmp]. *) -external const_icmp : Icmp.t -> llvalue -> llvalue -> llvalue - = "llvm_const_icmp" +val const_icmp : Icmp.t -> llvalue -> llvalue -> llvalue + (** [const_fcmp pred c1 c2] returns the constant comparison of two floating point constants, [c1 pred c2]. See the method [llvm::ConstantExpr::getFCmp]. *) -external const_fcmp : Fcmp.t -> llvalue -> llvalue -> llvalue - = "llvm_const_fcmp" +val const_fcmp : Fcmp.t -> llvalue -> llvalue -> llvalue + (** [const_shl c1 c2] returns the constant integer [c1] left-shifted by the constant integer [c2]. See the method [llvm::ConstantExpr::getShl]. *) -external const_shl : llvalue -> llvalue -> llvalue = "LLVMConstShl" +val const_shl : llvalue -> llvalue -> llvalue (** [const_lshr c1 c2] returns the constant integer [c1] right-shifted by the constant integer [c2] with zero extension. See the method [llvm::ConstantExpr::getLShr]. *) -external const_lshr : llvalue -> llvalue -> llvalue = "LLVMConstLShr" +val const_lshr : llvalue -> llvalue -> llvalue (** [const_ashr c1 c2] returns the constant integer [c1] right-shifted by the constant integer [c2] with sign extension. See the method [llvm::ConstantExpr::getAShr]. *) -external const_ashr : llvalue -> llvalue -> llvalue = "LLVMConstAShr" +val const_ashr : llvalue -> llvalue -> llvalue (** [const_gep pc indices] returns the constant [getElementPtr] of [p1] with the constant integers indices from the array [indices]. See the method [llvm::ConstantExpr::getGetElementPtr]. *) -external const_gep : llvalue -> llvalue array -> llvalue = "llvm_const_gep" +val const_gep : llvalue -> llvalue array -> llvalue (** [const_in_bounds_gep pc indices] returns the constant [getElementPtr] of [p1] with the constant integers indices from the array [indices]. See the method [llvm::ConstantExpr::getInBoundsGetElementPtr]. *) -external const_in_bounds_gep : llvalue -> llvalue array -> llvalue - = "llvm_const_in_bounds_gep" +val const_in_bounds_gep : llvalue -> llvalue array -> llvalue + (** [const_trunc c ty] returns the constant truncation of integer constant [c] to the smaller integer type [ty]. See the method [llvm::ConstantExpr::getTrunc]. *) -external const_trunc : llvalue -> lltype -> llvalue = "LLVMConstTrunc" +val const_trunc : llvalue -> lltype -> llvalue (** [const_sext c ty] returns the constant sign extension of integer constant [c] to the larger integer type [ty]. See the method [llvm::ConstantExpr::getSExt]. *) -external const_sext : llvalue -> lltype -> llvalue = "LLVMConstSExt" +val const_sext : llvalue -> lltype -> llvalue (** [const_zext c ty] returns the constant zero extension of integer constant [c] to the larger integer type [ty]. See the method [llvm::ConstantExpr::getZExt]. *) -external const_zext : llvalue -> lltype -> llvalue = "LLVMConstZExt" +val cons